mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/kube-vip/kube-vip.git
synced 2026-09-20 08:03:47 +08:00
Merge pull request #1639 from gabrielstedman/feat/allow-iface-not-up
Add an opt-in flag/env var to allow kube-vip to start when interface exists but is not up
This commit is contained in:
@@ -60,6 +60,7 @@ func init() {
|
||||
// Basic flags
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.Interface, "interface", "", "Name of the interface to bind to")
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.ServicesInterface, "serviceInterface", "", "Name of the interface to bind to (for services)")
|
||||
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.AllowInterfaceNotUp, "allowInterfaceNotUp", false, "Allow kube-vip to start even if the interface is not up")
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.VIP, "vip", "", "The Virtual IP address")
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.VIPSubnet, "vipSubnet", "", "The Virtual IP address subnet e.g. /32 /24 /8 etc.. (Default to 32 for IPv4 and 128 for IPv6)")
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.NodeName, "nodeName", "", "Name to be used for lease holder. Must be unique for each node/instance")
|
||||
|
||||
@@ -77,6 +77,16 @@ func ParseEnvironment(c *Config) error {
|
||||
c.ServicesInterface = env
|
||||
}
|
||||
|
||||
// Tolerate a down interface
|
||||
env = os.Getenv(vipAllowInterfaceNotUp)
|
||||
if env != "" {
|
||||
b, err := strconv.ParseBool(env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.AllowInterfaceNotUp = b
|
||||
}
|
||||
|
||||
// Find Kubernetes Leader Election configuration
|
||||
env = os.Getenv(vipLeaderElection)
|
||||
if env != "" {
|
||||
|
||||
@@ -51,6 +51,9 @@ const (
|
||||
// vipServicesInterface - defines the interface that the service vips should bind too
|
||||
vipServicesInterface = "vip_servicesinterface"
|
||||
|
||||
// vipAllowInterfaceNotUp - defines if kube-vip should tolerate a down interface
|
||||
vipAllowInterfaceNotUp = "vip_allow_interface_not_up"
|
||||
|
||||
// vipSubnet - defines the subnet that the vip will use
|
||||
vipSubnet = "vip_subnet"
|
||||
|
||||
|
||||
@@ -239,6 +239,17 @@ func generatePodSpec(c *Config, image, imageVersion string, inCluster bool) (*co
|
||||
newEnvironment = append(newEnvironment, svcInterface...)
|
||||
}
|
||||
|
||||
// Tolerate a down interface
|
||||
if c.AllowInterfaceNotUp {
|
||||
allowIface := []corev1.EnvVar{
|
||||
{
|
||||
Name: vipAllowInterfaceNotUp,
|
||||
Value: strconv.FormatBool(c.AllowInterfaceNotUp),
|
||||
},
|
||||
}
|
||||
newEnvironment = append(newEnvironment, allowIface...)
|
||||
}
|
||||
|
||||
// If a subnet is required for the VIP
|
||||
if c.VIPSubnet != "" {
|
||||
// build environment variables
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package kubevip
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
log "log/slog"
|
||||
@@ -12,6 +13,8 @@ const (
|
||||
Auto = "auto"
|
||||
)
|
||||
|
||||
var ErrInterfaceNotUp = errors.New("interface is not up")
|
||||
|
||||
func (c *Config) CheckSubnetExists() error {
|
||||
if c.VIPSubnet == "" && c.VIP != "" && c.Address == "" {
|
||||
return fmt.Errorf("vip_subnet must be set if using vip_address instead of address environment variable")
|
||||
@@ -23,15 +26,23 @@ func (c *Config) CheckSubnetExists() error {
|
||||
func (c *Config) CheckInterface() error {
|
||||
if c.Interface != "" {
|
||||
if err := isValidInterface(c.Interface); err != nil {
|
||||
if errors.Is(err, ErrInterfaceNotUp) && c.AllowInterfaceNotUp {
|
||||
log.Warn("interface is not up, continuing as allowInterfaceNotUp is set", "interface", c.Interface)
|
||||
} else {
|
||||
return fmt.Errorf("%s is not valid interface, reason: %w", c.Interface, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if c.ServicesInterface != "" {
|
||||
if err := isValidInterface(c.ServicesInterface); err != nil {
|
||||
if errors.Is(err, ErrInterfaceNotUp) && c.AllowInterfaceNotUp {
|
||||
log.Warn("interface is not up, continuing as allowInterfaceNotUp is set", "interface", c.ServicesInterface)
|
||||
} else {
|
||||
return fmt.Errorf("%s is not valid interface, reason: %w", c.ServicesInterface, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -58,7 +69,7 @@ func isValidInterface(iface string) error {
|
||||
iface,
|
||||
)
|
||||
} else if attrs.OperState != netlink.OperUp {
|
||||
return fmt.Errorf("%s is not up", iface)
|
||||
return fmt.Errorf("%s %w", iface, ErrInterfaceNotUp)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -115,6 +115,9 @@ type Config struct {
|
||||
// ServicesInterface is the network interface to bind to for services (optional)
|
||||
ServicesInterface string `yaml:"servicesInterface,omitempty"`
|
||||
|
||||
// AllowInterfaceNotUp allows kube-vip to start even when the interface is not up
|
||||
AllowInterfaceNotUp bool `yaml:"allowInterfaceNotUp,omitempty"`
|
||||
|
||||
// EnableLoadBalancer, provides the flexibility to make the load-balancer optional
|
||||
EnableLoadBalancer bool `yaml:"enableLoadBalancer"`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user