diff --git a/testing/services/main.go b/testing/services/main.go index 7b562c65..75d58cf7 100644 --- a/testing/services/main.go +++ b/testing/services/main.go @@ -218,8 +218,7 @@ func run() int { if t.Egress { ns := "kube-vip-egress" - // egress SNAT setup requires global watch: AutoDiscoverCIDRs needs kube-system pod access. - if err := deployment.EnsureNamespace(ctx, clientset, ns, t.ImagePath, true); err != nil { + if err := deployment.EnsureNamespace(ctx, clientset, ns, t.ImagePath, false); err != nil { slog.Fatalf("failed to create namespace %q: %v", ns, err) } cfg := t.WithNamespace(ns) @@ -238,8 +237,7 @@ func run() int { } if t.EgressIPv6 { ns := "kube-vip-egressv6" - // egress SNAT setup requires global watch: AutoDiscoverCIDRs needs kube-system pod access. - if err := deployment.EnsureNamespace(ctx, clientset, ns, t.ImagePath, true); err != nil { + if err := deployment.EnsureNamespace(ctx, clientset, ns, t.ImagePath, false); err != nil { slog.Fatalf("failed to create namespace %q: %v", ns, err) } cfg := t.WithNamespace(ns) diff --git a/testing/services/pkg/deployment/kind.go b/testing/services/pkg/deployment/kind.go index e9496516..455d0bfa 100644 --- a/testing/services/pkg/deployment/kind.go +++ b/testing/services/pkg/deployment/kind.go @@ -209,7 +209,7 @@ func (config *TestConfig) CreateKind() error { return err } // Replace cluster-wide rbac.yaml with two ClusterRoles: - // - kube-vip-nodes: cluster-scoped, always required + // - kube-vip-nodes: cluster-scoped node access and ServiceCIDR discovery // - kube-vip-services: used when GlobalWatch=true (per-namespace Role is used otherwise) const clusterRolesYAML = ` apiVersion: rbac.authorization.k8s.io/v1 @@ -220,6 +220,7 @@ rules: - apiGroups: [""] resources: ["nodes"] verbs: ["list", "get", "watch", "update", "patch"] +- {apiGroups: ["networking.k8s.io"], resources: ["servicecidrs"], verbs: ["list", "get", "watch"]} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole diff --git a/testing/services/pkg/deployment/kubernetes.go b/testing/services/pkg/deployment/kubernetes.go index d7871078..26d3c91b 100644 --- a/testing/services/pkg/deployment/kubernetes.go +++ b/testing/services/pkg/deployment/kubernetes.go @@ -78,6 +78,7 @@ func buildKVDsDaemonSet(ns, imageURL, metricsAddr string, globalWatch bool) apps {Name: "vip_arp", Value: "true"}, {Name: "vip_subnet", Value: "auto,auto"}, {Name: "svc_enable", Value: "true"}, + {Name: "egress_podcidr", Value: "10.244.0.0/16,fd00:10:244::/56"}, {Name: "enable_endpoints", Value: "false"}, {Name: "svc_election", Value: "true"}, {Name: "EGRESS_CLEAN", Value: "true"}, diff --git a/testing/services/pkg/deployment/kubernetes_test.go b/testing/services/pkg/deployment/kubernetes_test.go index 7e8000e7..66c0361b 100644 --- a/testing/services/pkg/deployment/kubernetes_test.go +++ b/testing/services/pkg/deployment/kubernetes_test.go @@ -23,3 +23,28 @@ func TestBackendLabelsExcludeKubeVIPDaemonSet(t *testing.T) { t.Fatal("backend selector unexpectedly matches kube-vip DaemonSet pods") } } + +func TestNamespacedKubeVIPDaemonSetEgressIsolation(t *testing.T) { + const namespace = "kube-vip-egress" + + daemonSet := buildKVDsDaemonSet(namespace, "kube-vip:test", "", false) + env := daemonSet.Spec.Template.Spec.Containers[0].Env + + want := map[string]string{ + "svc_namespace": namespace, + "egress_podcidr": "10.244.0.0/16,fd00:10:244::/56", + } + for _, variable := range env { + value, ok := want[variable.Name] + if !ok { + continue + } + if variable.Value != value { + t.Errorf("%s = %q, want %q", variable.Name, variable.Value, value) + } + delete(want, variable.Name) + } + for name := range want { + t.Errorf("%s environment variable not found", name) + } +}