Skip to content

Commit

Permalink
Add option to disable udn-host-isolation.
Browse files Browse the repository at this point in the history
UDN host isolation requires a kernel fix. Turn it off by default in
ovnkube.sh (aka in our kind cluster). As soon as the fix becomes
available for github runners (and dev environments), this flag will be
removed from ovnkube.sh (and potentially from the code).
This flag only takes effect when network segmentation is enabled.

Add DISABLE_UDN_HOST_ISOLATION env variable to test workflow, that is
set to true.
Skip host isolation tests based on the value.

Signed-off-by: Nadia Pinaeva <n.m.pinaeva@gmail.com>
  • Loading branch information
npinaeva committed Oct 23, 2024
1 parent a3f6743 commit 71ad044
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 56 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ jobs:
KIND_IPV6_SUPPORT: "${{ matrix.ipfamily == 'IPv6' || matrix.ipfamily == 'dualstack' }}"
ENABLE_MULTI_NET: "${{ matrix.target == 'multi-homing' || matrix.target == 'kv-live-migration' || matrix.target == 'network-segmentation' || matrix.target == 'tools' || matrix.target == 'multi-homing-helm' }}"
ENABLE_NETWORK_SEGMENTATION: "${{ matrix.target == 'network-segmentation' || matrix.target == 'tools' || matrix.target == 'kv-live-migration'}}"
DISABLE_UDN_HOST_ISOLATION: "true"
KIND_INSTALL_KUBEVIRT: "${{ matrix.target == 'kv-live-migration' }}"
OVN_COMPACT_MODE: "${{ matrix.target == 'compact-mode' }}"
OVN_DUMMY_GATEWAY_BRIDGE: "${{ matrix.target == 'compact-mode' }}"
Expand Down
1 change: 1 addition & 0 deletions dist/images/ovnkube.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1638,6 +1638,7 @@ ovnkube-controller() {
--metrics-bind-address ${ovnkube_master_metrics_bind_address} \
--metrics-enable-pprof \
--pidfile ${OVN_RUNDIR}/ovnkube-controller.pid \
--disable-udn-host-isolation \
--zone ${ovn_zone} &

echo "=============== ovnkube-controller ========== running"
Expand Down
19 changes: 11 additions & 8 deletions go-controller/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,14 +417,17 @@ type OVNKubernetesFeatureConfig struct {
EgressIPNodeHealthCheckPort int `gcfg:"egressip-node-healthcheck-port"`
EnableMultiNetwork bool `gcfg:"enable-multi-network"`
EnableNetworkSegmentation bool `gcfg:"enable-network-segmentation"`
EnableMultiNetworkPolicy bool `gcfg:"enable-multi-networkpolicy"`
EnableStatelessNetPol bool `gcfg:"enable-stateless-netpol"`
EnableInterconnect bool `gcfg:"enable-interconnect"`
EnableMultiExternalGateway bool `gcfg:"enable-multi-external-gateway"`
EnablePersistentIPs bool `gcfg:"enable-persistent-ips"`
EnableDNSNameResolver bool `gcfg:"enable-dns-name-resolver"`
EnableServiceTemplateSupport bool `gcfg:"enable-svc-template-support"`
EnableObservability bool `gcfg:"enable-observability"`
// This feature requires a kernel fix https://github.com/torvalds/linux/commit/7f3287db654395f9c5ddd246325ff7889f550286
// to work on a kind cluster. Flag allows to disable it for current CI, will be turned on when github runners have this fix.
DisableUDNHostIsolation bool `gcfg:"disable-udn-host-isolation"`
EnableMultiNetworkPolicy bool `gcfg:"enable-multi-networkpolicy"`
EnableStatelessNetPol bool `gcfg:"enable-stateless-netpol"`
EnableInterconnect bool `gcfg:"enable-interconnect"`
EnableMultiExternalGateway bool `gcfg:"enable-multi-external-gateway"`
EnablePersistentIPs bool `gcfg:"enable-persistent-ips"`
EnableDNSNameResolver bool `gcfg:"enable-dns-name-resolver"`
EnableServiceTemplateSupport bool `gcfg:"enable-svc-template-support"`
EnableObservability bool `gcfg:"enable-observability"`
}

// GatewayMode holds the node gateway mode
Expand Down
2 changes: 1 addition & 1 deletion go-controller/pkg/node/default_node_network_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func newDefaultNodeNetworkController(cnnci *CommonNodeNetworkControllerInfo, sto
},
routeManager: routeManager,
}
if util.IsNetworkSegmentationSupportEnabled() {
if util.IsNetworkSegmentationSupportEnabled() && !config.OVNKubernetesFeature.DisableUDNHostIsolation {
c.udnHostIsolationManager = NewUDNHostIsolationManager(config.IPv4Mode, config.IPv6Mode,
cnnci.watchFactory.PodCoreInformer(), nadController)
}
Expand Down
101 changes: 54 additions & 47 deletions test/e2e/network_segmentation.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,48 +340,51 @@ var _ = Describe("Network Segmentation", func() {
}, 10*time.Second, 1*time.Second).Should(BeTrue())
Expect(udnPod.Status.ContainerStatuses[0].RestartCount).To(Equal(int32(0)))

By("checking default network hostNetwork pod and non-kubelet host process can't reach the UDN pod")
hostNetPod, err := createPod(f, "host-net-pod", udnPodConfig.nodeSelector[nodeHostnameKey],
defaultNetNamespace, []string{}, nil, func(pod *v1.Pod) {
pod.Spec.HostNetwork = true
})
Expect(err).NotTo(HaveOccurred())

// positive check for reachable default network pod
for _, destIP := range []string{defaultIPv4, defaultIPv6} {
if destIP == "" {
continue
}
By("checking the default network hostNetwork can reach default pod on IP " + destIP)
Eventually(func() bool {
return connectToServer(podConfiguration{namespace: hostNetPod.Namespace, name: hostNetPod.Name}, destIP, defaultPort) == nil
}).Should(BeTrue())
By("checking the non-kubelet host process can reach default pod on IP " + destIP)
Eventually(func() bool {
_, err = runCommand(containerRuntime, "exec", workerOneNodeName,
"curl", "--connect-timeout", "2",
net.JoinHostPort(destIP, fmt.Sprintf("%d", defaultPort)))
return err == nil
}).Should(BeTrue())
}
// negative check for UDN pod
for _, destIP := range []string{udnIPv4, udnIPv6} {
if destIP == "" {
continue
}
if !isUDNHostIsolationDisabled() {
By("checking default network hostNetwork pod and non-kubelet host process can't reach the UDN pod")
hostNetPod, err := createPod(f, "host-net-pod", udnPodConfig.nodeSelector[nodeHostnameKey],
defaultNetNamespace, []string{}, nil, func(pod *v1.Pod) {
pod.Spec.HostNetwork = true
})
Expect(err).NotTo(HaveOccurred())

By("checking the default network hostNetwork pod can't reach UDN pod on IP " + destIP)
Consistently(func() bool {
return connectToServer(podConfiguration{namespace: hostNetPod.Namespace, name: hostNetPod.Name}, destIP, port) != nil
}, 5*time.Second).Should(BeTrue())
// positive check for reachable default network pod
for _, destIP := range []string{defaultIPv4, defaultIPv6} {
if destIP == "" {
continue
}
By("checking the default network hostNetwork can reach default pod on IP " + destIP)
Eventually(func() bool {
return connectToServer(podConfiguration{namespace: hostNetPod.Namespace, name: hostNetPod.Name}, destIP, defaultPort) == nil
}).Should(BeTrue())
By("checking the non-kubelet host process can reach default pod on IP " + destIP)
Eventually(func() bool {
_, err = runCommand(containerRuntime, "exec", workerOneNodeName,
"curl", "--connect-timeout", "2",
net.JoinHostPort(destIP, fmt.Sprintf("%d", defaultPort)))
return err == nil
}).Should(BeTrue())
}
// negative check for UDN pod
for _, destIP := range []string{udnIPv4, udnIPv6} {
if destIP == "" {
continue
}

By("checking the non-kubelet host process can't reach UDN pod on IP " + destIP)
Consistently(func() bool {
_, err = runCommand(containerRuntime, "exec", workerOneNodeName,
"curl", "--connect-timeout", "2",
net.JoinHostPort(destIP, fmt.Sprintf("%d", port)))
return err != nil
}, 5*time.Second).Should(BeTrue())
By("checking the default network hostNetwork pod can't reach UDN pod on IP " + destIP)
Consistently(func() bool {
return connectToServer(podConfiguration{namespace: hostNetPod.Namespace, name: hostNetPod.Name}, destIP, port) != nil
}, 5*time.Second).Should(BeTrue())

By("checking the non-kubelet host process can't reach UDN pod on IP " + destIP)
Consistently(func() bool {
_, err = runCommand(containerRuntime, "exec", workerOneNodeName,
"curl", "--connect-timeout", "2",
net.JoinHostPort(destIP, fmt.Sprintf("%d", port)))
return err != nil
}, 5*time.Second).Should(BeTrue())
}
}

By("asserting UDN pod can reach the kapi service in the default network")
Expand Down Expand Up @@ -1046,10 +1049,12 @@ spec:
return connectToServer(podConfiguration{namespace: defaultClientPod.Namespace, name: defaultClientPod.Name}, destIP, port) != nil
}, 5*time.Second).Should(BeTrue())

By("checking the default hostNetwork pod can't reach UDN pod on IP " + destIP)
Consistently(func() bool {
return connectToServer(podConfiguration{namespace: hostNetPod.Namespace, name: hostNetPod.Name}, destIP, port) != nil
}, 5*time.Second).Should(BeTrue())
if !isUDNHostIsolationDisabled() {
By("checking the default hostNetwork pod can't reach UDN pod on IP " + destIP)
Consistently(func() bool {
return connectToServer(podConfiguration{namespace: hostNetPod.Namespace, name: hostNetPod.Name}, destIP, port) != nil
}, 5*time.Second).Should(BeTrue())
}
}

By("Open UDN pod port")
Expand Down Expand Up @@ -1094,10 +1099,12 @@ spec:
return connectToServer(podConfiguration{namespace: defaultClientPod.Namespace, name: defaultClientPod.Name}, destIP, port) != nil
}, 5*time.Second).Should(BeTrue())

By("checking the default hostNetwork pod can't reach UDN pod on IP " + destIP)
Eventually(func() bool {
return connectToServer(podConfiguration{namespace: hostNetPod.Namespace, name: hostNetPod.Name}, destIP, port) != nil
}, 5*time.Second).Should(BeTrue())
if !isUDNHostIsolationDisabled() {
By("checking the default hostNetwork pod can't reach UDN pod on IP " + destIP)
Eventually(func() bool {
return connectToServer(podConfiguration{namespace: hostNetPod.Namespace, name: hostNetPod.Name}, destIP, port) != nil
}, 5*time.Second).Should(BeTrue())
}
}
By("Verify syntax error is reported via event")
events, err := cs.CoreV1().Events(udnPod.Namespace).List(context.Background(), metav1.ListOptions{})
Expand Down
5 changes: 5 additions & 0 deletions test/e2e/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,11 @@ func isInterconnectEnabled() bool {
return present && val == "true"
}

func isUDNHostIsolationDisabled() bool {
val, present := os.LookupEnv("DISABLE_UDN_HOST_ISOLATION")
return present && val == "true"
}

func isLocalGWModeEnabled() bool {
val, present := os.LookupEnv("OVN_GATEWAY_MODE")
return present && val == "local"
Expand Down

0 comments on commit 71ad044

Please sign in to comment.