mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/kube-vip/kube-vip.git
synced 2026-09-20 08:03:47 +08:00
fix: optionally attach BGP service VIPs to interface
Signed-off-by: Marijn Ritzen <marijnritzen@outlook.com>
This commit is contained in:
@@ -92,6 +92,7 @@ func init() {
|
||||
|
||||
// BGP flags
|
||||
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableBGP, "bgp", false, "This will enable BGP support within kube-vip")
|
||||
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.BGPAttachIPToInterface, "bgpAttachIPToInterface", false, "Assign BGP service VIPs to the configured interface")
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.BGPConfig.RouterID, "bgpRouterID", "", "The routerID for the bgp server")
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.BGPConfig.SourceIF, "sourceIF", "", "The source interface for bgp peering (not to be used with sourceIP)")
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.BGPConfig.SourceIP, "sourceIP", "", "The source address for bgp peering (not to be used with sourceIF)")
|
||||
|
||||
@@ -411,7 +411,7 @@ func (cluster *Cluster) StartLoadBalancerService(ctx context.Context, c *kubevip
|
||||
}
|
||||
}
|
||||
|
||||
if !c.EnableRoutingTable && !c.EnableBGP && !c.EnableWireguard {
|
||||
if shouldAddServiceIP(c) {
|
||||
// Normal VIP addition, use skipDAD=false for normal DAD process
|
||||
// Note: When WireGuard is enabled, the VIP is added to the tunnel interface
|
||||
// instead of lo, so we skip adding it here.
|
||||
@@ -480,6 +480,10 @@ func (cluster *Cluster) StartLoadBalancerService(ctx context.Context, c *kubevip
|
||||
return nil
|
||||
}
|
||||
|
||||
func shouldAddServiceIP(c *kubevip.Config) bool {
|
||||
return !c.EnableRoutingTable && (!c.EnableBGP || c.BGPAttachIPToInterface) && !c.EnableWireguard
|
||||
}
|
||||
|
||||
// Layer2Update, handles the creation of the
|
||||
func (cluster *Cluster) layer2Update(ctx context.Context, network vip.Network, c *kubevip.Config) {
|
||||
var ndp *vip.NdpResponder
|
||||
|
||||
55
pkg/cluster/service_config_test.go
Normal file
55
pkg/cluster/service_config_test.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kube-vip/kube-vip/pkg/kubevip"
|
||||
)
|
||||
|
||||
func TestShouldAddServiceIP(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config *kubevip.Config
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "BGP default does not attach IP",
|
||||
config: &kubevip.Config{EnableBGP: true},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "BGP opt-in attaches IP",
|
||||
config: &kubevip.Config{
|
||||
EnableBGP: true,
|
||||
BGPAttachIPToInterface: true,
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "routing table takes precedence",
|
||||
config: &kubevip.Config{
|
||||
EnableBGP: true,
|
||||
BGPAttachIPToInterface: true,
|
||||
EnableRoutingTable: true,
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "WireGuard takes precedence",
|
||||
config: &kubevip.Config{
|
||||
EnableBGP: true,
|
||||
BGPAttachIPToInterface: true,
|
||||
EnableWireguard: true,
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := shouldAddServiceIP(tt.config); got != tt.want {
|
||||
t.Fatalf("shouldAddServiceIP() = %t, want %t", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -456,6 +456,15 @@ func ParseEnvironment(c *Config) error {
|
||||
c.EnableBGP = b
|
||||
}
|
||||
|
||||
env = os.Getenv(bgpAttachIPToInterface)
|
||||
if env != "" {
|
||||
b, err := strconv.ParseBool(env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.BGPAttachIPToInterface = b
|
||||
}
|
||||
|
||||
// BGP Router interface determines an interface that we can use to find an address for
|
||||
env = os.Getenv(bgpRouterInterface)
|
||||
if env != "" {
|
||||
@@ -878,6 +887,9 @@ func mergeConfigValues(baseConfig, fileConfig *Config) {
|
||||
if !baseConfig.EnableBGP && fileConfig.EnableBGP {
|
||||
baseConfig.EnableBGP = fileConfig.EnableBGP
|
||||
}
|
||||
if !baseConfig.BGPAttachIPToInterface && fileConfig.BGPAttachIPToInterface {
|
||||
baseConfig.BGPAttachIPToInterface = fileConfig.BGPAttachIPToInterface
|
||||
}
|
||||
if !baseConfig.EnableWireguard && fileConfig.EnableWireguard {
|
||||
baseConfig.EnableWireguard = fileConfig.EnableWireguard
|
||||
}
|
||||
|
||||
@@ -100,6 +100,8 @@ const (
|
||||
|
||||
// bgpEnable defines if BGP should be enabled
|
||||
bgpEnable = "bgp_enable"
|
||||
// bgpAttachIPToInterface defines if BGP service VIPs should be assigned to the configured interface
|
||||
bgpAttachIPToInterface = "bgp_attach_ip_to_interface"
|
||||
// bgpRouterID defines the routerID for the BGP server
|
||||
bgpRouterID = "bgp_routerid"
|
||||
// bgpRouterInterface defines the interface that we can find the address for
|
||||
|
||||
@@ -476,6 +476,12 @@ func generatePodSpec(c *Config, image, imageVersion string, inCluster bool) (*co
|
||||
Value: strconv.FormatBool(c.EnableBGP),
|
||||
},
|
||||
}
|
||||
if c.BGPAttachIPToInterface {
|
||||
bgp = append(bgp, corev1.EnvVar{
|
||||
Name: bgpAttachIPToInterface,
|
||||
Value: strconv.FormatBool(c.BGPAttachIPToInterface),
|
||||
})
|
||||
}
|
||||
newEnvironment = append(newEnvironment, bgp...)
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,35 @@ func TestParseEnvironmentInstanceName(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseEnvironmentBGPAttachIPToInterface(t *testing.T) {
|
||||
t.Setenv(bgpAttachIPToInterface, "true")
|
||||
|
||||
config := &Config{}
|
||||
if err := ParseEnvironment(config); err != nil {
|
||||
t.Fatalf("ParseEnvironment() error = %v", err)
|
||||
}
|
||||
if !config.BGPAttachIPToInterface {
|
||||
t.Fatal("BGPAttachIPToInterface = false, want true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeneratePodSpecBGPAttachIPToInterface(t *testing.T) {
|
||||
pod, err := generatePodSpec(&Config{
|
||||
EnableBGP: true,
|
||||
BGPAttachIPToInterface: true,
|
||||
}, "ghcr.io/kube-vip/kube-vip", "v0.0.0", true)
|
||||
if err != nil {
|
||||
t.Fatalf("generatePodSpec() error = %v", err)
|
||||
}
|
||||
|
||||
for _, env := range pod.Spec.Containers[0].Env {
|
||||
if env.Name == bgpAttachIPToInterface && env.Value == "true" {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatalf("%s=true is missing from generated pod environment", bgpAttachIPToInterface)
|
||||
}
|
||||
|
||||
func TestGeneratePodSpecInstanceName(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
@@ -11,6 +11,9 @@ type Config struct {
|
||||
// EnableBGP, will use BGP to advertise the VIP address
|
||||
EnableBGP bool `yaml:"enableBGP"`
|
||||
|
||||
// BGPAttachIPToInterface assigns BGP-advertised service VIPs to the configured interface
|
||||
BGPAttachIPToInterface bool `yaml:"bgpAttachIPToInterface"`
|
||||
|
||||
// EnableWireguard, will use wireguard to advertise the VIP address
|
||||
EnableWireguard bool `yaml:"enableWireguard"`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user