@@ -2,15 +2,17 @@ package pod
2
2
3
3
import (
4
4
"fmt"
5
- "time"
5
+ "math/rand"
6
+ "net"
7
+ "strconv"
8
+ "strings"
6
9
7
10
"github.com/onsi/ginkgo/v2"
8
11
corev1 "k8s.io/api/core/v1"
9
12
"k8s.io/apimachinery/pkg/util/intstr"
10
13
clientset "k8s.io/client-go/kubernetes"
11
14
12
15
apiv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1"
13
- "github.com/kubeovn/kube-ovn/pkg/daemon"
14
16
"github.com/kubeovn/kube-ovn/pkg/util"
15
17
"github.com/kubeovn/kube-ovn/test/e2e/framework"
16
18
"github.com/kubeovn/kube-ovn/test/e2e/framework/iptables"
@@ -21,6 +23,7 @@ var _ = framework.SerialDescribe("[group:pod]", func() {
21
23
22
24
var cs clientset.Interface
23
25
var podClient * framework.PodClient
26
+ var eventClient * framework.EventClient
24
27
var subnetClient * framework.SubnetClient
25
28
var vpcClient * framework.VpcClient
26
29
var namespaceName , subnetName , podName , vpcName string
@@ -31,6 +34,7 @@ var _ = framework.SerialDescribe("[group:pod]", func() {
31
34
ginkgo .BeforeEach (func () {
32
35
cs = f .ClientSet
33
36
podClient = f .PodClient ()
37
+ eventClient = f .EventClient ()
34
38
subnetClient = f .SubnetClient ()
35
39
namespaceName = f .Namespace .Name
36
40
subnetName = "subnet-" + framework .RandomSuffix ()
@@ -64,7 +68,7 @@ var _ = framework.SerialDescribe("[group:pod]", func() {
64
68
}
65
69
})
66
70
67
- framework .ConformanceIt ("should support http and tcp liveness probe and readiness probe in custom vpc pod " , func () {
71
+ framework .ConformanceIt ("should support http and tcp readiness probe in custom vpc pod" , func () {
68
72
f .SkipVersionPriorTo (1 , 12 , "This feature was introduced in v1.12" )
69
73
daemonSetClient := f .DaemonSetClientNS (framework .KubeOvnNamespace )
70
74
originDs := daemonSetClient .Get ("kube-ovn-cni" )
@@ -94,108 +98,102 @@ var _ = framework.SerialDescribe("[group:pod]", func() {
94
98
subnet := framework .MakeSubnet (custVPCSubnetName , "" , cidr , "" , vpcName , "" , nil , nil , nil )
95
99
_ = subnetClient .CreateSync (subnet )
96
100
97
- ginkgo .By ("Creating pod with HTTP liveness and readiness probe that port is accessible " + podName )
98
- pod := framework .MakePod (namespaceName , podName , nil , map [string ]string {util .LogicalSwitchAnnotation : custVPCSubnetName }, framework .NginxImage , nil , nil )
99
-
101
+ ginkgo .By ("Creating pod with HTTP readiness probe that port is accessible " + podName )
102
+ port := 8000 + rand .Intn (1000 )
103
+ portStr := strconv .Itoa (port )
104
+ args := []string {"netexec" , "--http-port" , portStr }
105
+ pod := framework .MakePod (namespaceName , podName , nil , map [string ]string {util .LogicalSwitchAnnotation : custVPCSubnetName }, framework .AgnhostImage , nil , args )
100
106
pod .Spec .Containers [0 ].ReadinessProbe = & corev1.Probe {
101
107
ProbeHandler : corev1.ProbeHandler {
102
108
HTTPGet : & corev1.HTTPGetAction {
103
- Port : intstr .FromInt (80 ),
109
+ Port : intstr .FromInt (port ),
104
110
},
105
111
},
106
112
}
107
- pod .Spec .Containers [0 ].LivenessProbe = & corev1.Probe {
108
- ProbeHandler : corev1.ProbeHandler {
109
- HTTPGet : & corev1.HTTPGetAction {
110
- Port : intstr .FromInt (80 ),
111
- },
112
- },
113
- }
114
-
115
113
pod = podClient .CreateSync (pod )
116
- framework .ExpectEqual (pod .Status .ContainerStatuses [0 ].Ready , true )
117
- checkTProxyRules (f , pod , 80 , true )
114
+ checkTProxyRules (f , pod , port , true )
115
+
116
+ ginkgo .By ("Deleting pod " + podName )
118
117
podClient .DeleteSync (podName )
119
118
120
- ginkgo .By ("Creating pod with HTTP liveness and readiness probe that port is not accessible " + podName )
121
- pod = framework .MakePod (namespaceName , podName , nil , map [string ]string {util .LogicalSwitchAnnotation : custVPCSubnetName }, framework .NginxImage , nil , nil )
119
+ ginkgo .By ("Creating pod with HTTP readiness probe that port is not accessible " + podName )
120
+ pod = framework .MakePod (namespaceName , podName , nil , map [string ]string {util .LogicalSwitchAnnotation : custVPCSubnetName }, framework .AgnhostImage , nil , args )
122
121
pod .Spec .Containers [0 ].ReadinessProbe = & corev1.Probe {
123
122
ProbeHandler : corev1.ProbeHandler {
124
123
HTTPGet : & corev1.HTTPGetAction {
125
- Port : intstr .FromInt (81 ),
124
+ Port : intstr .FromInt (port + 1 ),
126
125
},
127
126
},
128
127
}
129
- pod .Spec .Containers [0 ].LivenessProbe = & corev1.Probe {
130
- ProbeHandler : corev1.ProbeHandler {
131
- HTTPGet : & corev1.HTTPGetAction {
132
- Port : intstr .FromInt (81 ),
133
- },
134
- },
128
+ _ = podClient .Create (pod )
129
+
130
+ ginkgo .By ("Waiting for pod readiness probe failure" )
131
+ events := eventClient .WaitToHaveEvent ("Pod" , podName , "Warning" , "Unhealthy" , "kubelet" , "" )
132
+ var found bool
133
+ for _ , event := range events {
134
+ if strings .Contains (event .Message , "Readiness probe failed" ) {
135
+ found = true
136
+ framework .Logf ("Found pod event: %s" , event .Message )
137
+ break
138
+ }
135
139
}
140
+ framework .ExpectTrue (found , "Pod readiness probe is expected to fail" )
136
141
137
- _ = podClient .Create (pod )
138
- time .Sleep (5 * time .Second )
139
142
pod = podClient .GetPod (podName )
143
+ checkTProxyRules (f , pod , port + 1 , true )
140
144
141
- framework .ExpectEqual (pod .Status .ContainerStatuses [0 ].Ready , false )
142
- checkTProxyRules (f , pod , 81 , true )
145
+ ginkgo .By ("Deleting pod " + podName )
143
146
podClient .DeleteSync (podName )
144
147
145
- ginkgo .By ("Creating pod with TCP probe liveness and readiness probe that port is accessible " + podName )
146
- pod = framework .MakePod (namespaceName , podName , nil , map [string ]string {util .LogicalSwitchAnnotation : custVPCSubnetName }, framework .NginxImage , nil , nil )
148
+ ginkgo .By ("Creating pod with TCP readiness probe that port is accessible " + podName )
149
+ pod = framework .MakePod (namespaceName , podName , nil , map [string ]string {util .LogicalSwitchAnnotation : custVPCSubnetName }, framework .AgnhostImage , nil , args )
147
150
pod .Spec .Containers [0 ].ReadinessProbe = & corev1.Probe {
148
151
ProbeHandler : corev1.ProbeHandler {
149
152
TCPSocket : & corev1.TCPSocketAction {
150
- Port : intstr .FromInt (80 ),
151
- },
152
- },
153
- }
154
- pod .Spec .Containers [0 ].LivenessProbe = & corev1.Probe {
155
- ProbeHandler : corev1.ProbeHandler {
156
- TCPSocket : & corev1.TCPSocketAction {
157
- Port : intstr .FromInt (80 ),
153
+ Port : intstr .FromInt (port ),
158
154
},
159
155
},
160
156
}
161
-
162
157
pod = podClient .CreateSync (pod )
163
- framework . ExpectEqual ( pod . Status . ContainerStatuses [ 0 ]. Ready , true )
158
+ checkTProxyRules ( f , pod , port , true )
164
159
165
- checkTProxyRules ( f , pod , 80 , true )
160
+ ginkgo . By ( "Deleting pod " + podName )
166
161
podClient .DeleteSync (podName )
167
162
168
- ginkgo .By ("Creating pod with TCP probe liveness and readiness probe that port is not accessible " + podName )
169
- pod = framework .MakePod (namespaceName , podName , nil , map [string ]string {util .LogicalSwitchAnnotation : custVPCSubnetName }, framework .NginxImage , nil , nil )
163
+ ginkgo .By ("Creating pod with TCP readiness probe that port is not accessible " + podName )
164
+ pod = framework .MakePod (namespaceName , podName , nil , map [string ]string {util .LogicalSwitchAnnotation : custVPCSubnetName }, framework .AgnhostImage , nil , args )
170
165
pod .Spec .Containers [0 ].ReadinessProbe = & corev1.Probe {
171
166
ProbeHandler : corev1.ProbeHandler {
172
167
TCPSocket : & corev1.TCPSocketAction {
173
- Port : intstr .FromInt (81 ),
168
+ Port : intstr .FromInt (port - 1 ),
174
169
},
175
170
},
176
171
}
177
- pod .Spec .Containers [0 ].LivenessProbe = & corev1.Probe {
178
- ProbeHandler : corev1.ProbeHandler {
179
- TCPSocket : & corev1.TCPSocketAction {
180
- Port : intstr .FromInt (81 ),
181
- },
182
- },
183
- }
184
-
185
172
_ = podClient .Create (pod )
186
- time .Sleep (5 * time .Second )
173
+ podClient .WaitForRunning (podName )
174
+
175
+ ginkgo .By ("Waiting for pod readiness probe failure" )
176
+ events = eventClient .WaitToHaveEvent ("Pod" , podName , "Warning" , "Unhealthy" , "kubelet" , "" )
177
+ found = false
178
+ for _ , event := range events {
179
+ if strings .Contains (event .Message , "Readiness probe failed" ) {
180
+ found = true
181
+ framework .Logf ("Found pod event: %s" , event .Message )
182
+ break
183
+ }
184
+ }
185
+ framework .ExpectTrue (found , "Pod readiness probe is expected to fail" )
187
186
188
187
pod = podClient .GetPod (podName )
189
- framework .ExpectEqual (pod .Status .ContainerStatuses [0 ].Ready , false )
190
- checkTProxyRules (f , pod , 81 , false )
188
+ checkTProxyRules (f , pod , port - 1 , false )
191
189
})
192
190
})
193
191
194
192
func checkTProxyRules (f * framework.Framework , pod * corev1.Pod , probePort int , exist bool ) {
195
193
196
194
nodeName := pod .Spec .NodeName
197
- tProxyOutputMarkMask := fmt .Sprintf ("%#x/%#x" , daemon .TProxyOutputMark , daemon .TProxyOutputMask )
198
- tProxyPreRoutingMarkMask := fmt .Sprintf ("%#x/%#x" , daemon .TProxyPreroutingMark , daemon .TProxyPreroutingMask )
195
+ tProxyOutputMarkMask := fmt .Sprintf ("%#x/%#x" , util .TProxyOutputMark , util .TProxyOutputMask )
196
+ tProxyPreRoutingMarkMask := fmt .Sprintf ("%#x/%#x" , util .TProxyPreroutingMark , util .TProxyPreroutingMask )
199
197
200
198
isZeroIP := false
201
199
if len (pod .Status .PodIPs ) == 2 {
@@ -207,20 +205,20 @@ func checkTProxyRules(f *framework.Framework, pod *corev1.Pod, probePort int, ex
207
205
expectedRules := []string {
208
206
fmt .Sprintf (`-A OVN-OUTPUT -d %s/32 -p tcp -m tcp --dport %d -j MARK --set-xmark %s` , podIP .IP , probePort , tProxyOutputMarkMask ),
209
207
}
210
- iptables .CheckIptablesRulesOnNode (f , nodeName , daemon . MANGLE , daemon .OvnOutput , apiv1 .ProtocolIPv4 , expectedRules , exist )
208
+ iptables .CheckIptablesRulesOnNode (f , nodeName , util . Mangle , util .OvnOutput , apiv1 .ProtocolIPv4 , expectedRules , exist )
211
209
hostIP := pod .Status .HostIP
212
210
if isZeroIP {
213
- hostIP = "0.0.0.0"
211
+ hostIP = net . IPv4zero . String ()
214
212
}
215
213
expectedRules = []string {
216
214
fmt .Sprintf (`-A OVN-PREROUTING -d %s/32 -p tcp -m tcp --dport %d -j TPROXY --on-port %d --on-ip %s --tproxy-mark %s` , podIP .IP , probePort , util .TProxyListenPort , hostIP , tProxyPreRoutingMarkMask ),
217
215
}
218
- iptables .CheckIptablesRulesOnNode (f , nodeName , daemon . MANGLE , daemon .OvnPrerouting , apiv1 .ProtocolIPv4 , expectedRules , exist )
216
+ iptables .CheckIptablesRulesOnNode (f , nodeName , util . Mangle , util .OvnPrerouting , apiv1 .ProtocolIPv4 , expectedRules , exist )
219
217
} else if util .CheckProtocol (podIP .IP ) == apiv1 .ProtocolIPv6 {
220
218
expectedRules := []string {
221
219
fmt .Sprintf (`-A OVN-OUTPUT -d %s/128 -p tcp -m tcp --dport %d -j MARK --set-xmark %s` , podIP .IP , probePort , tProxyOutputMarkMask ),
222
220
}
223
- iptables .CheckIptablesRulesOnNode (f , nodeName , daemon . MANGLE , daemon .OvnOutput , apiv1 .ProtocolIPv6 , expectedRules , exist )
221
+ iptables .CheckIptablesRulesOnNode (f , nodeName , util . Mangle , util .OvnOutput , apiv1 .ProtocolIPv6 , expectedRules , exist )
224
222
225
223
hostIP := pod .Status .HostIP
226
224
if isZeroIP {
@@ -229,7 +227,7 @@ func checkTProxyRules(f *framework.Framework, pod *corev1.Pod, probePort int, ex
229
227
expectedRules = []string {
230
228
fmt .Sprintf (`-A OVN-PREROUTING -d %s/128 -p tcp -m tcp --dport %d -j TPROXY --on-port %d --on-ip %s --tproxy-mark %s` , podIP .IP , probePort , util .TProxyListenPort , hostIP , tProxyPreRoutingMarkMask ),
231
229
}
232
- iptables .CheckIptablesRulesOnNode (f , nodeName , daemon . MANGLE , daemon .OvnPrerouting , apiv1 .ProtocolIPv6 , expectedRules , exist )
230
+ iptables .CheckIptablesRulesOnNode (f , nodeName , util . Mangle , util .OvnPrerouting , apiv1 .ProtocolIPv6 , expectedRules , exist )
233
231
}
234
232
}
235
233
}
0 commit comments