test(e2e/services): isolate parallel egress watchers

Scope each egress DaemonSet to its test namespace, pin Kind's dual-stack Pod CIDRs, retain per-instance nftables tables, and grant the test service account ServiceCIDR discovery access.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
This commit is contained in:
Marcel Fest
2026-08-21 15:12:34 +02:00
parent 42ba1fefb2
commit ed28c49f48
4 changed files with 30 additions and 5 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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"},

View File

@@ -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)
}
}