From 095ecdb0346c038b0c16c39f6f66ad4f67ad10b9 Mon Sep 17 00:00:00 2001 From: Brad Davidson Date: Wed, 17 Apr 2024 17:19:32 +0000 Subject: [PATCH] Fix issue with local traffic policy for single-stack services on dual-stack nodes. Just enable IP forwarding for all address families regardless of service address families. Signed-off-by: Brad Davidson --- pkg/cloudprovider/servicelb.go | 40 ++++++++++++---------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/pkg/cloudprovider/servicelb.go b/pkg/cloudprovider/servicelb.go index b744747ac7..7b0e26db7e 100644 --- a/pkg/cloudprovider/servicelb.go +++ b/pkg/cloudprovider/servicelb.go @@ -23,6 +23,7 @@ import ( meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/util/retry" @@ -320,10 +321,8 @@ func (k *k3s) patchStatus(svc *core.Service, previousStatus, newStatus *core.Loa // If at least one node has External IPs available, only external IPs are returned. // If no nodes have External IPs set, the Internal IPs of all nodes running pods are returned. func (k *k3s) podIPs(pods []*core.Pod, svc *core.Service, readyNodes map[string]bool) ([]string, error) { - // Go doesn't have sets so we stuff things into a map of bools and then get lists of keys - // to determine the unique set of IPs in use by pods. - extIPs := map[string]bool{} - intIPs := map[string]bool{} + extIPs := sets.Set[string]{} + intIPs := sets.Set[string]{} for _, pod := range pods { if pod.Spec.NodeName == "" || pod.Status.PodIP == "" { @@ -345,25 +344,18 @@ func (k *k3s) podIPs(pods []*core.Pod, svc *core.Service, readyNodes map[string] for _, addr := range node.Status.Addresses { if addr.Type == core.NodeExternalIP { - extIPs[addr.Address] = true + extIPs.Insert(addr.Address) } else if addr.Type == core.NodeInternalIP { - intIPs[addr.Address] = true + intIPs.Insert(addr.Address) } } } - keys := func(addrs map[string]bool) (ips []string) { - for k := range addrs { - ips = append(ips, k) - } - return ips - } - var ips []string - if len(extIPs) > 0 { - ips = keys(extIPs) + if extIPs.Len() > 0 { + ips = extIPs.UnsortedList() } else { - ips = keys(intIPs) + ips = intIPs.UnsortedList() } ips, err := filterByIPFamily(ips, svc) @@ -443,18 +435,11 @@ func (k *k3s) newDaemonSet(svc *core.Service) (*apps.DaemonSet, error) { } sourceRanges := strings.Join(sourceRangesSet.StringSlice(), ",") - var sysctls []core.Sysctl for _, ipFamily := range svc.Spec.IPFamilies { - switch ipFamily { - case core.IPv4Protocol: - sysctls = append(sysctls, core.Sysctl{Name: "net.ipv4.ip_forward", Value: "1"}) - case core.IPv6Protocol: - sysctls = append(sysctls, core.Sysctl{Name: "net.ipv6.conf.all.forwarding", Value: "1"}) + if ipFamily == core.IPv6Protocol && sourceRanges == "0.0.0.0/0" { // The upstream default load-balancer source range only includes IPv4, even if the service is IPv6-only or dual-stack. // If using the default range, and IPv6 is enabled, also allow IPv6. - if sourceRanges == "0.0.0.0/0" { - sourceRanges += ",::/0" - } + sourceRanges += ",::/0" } } @@ -490,7 +475,10 @@ func (k *k3s) newDaemonSet(svc *core.Service) (*apps.DaemonSet, error) { ServiceAccountName: "svclb", AutomountServiceAccountToken: utilsptr.To(false), SecurityContext: &core.PodSecurityContext{ - Sysctls: sysctls, + Sysctls: []core.Sysctl{ + {Name: "net.ipv4.ip_forward", Value: "1"}, + {Name: "net.ipv6.conf.all.forwarding", Value: "1"}, + }, }, Tolerations: []core.Toleration{ {