@@ -56,6 +56,7 @@ import (
56
56
e2eservice "k8s.io/kubernetes/test/e2e/framework/service"
57
57
e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
58
58
e2essh "k8s.io/kubernetes/test/e2e/framework/ssh"
59
+ "k8s.io/kubernetes/test/e2e/storage/utils"
59
60
testutils "k8s.io/kubernetes/test/utils"
60
61
imageutils "k8s.io/kubernetes/test/utils/image"
61
62
gcecloud "k8s.io/legacy-cloud-providers/gce"
@@ -3863,3 +3864,211 @@ func getApiserverRestartCount(c clientset.Interface) (int32, error) {
3863
3864
}
3864
3865
return - 1 , fmt .Errorf ("Failed to find kube-apiserver container in pod" )
3865
3866
}
3867
+
3868
+ var _ = SIGDescribe ("SCTP [Feature:SCTP] [LinuxOnly]" , func () {
3869
+ f := framework .NewDefaultFramework ("sctp" )
3870
+
3871
+ var cs clientset.Interface
3872
+
3873
+ ginkgo .BeforeEach (func () {
3874
+ cs = f .ClientSet
3875
+ })
3876
+
3877
+ ginkgo .It ("should allow creating a basic SCTP service with pod and endpoints" , func () {
3878
+ serviceName := "sctp-endpoint-test"
3879
+ ns := f .Namespace .Name
3880
+ jig := e2eservice .NewTestJig (cs , ns , serviceName )
3881
+
3882
+ ginkgo .By ("getting the state of the sctp module on nodes" )
3883
+ nodes , err := e2enode .GetReadySchedulableNodes (cs )
3884
+ framework .ExpectNoError (err )
3885
+ sctpLoadedAtStart := CheckSCTPModuleLoadedOnNodes (f , nodes )
3886
+
3887
+ ginkgo .By ("creating service " + serviceName + " in namespace " + ns )
3888
+ _ , err = jig .CreateSCTPServiceWithPort (nil , 5060 )
3889
+ framework .ExpectNoError (err )
3890
+ defer func () {
3891
+ err := cs .CoreV1 ().Services (ns ).Delete (context .TODO (), serviceName , metav1.DeleteOptions {})
3892
+ framework .ExpectNoError (err , "failed to delete service: %s in namespace: %s" , serviceName , ns )
3893
+ }()
3894
+
3895
+ err = e2enetwork .WaitForService (f .ClientSet , ns , serviceName , true , 5 * time .Second , e2eservice .TestTimeout )
3896
+ framework .ExpectNoError (err , fmt .Sprintf ("error while waiting for service:%s err: %v" , serviceName , err ))
3897
+
3898
+ ginkgo .By ("validating endpoints do not exist yet" )
3899
+ err = validateEndpointsPorts (cs , ns , serviceName , portsByPodName {})
3900
+ framework .ExpectNoError (err , "failed to validate endpoints for service %s in namespace: %s" , serviceName , ns )
3901
+
3902
+ ginkgo .By ("creating a pod for the service" )
3903
+ names := map [string ]bool {}
3904
+
3905
+ name1 := "pod1"
3906
+
3907
+ createPodOrFail (cs , ns , name1 , jig .Labels , []v1.ContainerPort {{ContainerPort : 5060 , Protocol : v1 .ProtocolSCTP }})
3908
+ names [name1 ] = true
3909
+ defer func () {
3910
+ for name := range names {
3911
+ err := cs .CoreV1 ().Pods (ns ).Delete (context .TODO (), name , metav1.DeleteOptions {})
3912
+ framework .ExpectNoError (err , "failed to delete pod: %s in namespace: %s" , name , ns )
3913
+ }
3914
+ }()
3915
+
3916
+ ginkgo .By ("validating endpoints exists" )
3917
+ err = validateEndpointsPorts (cs , ns , serviceName , portsByPodName {name1 : {5060 }})
3918
+ framework .ExpectNoError (err , "failed to validate endpoints for service %s in namespace: %s" , serviceName , ns )
3919
+
3920
+ ginkgo .By ("deleting the pod" )
3921
+ e2epod .DeletePodOrFail (cs , ns , name1 )
3922
+ delete (names , name1 )
3923
+ ginkgo .By ("validating endpoints do not exist anymore" )
3924
+ err = validateEndpointsPorts (cs , ns , serviceName , portsByPodName {})
3925
+ framework .ExpectNoError (err , "failed to validate endpoints for service %s in namespace: %s" , serviceName , ns )
3926
+
3927
+ ginkgo .By ("validating sctp module is still not loaded" )
3928
+ sctpLoadedAtEnd := CheckSCTPModuleLoadedOnNodes (f , nodes )
3929
+ if ! sctpLoadedAtStart && sctpLoadedAtEnd {
3930
+ framework .Failf ("The state of the sctp module has changed due to the test case" )
3931
+ }
3932
+ })
3933
+
3934
+ ginkgo .It ("should create a Pod with SCTP HostPort" , func () {
3935
+ ginkgo .By ("checking whether kubenet is used" )
3936
+ node , err := e2enode .GetRandomReadySchedulableNode (cs )
3937
+ framework .ExpectNoError (err )
3938
+ hostExec := utils .NewHostExec (f )
3939
+ defer hostExec .Cleanup ()
3940
+ cmd := "ps -C kubelet -o cmd= | grep kubenet"
3941
+ framework .Logf ("Executing cmd %q on node %v" , cmd , node .Name )
3942
+ err = hostExec .IssueCommand (cmd , node )
3943
+ if err != nil {
3944
+ e2eskipper .Skipf ("Interrogation of kubenet usage failed on node %s" , node .Name )
3945
+ }
3946
+ framework .Logf ("kubenet is in use" )
3947
+
3948
+ ginkgo .By ("getting the state of the sctp module on the selected node" )
3949
+ nodes := & v1.NodeList {}
3950
+ nodes .Items = append (nodes .Items , * node )
3951
+ sctpLoadedAtStart := CheckSCTPModuleLoadedOnNodes (f , nodes )
3952
+
3953
+ ginkgo .By ("creating a pod with hostport on the selected node" )
3954
+ podName := "hostport"
3955
+
3956
+ podSpec := & v1.Pod {
3957
+ ObjectMeta : metav1.ObjectMeta {
3958
+ Name : podName ,
3959
+ Namespace : f .Namespace .Name ,
3960
+ Labels : map [string ]string {"app" : "hostport-pod" },
3961
+ },
3962
+ Spec : v1.PodSpec {
3963
+ NodeName : node .Name ,
3964
+ Containers : []v1.Container {
3965
+ {
3966
+ Name : "hostport" ,
3967
+ Image : imageutils .GetE2EImage (imageutils .Agnhost ),
3968
+ Args : []string {"pause" },
3969
+ Ports : []v1.ContainerPort {
3970
+ {
3971
+ Protocol : v1 .ProtocolSCTP ,
3972
+ ContainerPort : 5060 ,
3973
+ HostPort : 5060 ,
3974
+ },
3975
+ },
3976
+ ImagePullPolicy : "IfNotPresent" ,
3977
+ },
3978
+ },
3979
+ },
3980
+ }
3981
+
3982
+ ginkgo .By (fmt .Sprintf ("Launching the pod on node %v" , node .Name ))
3983
+ f .PodClient ().CreateSync (podSpec )
3984
+ defer func () {
3985
+ err := cs .CoreV1 ().Pods (f .Namespace .Name ).Delete (context .TODO (), podName , metav1.DeleteOptions {})
3986
+ framework .ExpectNoError (err , "failed to delete pod: %s in namespace: %s" , podName , f .Namespace .Name )
3987
+ }()
3988
+
3989
+ ginkgo .By ("dumping iptables rules on the node" )
3990
+ cmd = "sudo iptables-save"
3991
+ framework .Logf ("Executing cmd %q on node %v" , cmd , node .Name )
3992
+ result , err := hostExec .IssueCommandWithResult (cmd , node )
3993
+ if err != nil {
3994
+ framework .Failf ("Interrogation of iptables rules failed on node %v" , node .Name )
3995
+ }
3996
+
3997
+ ginkgo .By ("checking that iptables contains the necessary iptables rules" )
3998
+ found := false
3999
+ for _ , line := range strings .Split (result , "\n " ) {
4000
+ if strings .Contains (line , "-p sctp" ) && strings .Contains (line , "--dport 5060" ) {
4001
+ found = true
4002
+ break
4003
+ }
4004
+ }
4005
+ if ! found {
4006
+ framework .Failf ("iptables rules are not set for a pod with sctp hostport" )
4007
+ }
4008
+ ginkgo .By ("validating sctp module is still not loaded" )
4009
+ sctpLoadedAtEnd := CheckSCTPModuleLoadedOnNodes (f , nodes )
4010
+ if ! sctpLoadedAtStart && sctpLoadedAtEnd {
4011
+ framework .Failf ("The state of the sctp module has changed due to the test case" )
4012
+ }
4013
+ })
4014
+ ginkgo .It ("should create a ClusterIP Service with SCTP ports" , func () {
4015
+ ginkgo .By ("checking that kube-proxy is in iptables mode" )
4016
+ if proxyMode , err := proxyMode (f ); err != nil {
4017
+ e2eskipper .Skipf ("Couldn't detect KubeProxy mode - skip, %v" , err )
4018
+ } else if proxyMode != "iptables" {
4019
+ e2eskipper .Skipf ("The test doesn't work if kube-proxy is not in iptables mode" )
4020
+ }
4021
+
4022
+ serviceName := "sctp-clusterip"
4023
+ ns := f .Namespace .Name
4024
+ jig := e2eservice .NewTestJig (cs , ns , serviceName )
4025
+
4026
+ ginkgo .By ("getting the state of the sctp module on nodes" )
4027
+ nodes , err := e2enode .GetReadySchedulableNodes (cs )
4028
+ framework .ExpectNoError (err )
4029
+ sctpLoadedAtStart := CheckSCTPModuleLoadedOnNodes (f , nodes )
4030
+
4031
+ ginkgo .By ("creating service " + serviceName + " in namespace " + ns )
4032
+ _ , err = jig .CreateSCTPServiceWithPort (func (svc * v1.Service ) {
4033
+ svc .Spec .Type = v1 .ServiceTypeClusterIP
4034
+ svc .Spec .Ports = []v1.ServicePort {{Protocol : v1 .ProtocolSCTP , Port : 5060 }}
4035
+ }, 5060 )
4036
+ framework .ExpectNoError (err )
4037
+ defer func () {
4038
+ err := cs .CoreV1 ().Services (ns ).Delete (context .TODO (), serviceName , metav1.DeleteOptions {})
4039
+ framework .ExpectNoError (err , "failed to delete service: %s in namespace: %s" , serviceName , ns )
4040
+ }()
4041
+
4042
+ err = e2enetwork .WaitForService (f .ClientSet , ns , serviceName , true , 5 * time .Second , e2eservice .TestTimeout )
4043
+ framework .ExpectNoError (err , fmt .Sprintf ("error while waiting for service:%s err: %v" , serviceName , err ))
4044
+
4045
+ ginkgo .By ("dumping iptables rules on a node" )
4046
+ hostExec := utils .NewHostExec (f )
4047
+ defer hostExec .Cleanup ()
4048
+ node , err := e2enode .GetRandomReadySchedulableNode (cs )
4049
+ framework .ExpectNoError (err )
4050
+ cmd := "sudo iptables-save"
4051
+ framework .Logf ("Executing cmd %q on node %v" , cmd , node .Name )
4052
+ result , err := hostExec .IssueCommandWithResult (cmd , node )
4053
+ if err != nil {
4054
+ framework .Failf ("Interrogation of iptables rules failed on node %v" , node .Name )
4055
+ }
4056
+
4057
+ ginkgo .By ("checking that iptables contains the necessary iptables rules" )
4058
+ kubeService := false
4059
+ for _ , line := range strings .Split (result , "\n " ) {
4060
+ if strings .Contains (line , "-A KUBE-SERVICES" ) && strings .Contains (line , "-p sctp" ) {
4061
+ kubeService = true
4062
+ break
4063
+ }
4064
+ }
4065
+ if ! kubeService {
4066
+ framework .Failf ("iptables rules are not set for a clusterip service with sctp ports" )
4067
+ }
4068
+ ginkgo .By ("validating sctp module is still not loaded" )
4069
+ sctpLoadedAtEnd := CheckSCTPModuleLoadedOnNodes (f , nodes )
4070
+ if ! sctpLoadedAtStart && sctpLoadedAtEnd {
4071
+ framework .Failf ("The state of the sctp module has changed due to the test case" )
4072
+ }
4073
+ })
4074
+ })
0 commit comments