From c6cc056675314ef7f74e4b318d39eadd73b2de40 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Tue, 25 Oct 2022 10:20:22 -0400 Subject: [PATCH 1/4] Replace iptables-proxy-specific SCTP e2e test with a unit test We had a test that creating a Service with an SCTP port would create an iptables rule with "-p sctp" in it, which let us test that kube-proxy was doing vaguely the right thing with SCTP even if the e2e environment didn't have SCTP support. But this would really make much more sense as a unit test. --- pkg/proxy/iptables/proxier_test.go | 24 ++++++------ test/e2e/network/service.go | 62 ------------------------------ 2 files changed, 12 insertions(+), 74 deletions(-) diff --git a/pkg/proxy/iptables/proxier_test.go b/pkg/proxy/iptables/proxier_test.go index 61b89a05be9..6b050a14713 100644 --- a/pkg/proxy/iptables/proxier_test.go +++ b/pkg/proxy/iptables/proxier_test.go @@ -2117,7 +2117,7 @@ func TestClusterIPReject(t *testing.T) { }) } -func TestClusterIPEndpointsJump(t *testing.T) { +func TestClusterIPEndpointsMore(t *testing.T) { ipt := iptablestest.NewFake() fp := NewFakeProxier(ipt) svcIP := "172.30.0.41" @@ -2125,7 +2125,7 @@ func TestClusterIPEndpointsJump(t *testing.T) { svcPortName := proxy.ServicePortName{ NamespacedName: makeNSN("ns1", "svc1"), Port: "p80", - Protocol: v1.ProtocolTCP, + Protocol: v1.ProtocolSCTP, } makeServiceMap(fp, @@ -2134,13 +2134,13 @@ func TestClusterIPEndpointsJump(t *testing.T) { svc.Spec.Ports = []v1.ServicePort{{ Name: svcPortName.Port, Port: int32(svcPort), - Protocol: v1.ProtocolTCP, + Protocol: v1.ProtocolSCTP, }} }), ) epIP := "10.180.0.1" - tcpProtocol := v1.ProtocolTCP + sctpProtocol := v1.ProtocolSCTP populateEndpointSlices(fp, makeTestEndpointSlice(svcPortName.Namespace, svcPortName.Name, 1, func(eps *discovery.EndpointSlice) { eps.AddressType = discovery.AddressTypeIPv4 @@ -2150,7 +2150,7 @@ func TestClusterIPEndpointsJump(t *testing.T) { eps.Ports = []discovery.EndpointPort{{ Name: pointer.String(svcPortName.Port), Port: pointer.Int32(int32(svcPort)), - Protocol: &tcpProtocol, + Protocol: &sctpProtocol, }} }), ) @@ -2173,18 +2173,18 @@ func TestClusterIPEndpointsJump(t *testing.T) { :KUBE-SERVICES - [0:0] :KUBE-MARK-MASQ - [0:0] :KUBE-POSTROUTING - [0:0] - :KUBE-SEP-SXIVWICOYRO3J4NJ - [0:0] - :KUBE-SVC-XPGD46QRK7WJZT7O - [0:0] - -A KUBE-SERVICES -m comment --comment "ns1/svc1:p80 cluster IP" -m tcp -p tcp -d 172.30.0.41 --dport 80 -j KUBE-SVC-XPGD46QRK7WJZT7O + :KUBE-SEP-RFW33Y6OHVBQ4W3M - [0:0] + :KUBE-SVC-GFCIFIA5VTFSTMSM - [0:0] + -A KUBE-SERVICES -m comment --comment "ns1/svc1:p80 cluster IP" -m sctp -p sctp -d 172.30.0.41 --dport 80 -j KUBE-SVC-GFCIFIA5VTFSTMSM -A KUBE-SERVICES -m comment --comment "kubernetes service nodeports; NOTE: this must be the last rule in this chain" -m addrtype --dst-type LOCAL -j KUBE-NODEPORTS -A KUBE-MARK-MASQ -j MARK --or-mark 0x4000 -A KUBE-POSTROUTING -m mark ! --mark 0x4000/0x4000 -j RETURN -A KUBE-POSTROUTING -j MARK --xor-mark 0x4000 -A KUBE-POSTROUTING -m comment --comment "kubernetes service traffic requiring SNAT" -j MASQUERADE - -A KUBE-SEP-SXIVWICOYRO3J4NJ -m comment --comment ns1/svc1:p80 -s 10.180.0.1 -j KUBE-MARK-MASQ - -A KUBE-SEP-SXIVWICOYRO3J4NJ -m comment --comment ns1/svc1:p80 -m tcp -p tcp -j DNAT --to-destination 10.180.0.1:80 - -A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 cluster IP" -m tcp -p tcp -d 172.30.0.41 --dport 80 ! -s 10.0.0.0/8 -j KUBE-MARK-MASQ - -A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.0.1:80" -j KUBE-SEP-SXIVWICOYRO3J4NJ + -A KUBE-SEP-RFW33Y6OHVBQ4W3M -m comment --comment ns1/svc1:p80 -s 10.180.0.1 -j KUBE-MARK-MASQ + -A KUBE-SEP-RFW33Y6OHVBQ4W3M -m comment --comment ns1/svc1:p80 -m sctp -p sctp -j DNAT --to-destination 10.180.0.1:80 + -A KUBE-SVC-GFCIFIA5VTFSTMSM -m comment --comment "ns1/svc1:p80 cluster IP" -m sctp -p sctp -d 172.30.0.41 --dport 80 ! -s 10.0.0.0/8 -j KUBE-MARK-MASQ + -A KUBE-SVC-GFCIFIA5VTFSTMSM -m comment --comment "ns1/svc1:p80 -> 10.180.0.1:80" -j KUBE-SEP-RFW33Y6OHVBQ4W3M COMMIT `) assertIPTablesRulesEqual(t, getLine(), true, expected, fp.iptablesData.String()) diff --git a/test/e2e/network/service.go b/test/e2e/network/service.go index 00be2448d1d..3b06eafe04f 100644 --- a/test/e2e/network/service.go +++ b/test/e2e/network/service.go @@ -4429,66 +4429,4 @@ var _ = common.SIGDescribe("SCTP [LinuxOnly]", func() { framework.Failf("The state of the sctp module has changed due to the test case") } }) - ginkgo.It("should create a ClusterIP Service with SCTP ports", func(ctx context.Context) { - ginkgo.By("checking that kube-proxy is in iptables mode") - if proxyMode, err := proxyMode(f); err != nil { - e2eskipper.Skipf("Couldn't detect KubeProxy mode - skip, %v", err) - } else if proxyMode != "iptables" { - e2eskipper.Skipf("The test doesn't work if kube-proxy is not in iptables mode") - } - - serviceName := "sctp-clusterip" - ns := f.Namespace.Name - jig := e2eservice.NewTestJig(cs, ns, serviceName) - - ginkgo.By("getting the state of the sctp module on nodes") - nodes, err := e2enode.GetBoundedReadySchedulableNodes(cs, 2) - framework.ExpectNoError(err) - sctpLoadedAtStart := CheckSCTPModuleLoadedOnNodes(f, nodes) - - ginkgo.By("creating service " + serviceName + " in namespace " + ns) - _, err = jig.CreateSCTPServiceWithPort(func(svc *v1.Service) { - svc.Spec.Type = v1.ServiceTypeClusterIP - svc.Spec.Ports = []v1.ServicePort{{Protocol: v1.ProtocolSCTP, Port: 5060}} - }, 5060) - framework.ExpectNoError(err) - ginkgo.DeferCleanup(func(ctx context.Context) { - err := cs.CoreV1().Services(ns).Delete(ctx, serviceName, metav1.DeleteOptions{}) - framework.ExpectNoError(err, "failed to delete service: %s in namespace: %s", serviceName, ns) - }) - - err = e2enetwork.WaitForService(f.ClientSet, ns, serviceName, true, 5*time.Second, e2eservice.TestTimeout) - framework.ExpectNoError(err, fmt.Sprintf("error while waiting for service:%s err: %v", serviceName, err)) - hostExec := utils.NewHostExec(f) - ginkgo.DeferCleanup(hostExec.Cleanup) - node := &nodes.Items[0] - cmd := "iptables-save" - if framework.TestContext.ClusterIsIPv6() { - cmd = "ip6tables-save" - } - err = wait.PollImmediate(framework.Poll, e2eservice.KubeProxyLagTimeout, func() (bool, error) { - framework.Logf("Executing cmd %q on node %v", cmd, node.Name) - result, err := hostExec.IssueCommandWithResult(cmd, node) - if err != nil { - framework.Logf("Interrogation of iptables rules failed on node %v", node.Name) - return false, nil - } - - for _, line := range strings.Split(result, "\n") { - if strings.Contains(line, "-A KUBE-SERVICES") && strings.Contains(line, "-p sctp") { - return true, nil - } - } - framework.Logf("retrying ... no iptables rules found for service with sctp ports on node %v", node.Name) - return false, nil - }) - if err != nil { - framework.Failf("iptables rules are not set for a clusterip service with sctp ports") - } - ginkgo.By("validating sctp module is still not loaded") - sctpLoadedAtEnd := CheckSCTPModuleLoadedOnNodes(f, nodes) - if !sctpLoadedAtStart && sctpLoadedAtEnd { - framework.Failf("The state of the sctp module has changed due to the test case") - } - }) }) From d9981065ddd81848c14099f6a60a05df037e1870 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Tue, 25 Oct 2022 11:03:00 -0400 Subject: [PATCH 2/4] Drop iptables-specific test from SCTP HostPort test The SCTP HostPort test was checking that creating a pod with an SCTP HostPort would create a certain iptables rule, but the handling of HostPorts is now up to CRI, not kubelet, so kubernetes e2e cannot assume it will implement the feature in any specific way. (The test still ensures that (a) the apiserver accepts SCTP HostPorts, and (b) neither kubelet nor the runtime causes the SCTP kernel module to be loaded as part of creating a pod with an SCTP HostPort.) --- test/e2e/network/service.go | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/test/e2e/network/service.go b/test/e2e/network/service.go index 3b06eafe04f..cd62bbcb92e 100644 --- a/test/e2e/network/service.go +++ b/test/e2e/network/service.go @@ -4375,7 +4375,7 @@ var _ = common.SIGDescribe("SCTP [LinuxOnly]", func() { } }) - ginkgo.It("should create a Pod with SCTP HostPort", func(ctx context.Context) { + ginkgo.It("should allow creating a Pod with an SCTP HostPort", func(ctx context.Context) { node, err := e2enode.GetRandomReadySchedulableNode(cs) framework.ExpectNoError(err) hostExec := utils.NewHostExec(f) @@ -4399,30 +4399,6 @@ var _ = common.SIGDescribe("SCTP [LinuxOnly]", func() { err := cs.CoreV1().Pods(f.Namespace.Name).Delete(ctx, podName, metav1.DeleteOptions{}) framework.ExpectNoError(err, "failed to delete pod: %s in namespace: %s", podName, f.Namespace.Name) }) - // wait until host port manager syncs rules - cmd := "iptables-save" - if framework.TestContext.ClusterIsIPv6() { - cmd = "ip6tables-save" - } - err = wait.PollImmediate(framework.Poll, framework.PollShortTimeout, func() (bool, error) { - framework.Logf("Executing cmd %q on node %v", cmd, node.Name) - result, err := hostExec.IssueCommandWithResult(cmd, node) - if err != nil { - framework.Logf("Interrogation of iptables rules failed on node %v", node.Name) - return false, nil - } - - for _, line := range strings.Split(result, "\n") { - if strings.Contains(line, "-p sctp") && strings.Contains(line, "--dport 5060") { - return true, nil - } - } - framework.Logf("retrying ... not hostport sctp iptables rules found on node %v", node.Name) - return false, nil - }) - if err != nil { - framework.Failf("iptables rules are not set for a pod with sctp hostport") - } ginkgo.By("validating sctp module is still not loaded") sctpLoadedAtEnd := CheckSCTPModuleLoadedOnNodes(f, nodes) if !sctpLoadedAtStart && sctpLoadedAtEnd { From 4cee7197ebb8819856349960865108800db72000 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 3 Nov 2022 10:49:44 -0400 Subject: [PATCH 3/4] Move two SCTP tests There were two SCTP tests grouped together in test/e2e/network/service.go, but one of them wasn't a service test... so move the SCTP service test to be grouped with the other service tests, and the SCTP hostport tests to be grouped with other non-service tests. --- test/e2e/network/networking.go | 33 ++++++++ test/e2e/network/service.go | 150 ++++++++++++--------------------- 2 files changed, 86 insertions(+), 97 deletions(-) diff --git a/test/e2e/network/networking.go b/test/e2e/network/networking.go index 1fd09f31f92..619adfff266 100644 --- a/test/e2e/network/networking.go +++ b/test/e2e/network/networking.go @@ -29,10 +29,12 @@ import ( "k8s.io/kubernetes/pkg/cluster/ports" "k8s.io/kubernetes/test/e2e/framework" e2enetwork "k8s.io/kubernetes/test/e2e/framework/network" + e2enode "k8s.io/kubernetes/test/e2e/framework/node" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper" e2essh "k8s.io/kubernetes/test/e2e/framework/ssh" "k8s.io/kubernetes/test/e2e/network/common" + "k8s.io/kubernetes/test/e2e/storage/utils" admissionapi "k8s.io/pod-security-admission/api" "github.com/onsi/ginkgo/v2" @@ -632,4 +634,35 @@ var _ = common.SIGDescribe("Networking", func() { } framework.ExpectNoError(err, "kubelet did not recreate its iptables rules") }) + + ginkgo.It("should allow creating a Pod with an SCTP HostPort [LinuxOnly]", func(ctx context.Context) { + node, err := e2enode.GetRandomReadySchedulableNode(f.ClientSet) + framework.ExpectNoError(err) + hostExec := utils.NewHostExec(f) + ginkgo.DeferCleanup(hostExec.Cleanup) + + ginkgo.By("getting the state of the sctp module on the selected node") + nodes := &v1.NodeList{} + nodes.Items = append(nodes.Items, *node) + sctpLoadedAtStart := CheckSCTPModuleLoadedOnNodes(f, nodes) + + ginkgo.By("creating a pod with hostport on the selected node") + podName := "hostport" + ports := []v1.ContainerPort{{Protocol: v1.ProtocolSCTP, ContainerPort: 5060, HostPort: 5060}} + podSpec := e2epod.NewAgnhostPod(f.Namespace.Name, podName, nil, nil, ports) + nodeSelection := e2epod.NodeSelection{Name: node.Name} + e2epod.SetNodeSelection(&podSpec.Spec, nodeSelection) + + ginkgo.By(fmt.Sprintf("Launching the pod on node %v", node.Name)) + e2epod.NewPodClient(f).CreateSync(podSpec) + ginkgo.DeferCleanup(func(ctx context.Context) { + err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Delete(ctx, podName, metav1.DeleteOptions{}) + framework.ExpectNoError(err, "failed to delete pod: %s in namespace: %s", podName, f.Namespace.Name) + }) + ginkgo.By("validating sctp module is still not loaded") + sctpLoadedAtEnd := CheckSCTPModuleLoadedOnNodes(f, nodes) + if !sctpLoadedAtStart && sctpLoadedAtEnd { + framework.Failf("The state of the sctp module has changed due to the test case") + } + }) }) diff --git a/test/e2e/network/service.go b/test/e2e/network/service.go index cd62bbcb92e..a797bb0f610 100644 --- a/test/e2e/network/service.go +++ b/test/e2e/network/service.go @@ -70,7 +70,6 @@ import ( e2eservice "k8s.io/kubernetes/test/e2e/framework/service" e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper" "k8s.io/kubernetes/test/e2e/network/common" - "k8s.io/kubernetes/test/e2e/storage/utils" testutils "k8s.io/kubernetes/test/utils" imageutils "k8s.io/kubernetes/test/utils/image" @@ -3781,6 +3780,59 @@ var _ = common.SIGDescribe("Services", func() { e2epod.DeletePodOrFail(cs, ns, podname1) }) + ginkgo.It("should allow creating a basic SCTP service with pod and endpoints [LinuxOnly]", func(ctx context.Context) { + serviceName := "sctp-endpoint-test" + ns := f.Namespace.Name + jig := e2eservice.NewTestJig(cs, ns, serviceName) + + ginkgo.By("getting the state of the sctp module on nodes") + nodes, err := e2enode.GetBoundedReadySchedulableNodes(cs, 2) + framework.ExpectNoError(err) + sctpLoadedAtStart := CheckSCTPModuleLoadedOnNodes(f, nodes) + + ginkgo.By("creating service " + serviceName + " in namespace " + ns) + _, err = jig.CreateSCTPServiceWithPort(nil, 5060) + framework.ExpectNoError(err) + ginkgo.DeferCleanup(func(ctx context.Context) { + err := cs.CoreV1().Services(ns).Delete(ctx, serviceName, metav1.DeleteOptions{}) + framework.ExpectNoError(err, "failed to delete service: %s in namespace: %s", serviceName, ns) + }) + + err = e2enetwork.WaitForService(f.ClientSet, ns, serviceName, true, 5*time.Second, e2eservice.TestTimeout) + framework.ExpectNoError(err, fmt.Sprintf("error while waiting for service:%s err: %v", serviceName, err)) + + ginkgo.By("validating endpoints do not exist yet") + validateEndpointsPortsOrFail(cs, ns, serviceName, portsByPodName{}) + + ginkgo.By("creating a pod for the service") + names := map[string]bool{} + + name1 := "pod1" + + createPodOrFail(f, ns, name1, jig.Labels, []v1.ContainerPort{{ContainerPort: 5060, Protocol: v1.ProtocolSCTP}}) + names[name1] = true + ginkgo.DeferCleanup(func(ctx context.Context) { + for name := range names { + err := cs.CoreV1().Pods(ns).Delete(ctx, name, metav1.DeleteOptions{}) + framework.ExpectNoError(err, "failed to delete pod: %s in namespace: %s", name, ns) + } + }) + + ginkgo.By("validating endpoints exists") + validateEndpointsPortsOrFail(cs, ns, serviceName, portsByPodName{name1: {5060}}) + + ginkgo.By("deleting the pod") + e2epod.DeletePodOrFail(cs, ns, name1) + delete(names, name1) + ginkgo.By("validating endpoints do not exist anymore") + validateEndpointsPortsOrFail(cs, ns, serviceName, portsByPodName{}) + + ginkgo.By("validating sctp module is still not loaded") + sctpLoadedAtEnd := CheckSCTPModuleLoadedOnNodes(f, nodes) + if !sctpLoadedAtStart && sctpLoadedAtEnd { + framework.Failf("The state of the sctp module has changed due to the test case") + } + }) }) // execAffinityTestForSessionAffinityTimeout is a helper function that wrap the logic of @@ -4310,99 +4362,3 @@ func validatePortsAndProtocols(ep, expectedEndpoints fullPortsByPodUID) error { } return nil } - -var _ = common.SIGDescribe("SCTP [LinuxOnly]", func() { - f := framework.NewDefaultFramework("sctp") - f.NamespacePodSecurityEnforceLevel = admissionapi.LevelPrivileged - - var cs clientset.Interface - - ginkgo.BeforeEach(func() { - cs = f.ClientSet - }) - - ginkgo.It("should allow creating a basic SCTP service with pod and endpoints", func(ctx context.Context) { - serviceName := "sctp-endpoint-test" - ns := f.Namespace.Name - jig := e2eservice.NewTestJig(cs, ns, serviceName) - - ginkgo.By("getting the state of the sctp module on nodes") - nodes, err := e2enode.GetBoundedReadySchedulableNodes(cs, 2) - framework.ExpectNoError(err) - sctpLoadedAtStart := CheckSCTPModuleLoadedOnNodes(f, nodes) - - ginkgo.By("creating service " + serviceName + " in namespace " + ns) - _, err = jig.CreateSCTPServiceWithPort(nil, 5060) - framework.ExpectNoError(err) - ginkgo.DeferCleanup(func(ctx context.Context) { - err := cs.CoreV1().Services(ns).Delete(ctx, serviceName, metav1.DeleteOptions{}) - framework.ExpectNoError(err, "failed to delete service: %s in namespace: %s", serviceName, ns) - }) - - err = e2enetwork.WaitForService(f.ClientSet, ns, serviceName, true, 5*time.Second, e2eservice.TestTimeout) - framework.ExpectNoError(err, fmt.Sprintf("error while waiting for service:%s err: %v", serviceName, err)) - - ginkgo.By("validating endpoints do not exist yet") - validateEndpointsPortsOrFail(cs, ns, serviceName, portsByPodName{}) - - ginkgo.By("creating a pod for the service") - names := map[string]bool{} - - name1 := "pod1" - - createPodOrFail(f, ns, name1, jig.Labels, []v1.ContainerPort{{ContainerPort: 5060, Protocol: v1.ProtocolSCTP}}) - names[name1] = true - ginkgo.DeferCleanup(func(ctx context.Context) { - for name := range names { - err := cs.CoreV1().Pods(ns).Delete(ctx, name, metav1.DeleteOptions{}) - framework.ExpectNoError(err, "failed to delete pod: %s in namespace: %s", name, ns) - } - }) - - ginkgo.By("validating endpoints exists") - validateEndpointsPortsOrFail(cs, ns, serviceName, portsByPodName{name1: {5060}}) - - ginkgo.By("deleting the pod") - e2epod.DeletePodOrFail(cs, ns, name1) - delete(names, name1) - ginkgo.By("validating endpoints do not exist anymore") - validateEndpointsPortsOrFail(cs, ns, serviceName, portsByPodName{}) - - ginkgo.By("validating sctp module is still not loaded") - sctpLoadedAtEnd := CheckSCTPModuleLoadedOnNodes(f, nodes) - if !sctpLoadedAtStart && sctpLoadedAtEnd { - framework.Failf("The state of the sctp module has changed due to the test case") - } - }) - - ginkgo.It("should allow creating a Pod with an SCTP HostPort", func(ctx context.Context) { - node, err := e2enode.GetRandomReadySchedulableNode(cs) - framework.ExpectNoError(err) - hostExec := utils.NewHostExec(f) - ginkgo.DeferCleanup(hostExec.Cleanup) - - ginkgo.By("getting the state of the sctp module on the selected node") - nodes := &v1.NodeList{} - nodes.Items = append(nodes.Items, *node) - sctpLoadedAtStart := CheckSCTPModuleLoadedOnNodes(f, nodes) - - ginkgo.By("creating a pod with hostport on the selected node") - podName := "hostport" - ports := []v1.ContainerPort{{Protocol: v1.ProtocolSCTP, ContainerPort: 5060, HostPort: 5060}} - podSpec := e2epod.NewAgnhostPod(f.Namespace.Name, podName, nil, nil, ports) - nodeSelection := e2epod.NodeSelection{Name: node.Name} - e2epod.SetNodeSelection(&podSpec.Spec, nodeSelection) - - ginkgo.By(fmt.Sprintf("Launching the pod on node %v", node.Name)) - e2epod.NewPodClient(f).CreateSync(podSpec) - ginkgo.DeferCleanup(func(ctx context.Context) { - err := cs.CoreV1().Pods(f.Namespace.Name).Delete(ctx, podName, metav1.DeleteOptions{}) - framework.ExpectNoError(err, "failed to delete pod: %s in namespace: %s", podName, f.Namespace.Name) - }) - ginkgo.By("validating sctp module is still not loaded") - sctpLoadedAtEnd := CheckSCTPModuleLoadedOnNodes(f, nodes) - if !sctpLoadedAtStart && sctpLoadedAtEnd { - framework.Failf("The state of the sctp module has changed due to the test case") - } - }) -}) From 41e1435d97377e3c3bf4db6fbe700c8e12ca4cbc Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Tue, 25 Oct 2022 11:59:21 -0400 Subject: [PATCH 4/4] Remove [Disruptive] from Feature:SCTPConnectivity tests The Feature:SCTPConnectivity tests cannot run at the same time as the "X doesn't cause sctp.ko to be loaded" tests, since they may cause sctp.ko to be loaded. We had dealt with this in the past by marking them [Disruptive], but this isn't really fair; the problem is more with the sctp.ko-checking tests than it is with the SCTPConnectivity tests. So make them not [Disruptive] and instead make the sctp.ko-checking tests be [Serial]. --- test/e2e/common/network/networking.go | 6 ++---- test/e2e/network/dual_stack.go | 3 +-- test/e2e/network/netpol/network_legacy.go | 7 +++++-- test/e2e/network/netpol/network_policy.go | 2 +- test/e2e/network/networking.go | 13 ++++++------- test/e2e/network/service.go | 4 +++- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/test/e2e/common/network/networking.go b/test/e2e/common/network/networking.go index 3f8d463399a..452707edc78 100644 --- a/test/e2e/common/network/networking.go +++ b/test/e2e/common/network/networking.go @@ -131,14 +131,12 @@ var _ = SIGDescribe("Networking", func() { } }) - // [Disruptive] because it conflicts with tests that call CheckSCTPModuleLoadedOnNodes - ginkgo.It("should function for intra-pod communication: sctp [LinuxOnly][Feature:SCTPConnectivity][Disruptive]", func(ctx context.Context) { + ginkgo.It("should function for intra-pod communication: sctp [LinuxOnly][Feature:SCTPConnectivity]", func(ctx context.Context) { config := e2enetwork.NewNetworkingTestConfig(f, e2enetwork.EnableSCTP) checkPodToPodConnectivity(config, "sctp", e2enetwork.EndpointSCTPPort) }) - // [Disruptive] because it conflicts with tests that call CheckSCTPModuleLoadedOnNodes - ginkgo.It("should function for node-pod communication: sctp [LinuxOnly][Feature:SCTPConnectivity][Disruptive]", func(ctx context.Context) { + ginkgo.It("should function for node-pod communication: sctp [LinuxOnly][Feature:SCTPConnectivity]", func(ctx context.Context) { ginkgo.Skip("Skipping SCTP node to pod test until DialFromNode supports SCTP #96482") config := e2enetwork.NewNetworkingTestConfig(f, e2enetwork.EnableSCTP) for _, endpointPod := range config.EndpointPods { diff --git a/test/e2e/network/dual_stack.go b/test/e2e/network/dual_stack.go index b1ae6c0739c..5d473549396 100644 --- a/test/e2e/network/dual_stack.go +++ b/test/e2e/network/dual_stack.go @@ -462,8 +462,7 @@ var _ = common.SIGDescribe("[Feature:IPv6DualStack]", func() { } }) - // [Disruptive] because it conflicts with tests that call CheckSCTPModuleLoadedOnNodes - ginkgo.It("should function for pod-Service: sctp [Feature:SCTPConnectivity][Disruptive]", func(ctx context.Context) { + ginkgo.It("should function for pod-Service: sctp [Feature:SCTPConnectivity]", func(ctx context.Context) { config := e2enetwork.NewNetworkingTestConfig(f, e2enetwork.EnableDualStack, e2enetwork.EnableSCTP) ginkgo.By(fmt.Sprintf("dialing(sctp) %v --> %v:%v (config.clusterIP)", config.TestContainerPod.Name, config.SecondaryClusterIP, e2enetwork.ClusterSCTPPort)) err := config.DialFromTestContainer("sctp", config.SecondaryClusterIP, e2enetwork.ClusterSCTPPort, config.MaxTries, 0, config.EndpointHostnames()) diff --git a/test/e2e/network/netpol/network_legacy.go b/test/e2e/network/netpol/network_legacy.go index 4875c88476a..6702afb60ab 100644 --- a/test/e2e/network/netpol/network_legacy.go +++ b/test/e2e/network/netpol/network_legacy.go @@ -1686,7 +1686,10 @@ var _ = common.SIGDescribe("NetworkPolicyLegacy [LinuxOnly]", func() { }) cleanupServerPodAndService(f, podA, serviceA) }) - ginkgo.It("should not allow access by TCP when a policy specifies only SCTP [Feature:NetworkPolicy]", func(ctx context.Context) { + + // This is [Serial] because it can't run at the same time as the + // [Feature:SCTPConnectivity] tests, since they may cause sctp.ko to be loaded. + ginkgo.It("should not allow access by TCP when a policy specifies only SCTP [Feature:NetworkPolicy] [Serial]", func(ctx context.Context) { ginkgo.By("getting the state of the sctp module on nodes") nodes, err := e2enode.GetReadySchedulableNodes(f.ClientSet) framework.ExpectNoError(err) @@ -1729,7 +1732,7 @@ var _ = common.SIGDescribe("NetworkPolicyLegacy [LinuxOnly]", func() { }) }) -var _ = common.SIGDescribe("NetworkPolicy [Feature:SCTPConnectivity][LinuxOnly][Disruptive]", func() { +var _ = common.SIGDescribe("NetworkPolicy [Feature:SCTPConnectivity][LinuxOnly]", func() { var service *v1.Service var podServer *v1.Pod var podServerLabelSelector string diff --git a/test/e2e/network/netpol/network_policy.go b/test/e2e/network/netpol/network_policy.go index 05bb2f19113..4cb45cf02bf 100644 --- a/test/e2e/network/netpol/network_policy.go +++ b/test/e2e/network/netpol/network_policy.go @@ -1312,7 +1312,7 @@ var _ = common.SIGDescribe("Netpol [LinuxOnly]", func() { }) }) -var _ = common.SIGDescribe("Netpol [Feature:SCTPConnectivity][LinuxOnly][Disruptive]", func() { +var _ = common.SIGDescribe("Netpol [Feature:SCTPConnectivity][LinuxOnly]", func() { f := framework.NewDefaultFramework("sctp-network-policy") f.SkipNamespaceCreation = true f.NamespacePodSecurityEnforceLevel = admissionapi.LevelBaseline diff --git a/test/e2e/network/networking.go b/test/e2e/network/networking.go index 619adfff266..fac8c030fb7 100644 --- a/test/e2e/network/networking.go +++ b/test/e2e/network/networking.go @@ -176,8 +176,7 @@ var _ = common.SIGDescribe("Networking", func() { } }) - // [Disruptive] because it conflicts with tests that call CheckSCTPModuleLoadedOnNodes - ginkgo.It("should function for pod-Service: sctp [Feature:SCTPConnectivity][Disruptive]", func(ctx context.Context) { + ginkgo.It("should function for pod-Service: sctp [Feature:SCTPConnectivity]", func(ctx context.Context) { config := e2enetwork.NewNetworkingTestConfig(f, e2enetwork.EnableSCTP) ginkgo.By(fmt.Sprintf("dialing(sctp) %v --> %v:%v (config.clusterIP)", config.TestContainerPod.Name, config.ClusterIP, e2enetwork.ClusterSCTPPort)) err := config.DialFromTestContainer("sctp", config.ClusterIP, e2enetwork.ClusterSCTPPort, config.MaxTries, 0, config.EndpointHostnames()) @@ -219,8 +218,7 @@ var _ = common.SIGDescribe("Networking", func() { } }) - // [Disruptive] because it conflicts with tests that call CheckSCTPModuleLoadedOnNodes - ginkgo.It("should function for node-Service: sctp [Feature:SCTPConnectivity][Disruptive]", func(ctx context.Context) { + ginkgo.It("should function for node-Service: sctp [Feature:SCTPConnectivity]", func(ctx context.Context) { ginkgo.Skip("Skipping SCTP node to service test until DialFromNode supports SCTP #96482") config := e2enetwork.NewNetworkingTestConfig(f, e2enetwork.EnableSCTP) ginkgo.By(fmt.Sprintf("dialing(sctp) %v (node) --> %v:%v (config.clusterIP)", config.NodeIP, config.ClusterIP, e2enetwork.ClusterSCTPPort)) @@ -264,8 +262,7 @@ var _ = common.SIGDescribe("Networking", func() { } }) - // [Disruptive] because it conflicts with tests that call CheckSCTPModuleLoadedOnNodes - ginkgo.It("should function for endpoint-Service: sctp [Feature:SCTPConnectivity][Disruptive]", func(ctx context.Context) { + ginkgo.It("should function for endpoint-Service: sctp [Feature:SCTPConnectivity]", func(ctx context.Context) { config := e2enetwork.NewNetworkingTestConfig(f, e2enetwork.EnableSCTP) ginkgo.By(fmt.Sprintf("dialing(sctp) %v (endpoint) --> %v:%v (config.clusterIP)", config.EndpointPods[0].Name, config.ClusterIP, e2enetwork.ClusterSCTPPort)) err := config.DialFromEndpointContainer("sctp", config.ClusterIP, e2enetwork.ClusterSCTPPort, config.MaxTries, 0, config.EndpointHostnames()) @@ -635,7 +632,9 @@ var _ = common.SIGDescribe("Networking", func() { framework.ExpectNoError(err, "kubelet did not recreate its iptables rules") }) - ginkgo.It("should allow creating a Pod with an SCTP HostPort [LinuxOnly]", func(ctx context.Context) { + // This is [Serial] because it can't run at the same time as the + // [Feature:SCTPConnectivity] tests, since they may cause sctp.ko to be loaded. + ginkgo.It("should allow creating a Pod with an SCTP HostPort [LinuxOnly] [Serial]", func(ctx context.Context) { node, err := e2enode.GetRandomReadySchedulableNode(f.ClientSet) framework.ExpectNoError(err) hostExec := utils.NewHostExec(f) diff --git a/test/e2e/network/service.go b/test/e2e/network/service.go index a797bb0f610..fcaf4eebb71 100644 --- a/test/e2e/network/service.go +++ b/test/e2e/network/service.go @@ -3780,7 +3780,9 @@ var _ = common.SIGDescribe("Services", func() { e2epod.DeletePodOrFail(cs, ns, podname1) }) - ginkgo.It("should allow creating a basic SCTP service with pod and endpoints [LinuxOnly]", func(ctx context.Context) { + // These is [Serial] because it can't run at the same time as the + // [Feature:SCTPConnectivity] tests, since they may cause sctp.ko to be loaded. + ginkgo.It("should allow creating a basic SCTP service with pod and endpoints [LinuxOnly] [Serial]", func(ctx context.Context) { serviceName := "sctp-endpoint-test" ns := f.Namespace.Name jig := e2eservice.NewTestJig(cs, ns, serviceName)