Skip to content

Commit 4b2b122

Browse files
committed
OCPBUGS-62144: Restart pods when rendering egressIP settings
Signed-off-by: Raphael Rosa <raprosa@redhat.com>
1 parent f3e41c5 commit 4b2b122

5 files changed

Lines changed: 197 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ Other values are ignored. If you wish to use use a third-party network provider
146146

147147

148148
### Configuring OVNKubernetes
149-
OVNKubernetes supports the following configuration options, all of which are optional and once set at cluster creation, they can't be changed except for `gatewayConfig` and `IPsec` which can be changed at runtime:
149+
OVNKubernetes supports the following configuration options, all of which are optional and once set at cluster creation, they can't be changed except for `gatewayConfig`, `IPsec` and `reachabilityTotalTimeoutSeconds` which can be changed at runtime:
150150
* `MTU`: The MTU to use for the geneve overlay. The default is the MTU of the node that the cluster-network-operator is first run on, minus 100 bytes for geneve overhead. If the nodes in your cluster don't all have the same MTU then you may need to set this explicitly.
151151
* `genevePort`: The UDP port to use for the Geneve overlay. The default is 6081.
152152
* `hybridOverlayConfig`: hybrid linux/windows cluster (see below).

bindata/network/ovn-kubernetes/common/008-script-lib.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,13 @@ data:
571571

572572
# enable egress ip, egress firewall, egress qos, egress service
573573
egress_features_enable_flag="--enable-egress-ip=true --enable-egress-firewall=true --enable-egress-qos=true --enable-egress-service=true"
574+
575+
{{- if .ReachabilityTotalTimeoutSeconds }}
576+
if [[ "{{.ReachabilityTotalTimeoutSeconds}}" != "" ]]; then
577+
egress_features_enable_flag="$egress_features_enable_flag --egressip-reachability-total-timeout {{.ReachabilityTotalTimeoutSeconds}}"
578+
fi
579+
{{ end }}
580+
574581
init_ovnkube_controller="--init-ovnkube-controller ${K8S_NODE}"
575582
multi_external_gateway_enable_flag="--enable-multi-external-gateway=true"
576583
gateway_interface=br-ex

bindata/network/ovn-kubernetes/managed/ovnkube-control-plane.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ spec:
156156
fi
157157
done
158158
159+
{{- if .ReachabilityTotalTimeoutSeconds }}
160+
ovn_eip_reachability_timeout_opt=
161+
if [[ "{{.ReachabilityTotalTimeoutSeconds}}" != "" ]]; then
162+
ovn_eip_reachability_timeout_opt="--egressip-reachability-total-timeout {{.ReachabilityTotalTimeoutSeconds}}"
163+
fi
164+
{{ end }}
165+
159166
ovn_v4_join_subnet_opt=
160167
if [[ "{{.V4JoinSubnet}}" != "" ]]; then
161168
ovn_v4_join_subnet_opt="--gateway-v4-join-subnet {{.V4JoinSubnet}}"
@@ -249,6 +256,7 @@ spec:
249256
${evpn_enable_flag} \
250257
${preconfigured_udn_addresses_enable_flag} \
251258
--enable-egress-ip=true \
259+
${ovn_eip_reachability_timeout_opt} \
252260
--enable-egress-firewall=true \
253261
--enable-egress-qos=true \
254262
--enable-egress-service=true \

bindata/network/ovn-kubernetes/self-hosted/ovnkube-control-plane.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ spec:
102102
source "/env/_master"
103103
set +o allexport
104104
fi
105+
106+
{{- if .ReachabilityTotalTimeoutSeconds }}
107+
ovn_eip_reachability_timeout_opt=
108+
if [[ "{{.ReachabilityTotalTimeoutSeconds}}" != "" ]]; then
109+
ovn_eip_reachability_timeout_opt="--egressip-reachability-total-timeout {{.ReachabilityTotalTimeoutSeconds}}"
110+
fi
111+
{{ end }}
105112
106113
ovn_v4_join_subnet_opt=
107114
if [[ "{{.V4JoinSubnet}}" != "" ]]; then
@@ -203,6 +210,7 @@ spec:
203210
${evpn_enable_flag} \
204211
${preconfigured_udn_addresses_enable_flag} \
205212
--enable-egress-ip=true \
213+
${ovn_eip_reachability_timeout_opt} \
206214
--enable-egress-firewall=true \
207215
--enable-egress-qos=true \
208216
--enable-egress-service=true \

pkg/network/ovn_kubernetes_test.go

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3944,6 +3944,179 @@ func TestRenderOVNKubernetesEnablePersistentIPs(t *testing.T) {
39443944
g.Expect(objs).To(ContainElement(HaveKubernetesID("CustomResourceDefinition", "", "ipamclaims.k8s.cni.cncf.io")))
39453945
}
39463946

3947+
// TestRenderOVNKubernetesReachability tests egress IP reachability timeout rendering
3948+
func TestRenderOVNKubernetesReachability(t *testing.T) {
3949+
g := NewGomegaWithT(t)
3950+
3951+
testCases := []struct {
3952+
name string
3953+
reachabilityTimeout *uint32
3954+
expectKubernetesFeatureReachability bool
3955+
expectErr bool
3956+
}{
3957+
{
3958+
name: "No reachability timeout (nil)",
3959+
reachabilityTimeout: nil,
3960+
expectKubernetesFeatureReachability: false,
3961+
expectErr: false,
3962+
},
3963+
{
3964+
name: "Reachability timeout set to 0",
3965+
reachabilityTimeout: ptrToUint32(0),
3966+
expectKubernetesFeatureReachability: true,
3967+
expectErr: false,
3968+
},
3969+
{
3970+
name: "Reachability timeout changed to 10",
3971+
reachabilityTimeout: ptrToUint32(10),
3972+
expectKubernetesFeatureReachability: true,
3973+
expectErr: false,
3974+
},
3975+
{
3976+
name: "Reachability timeout unchanged to 10",
3977+
reachabilityTimeout: ptrToUint32(10),
3978+
expectKubernetesFeatureReachability: true,
3979+
expectErr: false,
3980+
},
3981+
{
3982+
name: "Reachability timeout changed to 5",
3983+
reachabilityTimeout: ptrToUint32(5),
3984+
expectKubernetesFeatureReachability: true,
3985+
expectErr: false,
3986+
},
3987+
{
3988+
name: "Reachability timeout disabled",
3989+
reachabilityTimeout: nil,
3990+
expectKubernetesFeatureReachability: false,
3991+
expectErr: false,
3992+
},
3993+
}
3994+
3995+
for _, tc := range testCases {
3996+
t.Run(tc.name, func(t *testing.T) {
3997+
crd := OVNKubernetesConfig.DeepCopy()
3998+
config := &crd.Spec
3999+
config.DefaultNetwork.OVNKubernetesConfig.EgressIPConfig.ReachabilityTotalTimeoutSeconds = tc.reachabilityTimeout
4000+
4001+
errs := validateOVNKubernetes(config)
4002+
g.Expect(errs).To(HaveLen(0))
4003+
fillDefaults(config, nil)
4004+
4005+
// at the same time we have an upgrade
4006+
t.Setenv("RELEASE_VERSION", "2.0.0")
4007+
4008+
bootstrapResult := fakeBootstrapResult()
4009+
bootstrapResult.OVN = bootstrap.OVNBootstrapResult{
4010+
ControlPlaneReplicaCount: 3,
4011+
OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{
4012+
DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST,
4013+
DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU,
4014+
SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC,
4015+
MgmtPortResourceName: "",
4016+
HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{
4017+
Enabled: false,
4018+
},
4019+
},
4020+
}
4021+
4022+
featureGatesCNO := getDefaultFeatureGates()
4023+
fakeClient := cnofake.NewFakeClient()
4024+
// Set is as Hypershift hosted control plane.
4025+
bootstrapResult.Infra = bootstrap.InfraStatus{}
4026+
bootstrapResult.Infra.HostedControlPlane = &hypershift.HostedControlPlane{}
4027+
objs, _, err := renderOVNKubernetes(config, bootstrapResult, manifestDirOvn, fakeClient, featureGatesCNO)
4028+
if tc.expectErr {
4029+
g.Expect(err).To(HaveOccurred())
4030+
return
4031+
}
4032+
g.Expect(err).NotTo(HaveOccurred())
4033+
4034+
// Find the ovnkube-config ConfigMap and check the template data
4035+
var configMap *uns.Unstructured
4036+
for _, obj := range objs {
4037+
if obj.GetKind() == "ConfigMap" && obj.GetName() == "ovnkube-config" {
4038+
configMap = obj
4039+
break
4040+
}
4041+
}
4042+
g.Expect(configMap).NotTo(BeNil(), "ovnkube-config ConfigMap should exist")
4043+
4044+
// Check the transport value in the rendered ConfigMap
4045+
configMapData, found, err := uns.NestedStringMap(configMap.Object, "data")
4046+
g.Expect(err).NotTo(HaveOccurred())
4047+
g.Expect(found).To(BeTrue(), "ConfigMap should have data field")
4048+
ovnkubeConf := configMapData["ovnkube.conf"]
4049+
4050+
var scriptCP string
4051+
var scriptNode string
4052+
for _, obj := range objs {
4053+
// Gets script that starts ovnkube-control-plane pod, ovnkube-cluster-manager container
4054+
if obj.GetKind() == "Deployment" && obj.GetName() == "ovnkube-control-plane" && obj.GetNamespace() == "openshift-ovn-kubernetes" {
4055+
containers, found, err := uns.NestedSlice(obj.Object, "spec", "template", "spec", "containers")
4056+
g.Expect(err).NotTo(HaveOccurred())
4057+
g.Expect(found).To(BeTrue())
4058+
for _, c := range containers {
4059+
cm := c.(map[string]interface{})
4060+
if name, ok := cm["name"]; ok && (name == "ovnkube-cluster-manager" || name == "ovnkube-control-plane") {
4061+
command, found, err := uns.NestedSlice(cm, "command")
4062+
g.Expect(err).NotTo(HaveOccurred())
4063+
g.Expect(found).To(BeTrue())
4064+
g.Expect(len(command)).To(BeNumerically(">", 2))
4065+
scriptCP = command[2].(string)
4066+
break
4067+
}
4068+
}
4069+
}
4070+
4071+
// Gets script that starts ovnkube-node pod, ovnkube-controller container
4072+
if obj.GetKind() == "ConfigMap" && obj.GetName() == "ovnkube-script-lib" {
4073+
configMap = obj
4074+
configMapData, found, err := uns.NestedStringMap(configMap.Object, "data")
4075+
g.Expect(err).NotTo(HaveOccurred())
4076+
g.Expect(found).To(BeTrue(), "ovnkube-script-lib ConfigMap should have data field")
4077+
scriptNode = configMapData["ovnkube-lib.sh"]
4078+
}
4079+
}
4080+
g.Expect(scriptCP).NotTo(BeEmpty())
4081+
g.Expect(scriptNode).NotTo(BeEmpty())
4082+
4083+
if tc.expectKubernetesFeatureReachability {
4084+
g.Expect(ovnkubeConf).To(ContainSubstring("[ovnkubernetesfeature]"),
4085+
"ConfigMap should contain [ovnkubernetesfeature] section when enabled")
4086+
g.Expect(tc.reachabilityTimeout).NotTo(BeNil())
4087+
g.Expect(ovnkubeConf).To(
4088+
ContainSubstring(fmt.Sprintf("egressip-reachability-total-timeout=%d", *tc.reachabilityTimeout)),
4089+
"ConfigMap should contain the configured reachability timeout value",
4090+
)
4091+
g.Expect(ovnkubeConf).To(ContainSubstring("egressip-reachability-total-timeout="),
4092+
"ConfigMap should contain egressip-reachability-total-timeout=")
4093+
4094+
g.Expect(scriptCP).To(
4095+
ContainSubstring(fmt.Sprintf("--egressip-reachability-total-timeout %d", *tc.reachabilityTimeout)),
4096+
"ovnkube-control-plane pod template should contain the configured reachability timeout value",
4097+
)
4098+
g.Expect(scriptNode).To(
4099+
ContainSubstring(fmt.Sprintf("--egressip-reachability-total-timeout %d", *tc.reachabilityTimeout)),
4100+
"ovnkube-node pod template should contain the configured reachability timeout value",
4101+
)
4102+
4103+
} else {
4104+
g.Expect(ovnkubeConf).NotTo(ContainSubstring("egressip-reachability-total-timeout="),
4105+
"ConfigMap should not contain egressip-reachability-total-timeout= section when disabled")
4106+
4107+
g.Expect(scriptCP).NotTo(
4108+
ContainSubstring("--egressip-reachability-total-timeout"),
4109+
"ovnkube-control-plane pod template should not contain the configured reachability timeout value",
4110+
)
4111+
g.Expect(scriptNode).NotTo(
4112+
ContainSubstring("--egressip-reachability-total-timeout"),
4113+
"ovnkube-node pod template should not contain the configured reachability timeout value",
4114+
)
4115+
}
4116+
})
4117+
}
4118+
}
4119+
39474120
type fakeClientReader struct {
39484121
configMap *v1.ConfigMap
39494122
}

0 commit comments

Comments
 (0)