mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/kube-vip/kube-vip.git
synced 2026-09-20 08:03:47 +08:00
Auto detect default interface for VIP
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/kube-vip/kube-vip/pkg/kubevip"
|
||||
"github.com/kube-vip/kube-vip/pkg/vip"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -43,6 +44,15 @@ var kubeManifestPod = &cobra.Command{
|
||||
// TODO - A load of text detailing what's actually happening
|
||||
kubevip.ParseEnvironment(&initConfig)
|
||||
// TODO - check for certain things VIP/interfaces
|
||||
|
||||
if initConfig.AutoInterface {
|
||||
defaultIF, err := vip.GetDefaultGatewayInterface()
|
||||
if err != nil {
|
||||
log.Fatalf("unable to set default interface -> [%v]", err)
|
||||
}
|
||||
initConfig.Interface = defaultIF.Name
|
||||
}
|
||||
|
||||
if initConfig.Interface == "" {
|
||||
cmd.Help()
|
||||
log.Fatalln("No interface is specified for kube-vip to bind to")
|
||||
@@ -69,6 +79,15 @@ var kubeManifestDaemon = &cobra.Command{
|
||||
// TODO - A load of text detailing what's actually happening
|
||||
kubevip.ParseEnvironment(&initConfig)
|
||||
// TODO - check for certain things VIP/interfaces
|
||||
|
||||
if initConfig.AutoInterface {
|
||||
defaultIF, err := vip.GetDefaultGatewayInterface()
|
||||
if err != nil {
|
||||
log.Fatalf("unable to set default interface -> [%v]", err)
|
||||
}
|
||||
initConfig.Interface = defaultIF.Name
|
||||
}
|
||||
|
||||
if initConfig.Interface == "" {
|
||||
cmd.Help()
|
||||
log.Fatalln("No interface is specified for kube-vip to bind to")
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/kube-vip/kube-vip/pkg/kubevip"
|
||||
"github.com/kube-vip/kube-vip/pkg/manager"
|
||||
"github.com/kube-vip/kube-vip/pkg/packet"
|
||||
"github.com/kube-vip/kube-vip/pkg/vip"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -67,6 +68,8 @@ func init() {
|
||||
initConfig.LocalPeer = *localpeer
|
||||
//initConfig.Peers = append(initConfig.Peers, *localpeer)
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.Interface, "interface", "", "Name of the interface to bind to")
|
||||
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.AutoInterface, "autoInterface", false, "Name of the interface to bind to")
|
||||
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.ServicesInterface, "serviceInterface", "", "Name of the interface to bind to (for services)")
|
||||
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.VIP, "vip", "", "The Virtual IP address")
|
||||
@@ -209,6 +212,19 @@ var kubeVipManager = &cobra.Command{
|
||||
// Set the logging level for all subsequent functions
|
||||
log.SetLevel(log.Level(logLevel))
|
||||
|
||||
if initConfig.AutoInterface {
|
||||
defaultIF, err := vip.GetDefaultGatewayInterface()
|
||||
if err != nil {
|
||||
log.Fatalf("unable to set default interface -> [%v]", err)
|
||||
}
|
||||
initConfig.Interface = defaultIF.Name
|
||||
}
|
||||
|
||||
if initConfig.Interface == "" {
|
||||
cmd.Help()
|
||||
log.Fatalln("No interface is specified for kube-vip to bind to")
|
||||
}
|
||||
|
||||
go servePrometheusHTTPServer(cmd.Context(), PrometheusHTTPServerConfig{
|
||||
Addr: initConfig.PrometheusHTTPServer,
|
||||
})
|
||||
@@ -240,7 +256,7 @@ var kubeVipManager = &cobra.Command{
|
||||
// Define the new service manager
|
||||
mgr, err := manager.New(configMap, &initConfig)
|
||||
if err != nil {
|
||||
log.Fatalf("%v", err)
|
||||
log.Fatalf("configuring new Manager error -> %v", err)
|
||||
}
|
||||
|
||||
prometheus.MustRegister(mgr.PrometheusCollector()...)
|
||||
@@ -248,7 +264,7 @@ var kubeVipManager = &cobra.Command{
|
||||
// Start the service manager, this will watch the config Map and construct kube-vip services for it
|
||||
err = mgr.Start()
|
||||
if err != nil {
|
||||
log.Fatalf("%v", err)
|
||||
log.Fatalf("starting new Manager error -> %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@ const (
|
||||
//vipInterface - defines the interface that the vip should bind too
|
||||
vipInterface = "vip_interface"
|
||||
|
||||
//vipAutoInterface - defines the interface that the vip should bind too
|
||||
vipAutoInterface = "vip_autointerface"
|
||||
|
||||
//vipServicesInterface - defines the interface that the service vips should bind too
|
||||
vipServicesInterface = "vip_servicesinterface"
|
||||
|
||||
|
||||
@@ -34,6 +34,16 @@ func ParseEnvironment(c *Config) error {
|
||||
c.Interface = env
|
||||
}
|
||||
|
||||
// Find interface
|
||||
env = os.Getenv(vipAutoInterface)
|
||||
if env != "" {
|
||||
b, err := strconv.ParseBool(env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.AutoInterface = b
|
||||
}
|
||||
|
||||
// Find (services) interface
|
||||
env = os.Getenv(vipServicesInterface)
|
||||
if env != "" {
|
||||
@@ -449,22 +459,37 @@ func parseEnvironmentLoadBalancer(c *Config) error {
|
||||
// generatePodSpec will take a kube-vip config and generate a Pod spec
|
||||
func generatePodSpec(c *Config, imageVersion string, inCluster bool) *corev1.Pod {
|
||||
command := "manager"
|
||||
|
||||
// build environment variables
|
||||
newEnvironment := []corev1.EnvVar{
|
||||
{
|
||||
Name: vipArp,
|
||||
Value: strconv.FormatBool(c.EnableARP),
|
||||
},
|
||||
{
|
||||
Name: vipInterface,
|
||||
Value: c.Interface,
|
||||
},
|
||||
{
|
||||
Name: port,
|
||||
Value: fmt.Sprintf("%d", c.Port),
|
||||
},
|
||||
}
|
||||
|
||||
if c.AutoInterface {
|
||||
// build environment variables
|
||||
autoInterface := []corev1.EnvVar{
|
||||
{
|
||||
Name: vipAutoInterface,
|
||||
Value: strconv.FormatBool(c.AutoInterface),
|
||||
},
|
||||
}
|
||||
newEnvironment = append(newEnvironment, autoInterface...)
|
||||
} else {
|
||||
iface := []corev1.EnvVar{
|
||||
{
|
||||
Name: vipInterface,
|
||||
Value: c.Interface,
|
||||
},
|
||||
}
|
||||
newEnvironment = append(newEnvironment, iface...)
|
||||
}
|
||||
// Detect if we should be using a seperate interface for sercices
|
||||
if c.ServicesInterface != "" {
|
||||
// build environment variables
|
||||
|
||||
@@ -63,6 +63,9 @@ type Config struct {
|
||||
// Interface is the network interface to bind to (default: First Adapter)
|
||||
Interface string `yaml:"interface,omitempty"`
|
||||
|
||||
// AutoInterface is the network interface to bind to (Adapter is determined from Default Gateway)
|
||||
AutoInterface bool `yaml:"interface,omitempty"`
|
||||
|
||||
// ServicesInterface is the network interface to bind to for services (optional)
|
||||
ServicesInterface string `yaml:"servicesInterface,omitempty"`
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ func New(configMap string, config *kubevip.Config) (*Manager, error) {
|
||||
// Second check in home directory for kube config
|
||||
configPath = filepath.Join(os.Getenv("HOME"), ".kube", "config")
|
||||
if fileExists(configPath) {
|
||||
log.Debugf("Using external Kubernetes configuration from file [%s]", configPath)
|
||||
log.Debugf("Using external Kubernetes configuration from home file [%s]", configPath)
|
||||
cfg, err = clientcmd.BuildConfigFromFlags("", configPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -4,8 +4,10 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
// LookupHost resolves dnsName and return an IP or an error
|
||||
@@ -64,3 +66,22 @@ func GetFullMask(address string) (string, error) {
|
||||
}
|
||||
return "", fmt.Errorf("failed to parse %s as either IPv4 or IPv6", address)
|
||||
}
|
||||
|
||||
// GetDefaultGatewayInterface return default gateway interface link
|
||||
func GetDefaultGatewayInterface() (*net.Interface, error) {
|
||||
routes, err := netlink.RouteList(nil, syscall.AF_INET)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, route := range routes {
|
||||
if route.Dst == nil || route.Dst.String() == "0.0.0.0/0" {
|
||||
if route.LinkIndex <= 0 {
|
||||
return nil, errors.New("Found default route but could not determine interface")
|
||||
}
|
||||
return net.InterfaceByIndex(route.LinkIndex)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("Unable to find default route")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user