@@ -18,16 +18,15 @@ package network
18
18
19
19
import (
20
20
"context"
21
+ "net/netip"
21
22
22
23
"github.com/onsi/ginkgo/v2"
23
24
v1 "k8s.io/api/core/v1"
24
- networkingv1beta1 "k8s.io/api/networking/v1beta1 "
25
+ networkingv1 "k8s.io/api/networking/v1 "
25
26
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26
27
"k8s.io/apimachinery/pkg/util/intstr"
27
28
"k8s.io/apimachinery/pkg/util/wait"
28
29
clientset "k8s.io/client-go/kubernetes"
29
- "k8s.io/kubernetes/pkg/features"
30
- "k8s.io/kubernetes/test/e2e/feature"
31
30
"k8s.io/kubernetes/test/e2e/framework"
32
31
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
33
32
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
@@ -37,7 +36,7 @@ import (
37
36
admissionapi "k8s.io/pod-security-admission/api"
38
37
)
39
38
40
- var _ = common .SIGDescribe (feature . ServiceCIDRs , framework . WithFeatureGate ( features . MultiCIDRServiceAllocator ) , func () {
39
+ var _ = common .SIGDescribe ("Service CIDRs" , func () {
41
40
42
41
fr := framework .NewDefaultFramework ("servicecidrs" )
43
42
fr .NamespacePodSecurityEnforceLevel = admissionapi .LevelPrivileged
@@ -62,19 +61,30 @@ var _ = common.SIGDescribe(feature.ServiceCIDRs, framework.WithFeatureGate(featu
62
61
})
63
62
64
63
ginkgo .It ("should create Services and serve on different Service CIDRs" , func (ctx context.Context ) {
64
+ // use a ServiceCIDR that does not have risk to overlap with other ranges
65
+ serviceCIDR := netip .MustParsePrefix ("203.0.113.0/24" ) // RFC 5737 (TEST-NET-3) is provided for use in documentation.
66
+ // use a random IP inside the range
67
+ serviceIP := netip .MustParseAddr ("203.0.113.10" )
68
+ if framework .TestContext .ClusterIsIPv6 () {
69
+ serviceCIDR = netip .MustParsePrefix ("2001:db8:cb00::/64" ) // RFC 3849 IPv6 Address Prefix Reserved for Documentation.
70
+ serviceIP = netip .MustParseAddr ("2001:db8:cb00::a" )
71
+ }
72
+
65
73
// create a new service CIDR
66
- svcCIDR := & networkingv1beta1 .ServiceCIDR {
74
+ svcCIDR := & networkingv1 .ServiceCIDR {
67
75
ObjectMeta : metav1.ObjectMeta {
68
76
Name : "test-svc-cidr" ,
69
77
},
70
- Spec : networkingv1beta1 .ServiceCIDRSpec {
71
- CIDRs : []string {"10.196.196.0/24" },
78
+ Spec : networkingv1 .ServiceCIDRSpec {
79
+ CIDRs : []string {serviceCIDR . String () },
72
80
},
73
81
}
74
- _ , err := cs .NetworkingV1beta1 ().ServiceCIDRs ().Create (context .TODO (), svcCIDR , metav1.CreateOptions {})
82
+ _ , err := cs .NetworkingV1 ().ServiceCIDRs ().Create (context .TODO (), svcCIDR , metav1.CreateOptions {})
75
83
framework .ExpectNoError (err , "error creating ServiceCIDR" )
84
+ ginkgo .DeferCleanup (cs .NetworkingV1 ().ServiceCIDRs ().Delete , svcCIDR .Name , metav1.DeleteOptions {})
85
+
76
86
if pollErr := wait .PollUntilContextTimeout (ctx , framework .Poll , e2eservice .RespondingTimeout , false , func (ctx context.Context ) (bool , error ) {
77
- svcCIDR , err := cs .NetworkingV1beta1 ().ServiceCIDRs ().Get (ctx , svcCIDR .Name , metav1.GetOptions {})
87
+ svcCIDR , err := cs .NetworkingV1 ().ServiceCIDRs ().Get (ctx , svcCIDR .Name , metav1.GetOptions {})
78
88
if err != nil {
79
89
return false , nil
80
90
}
@@ -87,14 +97,30 @@ var _ = common.SIGDescribe(feature.ServiceCIDRs, framework.WithFeatureGate(featu
87
97
jig := e2eservice .NewTestJig (cs , ns , serviceName )
88
98
89
99
ginkgo .By ("creating service " + serviceName + " with type=NodePort in namespace " + ns )
90
- nodePortService , err := jig .CreateTCPService (ctx , func (svc * v1.Service ) {
91
- svc .Spec .ClusterIP = "10.196.196.77"
92
- svc .Spec .Type = v1 .ServiceTypeNodePort
93
- svc .Spec .Ports = []v1.ServicePort {
94
- {Port : 80 , Name : "http" , Protocol : v1 .ProtocolTCP , TargetPort : intstr .FromInt (9376 )},
100
+ // Because this test run in parallel with other test there is a chance that the ClusterIP
101
+ // gets allocated, we also need to ensure the ClusterIP belongs to the new Service range
102
+ // so we need to explicitly set it. Try several times before giving up.
103
+ var nodePortService * v1.Service
104
+ for i := 0 ; i < 5 ; i ++ {
105
+ nodePortService , err = jig .CreateTCPService (ctx , func (svc * v1.Service ) {
106
+ svc .Spec .ClusterIP = serviceIP .String ()
107
+ svc .Spec .Type = v1 .ServiceTypeNodePort
108
+ svc .Spec .Ports = []v1.ServicePort {
109
+ {Port : 80 , Name : "http" , Protocol : v1 .ProtocolTCP , TargetPort : intstr .FromInt (9376 )},
110
+ }
111
+ })
112
+ if err != nil {
113
+ serviceIP = serviceIP .Next ()
114
+ } else {
115
+ break
95
116
}
117
+ }
118
+ framework .ExpectNoError (err , "unable to allocate Service on new ServiceCIDR" )
119
+
120
+ ginkgo .DeferCleanup (func (ctx context.Context ) {
121
+ err := cs .CoreV1 ().Services (ns ).Delete (ctx , serviceName , metav1.DeleteOptions {})
122
+ framework .ExpectNoError (err , "failed to delete service: %s in namespace: %s" , serviceName , ns )
96
123
})
97
- framework .ExpectNoError (err )
98
124
err = jig .CreateServicePods (ctx , 2 )
99
125
framework .ExpectNoError (err )
100
126
execPod := e2epod .CreateExecPodOrFail (ctx , cs , ns , "execpod" , nil )
@@ -104,13 +130,13 @@ var _ = common.SIGDescribe(feature.ServiceCIDRs, framework.WithFeatureGate(featu
104
130
105
131
})
106
132
107
- func isReady (serviceCIDR * networkingv1beta1 .ServiceCIDR ) bool {
133
+ func isReady (serviceCIDR * networkingv1 .ServiceCIDR ) bool {
108
134
if serviceCIDR == nil {
109
135
return false
110
136
}
111
137
112
138
for _ , condition := range serviceCIDR .Status .Conditions {
113
- if condition .Type == string (networkingv1beta1 .ServiceCIDRConditionReady ) {
139
+ if condition .Type == string (networkingv1 .ServiceCIDRConditionReady ) {
114
140
return condition .Status == metav1 .ConditionStatus (metav1 .ConditionTrue )
115
141
}
116
142
}
0 commit comments