Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCPBUGS-42944: Fix egress gateway pod cleanup for remote zone pods. #2356

Open
wants to merge 2 commits into
base: release-4.14
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions go-controller/pkg/ovn/ovn.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,10 @@ func (oc *DefaultNetworkController) removeRemoteZonePod(pod *kapi.Pod) error {
return fmt.Errorf("failed to remove the remote zone pod : %w", err)
}

if util.PodWantsHostNetwork(pod) {
// Delete the routes in the namespace associated with this remote pod if it was acting as an external GW
if err := oc.deletePodExternalGW(pod); err != nil {
return fmt.Errorf("unable to delete external gateway routes for remote pod %s: %w",
getPodNamespacedName(pod), err)
}
// Delete the routes in the namespace associated with this remote pod if it was acting as an external GW
if err := oc.deletePodExternalGW(pod); err != nil {
return fmt.Errorf("unable to delete external gateway routes for remote pod %s: %w",
getPodNamespacedName(pod), err)
}

if kubevirt.IsPodLiveMigratable(pod) {
Expand Down
31 changes: 21 additions & 10 deletions test/e2e/external_gateways.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ var _ = ginkgo.Describe("External Gateway", func() {
servingNamespace = ns.Name

addressesv4, addressesv6 = setupGatewayContainersForConntrackTest(f, nodes, gwContainer1, gwContainer2, srcPodName)
sleepCommand = []string{"bash", "-c", "sleep 20000"}
sleepCommand = []string{"bash", "-c", "trap : TERM INT; sleep infinity & wait"}
_, err = createGenericPod(f, gatewayPodName1, nodes.Items[0].Name, servingNamespace, sleepCommand)
framework.ExpectNoError(err, "Create and annotate the external gw pods to manage the src app pod namespace, failed: %v", err)
_, err = createGenericPod(f, gatewayPodName2, nodes.Items[1].Name, servingNamespace, sleepCommand)
Expand Down Expand Up @@ -490,7 +490,7 @@ var _ = ginkgo.Describe("External Gateway", func() {
ginkgotable.Entry("IPV6 udp", &addressesv6, "udp"),
ginkgotable.Entry("IPV6 tcp", &addressesv6, "tcp"))

ginkgotable.DescribeTable("ExternalGWPod annotation: Should validate conntrack entry deletion for TCP/UDP traffic via multiple external gateways a.k.a ECMP routes", func(addresses *gatewayTestIPs, protocol string) {
ginkgotable.DescribeTable("ExternalGWPod annotation: Should validate conntrack entry deletion for TCP/UDP traffic via multiple external gateways a.k.a ECMP routes", func(addresses *gatewayTestIPs, protocol string, deletePod bool) {
if addresses.srcPodIP == "" || addresses.nodeIP == "" {
skipper.Skipf("Skipping as pod ip / node ip are not set pod ip %s node ip %s", addresses.srcPodIP, addresses.nodeIP)
}
Expand Down Expand Up @@ -537,8 +537,16 @@ var _ = ginkgo.Describe("External Gateway", func() {
totalPodConnEntries := pokeConntrackEntries(nodeName, addresses.srcPodIP, protocol, nil)
gomega.Expect(totalPodConnEntries).To(gomega.Equal(6)) // total conntrack entries for this pod/protocol

ginkgo.By("Remove second external gateway pod's routing-namespace annotation")
annotatePodForGateway(gatewayPodName2, servingNamespace, "", addresses.gatewayIPs[1], false)
if deletePod {
ginkgo.By(fmt.Sprintf("Delete second external gateway pod %s from ns %s", gatewayPodName2, servingNamespace))
err = f.ClientSet.CoreV1().Pods(servingNamespace).Delete(context.TODO(), gatewayPodName2, metav1.DeleteOptions{})
framework.ExpectNoError(err, "Delete the gateway pod failed: %v", err)
// give some time to handle pod delete event
time.Sleep(5 * time.Second)
} else {
ginkgo.By("Remove second external gateway pod's routing-namespace annotation")
annotatePodForGateway(gatewayPodName2, servingNamespace, "", addresses.gatewayIPs[1], false)
}

// ensure the conntrack deletion tracker annotation is updated
if !isInterconnectEnabled() {
Expand Down Expand Up @@ -577,10 +585,13 @@ var _ = ginkgo.Describe("External Gateway", func() {
gomega.Expect(podConnEntriesWithMACLabelsSet).To(gomega.Equal(0)) // we don't have any remaining gateways left
gomega.Expect(totalPodConnEntries).To(gomega.Equal(4)) // 6-2
},
ginkgotable.Entry("IPV4 udp", &addressesv4, "udp"),
ginkgotable.Entry("IPV4 tcp", &addressesv4, "tcp"),
ginkgotable.Entry("IPV6 udp", &addressesv6, "udp"),
ginkgotable.Entry("IPV6 tcp", &addressesv6, "tcp"))
ginkgotable.Entry("IPV4 udp", &addressesv4, "udp", false),
ginkgotable.Entry("IPV4 tcp", &addressesv4, "tcp", false),
ginkgotable.Entry("IPV6 udp", &addressesv6, "udp", false),
ginkgotable.Entry("IPV6 tcp", &addressesv6, "tcp", false),
ginkgo.Entry("IPV4 udp + pod delete", &addressesv4, "udp", true),
ginkgo.Entry("IPV6 tcp + pod delete", &addressesv6, "tcp", true),
)
})

// BFD Tests are dual of external gateway. The only difference is that they enable BFD on ovn and
Expand Down Expand Up @@ -2581,7 +2592,7 @@ func reachPodFromContainer(targetAddress, targetPort, targetPodName, srcContaine
framework.ExpectEqual(strings.Trim(res, "\n"), targetPodName)
}

func annotatePodForGateway(podName, podNS, namespace, networkIPs string, bfd bool) {
func annotatePodForGateway(podName, podNS, targetNamespace, networkIPs string, bfd bool) {
if !strings.HasPrefix(networkIPs, "\"") {
networkIPs = fmt.Sprintf("\"%s\"", networkIPs)
}
Expand All @@ -2591,7 +2602,7 @@ func annotatePodForGateway(podName, podNS, namespace, networkIPs string, bfd boo
annotateArgs := []string{
fmt.Sprintf("k8s.v1.cni.cncf.io/network-status=[{\"name\":\"%s\",\"interface\":"+
"\"net1\",\"ips\":[%s],\"mac\":\"%s\"}]", "foo", networkIPs, "01:23:45:67:89:10"),
fmt.Sprintf("k8s.ovn.org/routing-namespaces=%s", namespace),
fmt.Sprintf("k8s.ovn.org/routing-namespaces=%s", targetNamespace),
fmt.Sprintf("k8s.ovn.org/routing-network=%s", "foo"),
}
if bfd {
Expand Down
2 changes: 1 addition & 1 deletion test/scripts/e2e-cp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ SKIPPED_TESTS=""
if [ "$KIND_IPV4_SUPPORT" == true ]; then
if [ "$KIND_IPV6_SUPPORT" == true ]; then
# No support for these features in dual-stack yet
SKIPPED_TESTS="hybrid.overlay|external.gateway"
SKIPPED_TESTS="hybrid.overlay"
else
# Skip sflow in IPv4 since it's a long test (~5 minutes)
# We're validating netflow v5 with an ipv4 cluster, sflow with an ipv6 cluster
Expand Down