From 7917da9e133f289327df8a6367a38b4f30d02a9a Mon Sep 17 00:00:00 2001 From: Michal Rostecki Date: Wed, 20 Apr 2022 16:01:49 +0200 Subject: [PATCH 1/4] agent(netpol): Explicitly enable IPv4 when necessary Before this change, kube-router was always assuming that IPv4 is enabled, which is not the case in IPv6-only clusters. To enable network policies in IPv6-only, we need to explicitly let kube-router know when to disable IPv4. Signed-off-by: Michal Rostecki --- pkg/agent/netpol/netpol.go | 2 +- pkg/agent/run.go | 4 ++++ pkg/daemons/config/types.go | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/agent/netpol/netpol.go b/pkg/agent/netpol/netpol.go index 3c8538755982..81861d6d2f2e 100644 --- a/pkg/agent/netpol/netpol.go +++ b/pkg/agent/netpol/netpol.go @@ -55,7 +55,7 @@ func Run(ctx context.Context, nodeConfig *config.Node) error { krConfig := options.NewKubeRouterConfig() krConfig.ClusterIPCIDR = util.JoinIPNets(nodeConfig.AgentConfig.ServiceCIDRs) - krConfig.EnableIPv4 = true + krConfig.EnableIPv4 = nodeConfig.AgentConfig.EnableIPv4 krConfig.EnableIPv6 = nodeConfig.AgentConfig.EnableIPv6 krConfig.NodePortRange = strings.ReplaceAll(nodeConfig.AgentConfig.ServiceNodePortRange.String(), "-", ":") krConfig.HostnameOverride = nodeConfig.AgentConfig.NodeName diff --git a/pkg/agent/run.go b/pkg/agent/run.go index f7df88885d3e..e521e14c4966 100644 --- a/pkg/agent/run.go +++ b/pkg/agent/run.go @@ -63,15 +63,19 @@ func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error { if err != nil { return errors.Wrap(err, "failed to validate node-ip") } + serviceIPv4 := utilsnet.IsIPv4CIDR(nodeConfig.AgentConfig.ServiceCIDR) + clusterIPv4 := utilsnet.IsIPv4CIDR(nodeConfig.AgentConfig.ClusterCIDR) serviceIPv6 := utilsnet.IsIPv6CIDR(nodeConfig.AgentConfig.ServiceCIDR) clusterIPv6 := utilsnet.IsIPv6CIDR(nodeConfig.AgentConfig.ClusterCIDR) + enableIPv4 := dualCluster || dualService || dualNode || serviceIPv4 || clusterIPv4 enableIPv6 := dualCluster || dualService || dualNode || serviceIPv6 || clusterIPv6 conntrackConfig, err := getConntrackConfig(nodeConfig) if err != nil { return errors.Wrap(err, "failed to validate kube-proxy conntrack configuration") } syssetup.Configure(enableIPv6, conntrackConfig) + nodeConfig.AgentConfig.EnableIPv4 = enableIPv4 nodeConfig.AgentConfig.EnableIPv6 = enableIPv6 if err := setupCriCtlConfig(cfg, nodeConfig); err != nil { diff --git a/pkg/daemons/config/types.go b/pkg/daemons/config/types.go index f01fa29c269c..801f68901b0f 100644 --- a/pkg/daemons/config/types.go +++ b/pkg/daemons/config/types.go @@ -122,6 +122,7 @@ type Agent struct { Rootless bool ProtectKernelDefaults bool DisableServiceLB bool + EnableIPv4 bool EnableIPv6 bool } From 1cb80fb69d08a990948acd6e712402276854176d Mon Sep 17 00:00:00 2001 From: Manuel Buil Date: Fri, 22 Apr 2022 16:04:22 +0200 Subject: [PATCH 2/4] Check if user has a correct cluster-cidr and service-cidr config Signed-off-by: Manuel Buil --- pkg/agent/run.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pkg/agent/run.go b/pkg/agent/run.go index e521e14c4966..6070f5e4e75a 100644 --- a/pkg/agent/run.go +++ b/pkg/agent/run.go @@ -2,6 +2,7 @@ package agent import ( "context" + "fmt" "net" "os" "path/filepath" @@ -65,11 +66,19 @@ func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error { } serviceIPv4 := utilsnet.IsIPv4CIDR(nodeConfig.AgentConfig.ServiceCIDR) clusterIPv4 := utilsnet.IsIPv4CIDR(nodeConfig.AgentConfig.ClusterCIDR) + nodeIPv4 := utilsnet.IsIPv4String(nodeConfig.AgentConfig.NodeIP) serviceIPv6 := utilsnet.IsIPv6CIDR(nodeConfig.AgentConfig.ServiceCIDR) clusterIPv6 := utilsnet.IsIPv6CIDR(nodeConfig.AgentConfig.ClusterCIDR) + nodeIPv6 := utilsnet.IsIPv6String(nodeConfig.AgentConfig.NodeIP) + if (serviceIPv6 != clusterIPv6) || (dualCluster != dualService) || (serviceIPv4 != clusterIPv4) { + return fmt.Errorf("cluster-cidr: %v and service-cidr: %v, must share the same IP version (IPv4, IPv6 or dual-stack)", nodeConfig.AgentConfig.ClusterCIDRs, nodeConfig.AgentConfig.ServiceCIDRs) + } + if (clusterIPv6 != nodeIPv6) || (dualCluster != dualNode) || (clusterIPv4 != nodeIPv4) { + return fmt.Errorf("cluster-cidr: %v and node-ip: %v, must share the same IP version (IPv4, IPv6 or dual-stack)", nodeConfig.AgentConfig.ClusterCIDRs, nodeConfig.AgentConfig.NodeIPs) + } + enableIPv6 := dualCluster || clusterIPv6 + enableIPv4 := dualCluster || clusterIPv4 - enableIPv4 := dualCluster || dualService || dualNode || serviceIPv4 || clusterIPv4 - enableIPv6 := dualCluster || dualService || dualNode || serviceIPv6 || clusterIPv6 conntrackConfig, err := getConntrackConfig(nodeConfig) if err != nil { return errors.Wrap(err, "failed to validate kube-proxy conntrack configuration") From 708844fadadd15afad37912365e36c0d670f4bff Mon Sep 17 00:00:00 2001 From: Roberto Bonafiglia Date: Fri, 29 Jul 2022 17:21:23 +0200 Subject: [PATCH 3/4] Added NodeIP autodect in case of dualstack connection Signed-off-by: Roberto Bonafiglia --- pkg/agent/run.go | 2 +- pkg/netutil/iface.go | 10 +++++++++- pkg/util/net.go | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pkg/agent/run.go b/pkg/agent/run.go index 6070f5e4e75a..82046b39b506 100644 --- a/pkg/agent/run.go +++ b/pkg/agent/run.go @@ -73,7 +73,7 @@ func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error { if (serviceIPv6 != clusterIPv6) || (dualCluster != dualService) || (serviceIPv4 != clusterIPv4) { return fmt.Errorf("cluster-cidr: %v and service-cidr: %v, must share the same IP version (IPv4, IPv6 or dual-stack)", nodeConfig.AgentConfig.ClusterCIDRs, nodeConfig.AgentConfig.ServiceCIDRs) } - if (clusterIPv6 != nodeIPv6) || (dualCluster != dualNode) || (clusterIPv4 != nodeIPv4) { + if (clusterIPv6 && !nodeIPv6) || (dualCluster && !dualNode) || (clusterIPv4 && !nodeIPv4) { return fmt.Errorf("cluster-cidr: %v and node-ip: %v, must share the same IP version (IPv4, IPv6 or dual-stack)", nodeConfig.AgentConfig.ClusterCIDRs, nodeConfig.AgentConfig.NodeIPs) } enableIPv6 := dualCluster || clusterIPv6 diff --git a/pkg/netutil/iface.go b/pkg/netutil/iface.go index abf00a79198f..bfe1654bbd51 100644 --- a/pkg/netutil/iface.go +++ b/pkg/netutil/iface.go @@ -32,6 +32,7 @@ func getIPFromInterface(ifaceName string) (string, error) { } globalUnicasts := []string{} + globalUnicastsIPv6 := []string{} for _, addr := range addrs { ip, _, err := net.ParseCIDR(addr.String()) if err != nil { @@ -39,6 +40,9 @@ func getIPFromInterface(ifaceName string) (string, error) { } // skipping if not ipv4 if ip.To4() == nil { + if ip.IsGlobalUnicast() { + globalUnicastsIPv6 = append(globalUnicastsIPv6, ip.String()) + } continue } if ip.IsGlobalUnicast() { @@ -49,8 +53,12 @@ func getIPFromInterface(ifaceName string) (string, error) { if len(globalUnicasts) > 1 { return "", fmt.Errorf("multiple global unicast addresses defined for %s, please set ip from one of %v", ifaceName, globalUnicasts) } - if len(globalUnicasts) == 1 { + if len(globalUnicasts) == 1 && len(globalUnicastsIPv6) == 0 { return globalUnicasts[0], nil + } else if len(globalUnicastsIPv6) > 0 && len(globalUnicasts) == 1 { + return globalUnicasts[0] + "," + globalUnicastsIPv6[0], nil + } else if len(globalUnicastsIPv6) > 0 { + return globalUnicastsIPv6[0], nil } return "", fmt.Errorf("can't find ip for interface %s", ifaceName) diff --git a/pkg/util/net.go b/pkg/util/net.go index 8118816d223f..c26f464dd98a 100644 --- a/pkg/util/net.go +++ b/pkg/util/net.go @@ -142,6 +142,10 @@ func GetHostnameAndIPs(name string, nodeIPs cli.StringSlice) (string, []net.IP, return "", nil, err } ips = append(ips, hostIP) + hostIPv6, err := apinet.ResolveBindAddress(net.IPv6loopback) + if err == nil && !hostIPv6.Equal(hostIP) { + ips = append(ips, hostIPv6) + } } else { var err error ips, err = ParseStringSliceToIPs(nodeIPs) From 17be240d72e1d66cbce789c0bc2768e5a89df425 Mon Sep 17 00:00:00 2001 From: Roberto Bonafiglia Date: Wed, 3 Aug 2022 14:20:42 +0200 Subject: [PATCH 4/4] Fix comments and add check in case of IPv6 only node Signed-off-by: Roberto Bonafiglia --- pkg/netutil/iface.go | 2 +- pkg/util/net.go | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pkg/netutil/iface.go b/pkg/netutil/iface.go index bfe1654bbd51..c6d9b44af7ba 100644 --- a/pkg/netutil/iface.go +++ b/pkg/netutil/iface.go @@ -38,7 +38,7 @@ func getIPFromInterface(ifaceName string) (string, error) { if err != nil { return "", errors.Wrapf(err, "unable to parse CIDR for interface %s", iface.Name) } - // skipping if not ipv4 + // if not IPv4 adding it on IPv6 list if ip.To4() == nil { if ip.IsGlobalUnicast() { globalUnicastsIPv6 = append(globalUnicastsIPv6, ip.String()) diff --git a/pkg/util/net.go b/pkg/util/net.go index c26f464dd98a..6e9c2963dbef 100644 --- a/pkg/util/net.go +++ b/pkg/util/net.go @@ -142,9 +142,12 @@ func GetHostnameAndIPs(name string, nodeIPs cli.StringSlice) (string, []net.IP, return "", nil, err } ips = append(ips, hostIP) - hostIPv6, err := apinet.ResolveBindAddress(net.IPv6loopback) - if err == nil && !hostIPv6.Equal(hostIP) { - ips = append(ips, hostIPv6) + // If IPv6 it's an IPv6 only node + if hostIP.To4() != nil { + hostIPv6, err := apinet.ResolveBindAddress(net.IPv6loopback) + if err == nil && !hostIPv6.Equal(hostIP) { + ips = append(ips, hostIPv6) + } } } else { var err error