From 4e50fc5fda8462bd76e86835e4e56c2c019b69b0 Mon Sep 17 00:00:00 2001 From: Alexander Constantinescu Date: Fri, 15 Oct 2021 18:00:34 +0200 Subject: [PATCH] Legacy: fix node connectivity to service backed by egress IP pods Legacy commit using ovn-nbctl for the implementation. This commit will be used for backports to older versions. The host network couldn't connect to services backed by egress IP matching pods since the return packets would get forwarded to the egress nodes for these pods because of the routing policies specified for the egress matching pods. This would in turn break the connection. Hence what we need is to specify routing policies which forces the packet to go to the originating GR instead of getting routed to the egress node GR. Conflicts: go-controller/pkg/ovn/egressip.go go-controller/pkg/ovn/egressip_test.go Signed-off-by: Flavio Fernandes Co-authored-by: Alexander Constantinescu (cherry picked from commit 49f4fef8ae0f5c18bc4ba768cda4fa502bb148b4) --- go-controller/pkg/ovn/egressip.go | 20 +++++++++++ go-controller/pkg/ovn/egressip_test.go | 48 ++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/go-controller/pkg/ovn/egressip.go b/go-controller/pkg/ovn/egressip.go index 09d052e68c..520b9df4d4 100644 --- a/go-controller/pkg/ovn/egressip.go +++ b/go-controller/pkg/ovn/egressip.go @@ -751,6 +751,7 @@ func (oc *Controller) deleteNodeForEgress(node *v1.Node) error { func (oc *Controller) initClusterEgressPolicies(nodes []interface{}) { v4ClusterSubnet, v6ClusterSubnet := getClusterSubnets() createDefaultNoReroutePodPolicies(v4ClusterSubnet, v6ClusterSubnet) + oc.createDefaultNoRerouteServicePolicies(v4ClusterSubnet, v6ClusterSubnet) go oc.checkEgressNodesReachability() } @@ -1095,6 +1096,25 @@ func getNodeInternalAddrs(node *v1.Node) (net.IP, net.IP) { return v4Addr, v6Addr } +// createDefaultNoRerouteServicePolicies ensures service reachability from the +// host network to any service backed by egress IP matching pods +func (oc *Controller) createDefaultNoRerouteServicePolicies(v4ClusterSubnet, v6ClusterSubnet *net.IPNet) { + if v4ClusterSubnet != nil { + _, stderr, err := util.RunOVNNbctl("--may-exist", "lr-policy-add", types.OVNClusterRouter, fmt.Sprintf("%v", types.DefaultNoRereoutePriority), + fmt.Sprintf("ip4.src == %s && ip4.dst == %s", v4ClusterSubnet.String(), config.Gateway.V4JoinSubnet), "allow") + if err != nil { + klog.Errorf("Unable to create IPv4 default no-reroute service policy, stderr: %s, err: %v", stderr, err) + } + } + if v6ClusterSubnet != nil { + _, stderr, err := util.RunOVNNbctl("--may-exist", "lr-policy-add", types.OVNClusterRouter, fmt.Sprintf("%v", types.DefaultNoRereoutePriority), + fmt.Sprintf("ip6.src == %s && ip6.dst == %s", v6ClusterSubnet.String(), config.Gateway.V6JoinSubnet), "allow") + if err != nil { + klog.Errorf("Unable to create IPv6 default no-reroute service policy, stderr: %s, err: %v", stderr, err) + } + } +} + // createDefaultNoReroutePodPolicies ensures egress pods east<->west traffic with regular pods, // i.e: ensuring that an egress pod can still communicate with a regular pod / service backed by regular pods func createDefaultNoReroutePodPolicies(v4ClusterSubnet, v6ClusterSubnet *net.IPNet) { diff --git a/go-controller/pkg/ovn/egressip_test.go b/go-controller/pkg/ovn/egressip_test.go index 62b4662b37..fe9a047632 100644 --- a/go-controller/pkg/ovn/egressip_test.go +++ b/go-controller/pkg/ovn/egressip_test.go @@ -241,6 +241,12 @@ var _ = Describe("OVN master EgressIP Operations", func() { }, ) + fakeOvn.fakeExec.AddFakeCmdsNoOutputNoError( + []string{ + fmt.Sprintf("ovn-nbctl --timeout=15 --may-exist lr-policy-add %s %v ip4.src == 10.128.0.0/14 && ip4.dst == %s allow", types.OVNClusterRouter, types.DefaultNoRereoutePriority, config.Gateway.V4JoinSubnet), + }, + ) + fakeOvn.controller.WatchEgressNodes() Eventually(getEgressIPAllocatorSizeSafely).Should(Equal(2)) Expect(fakeOvn.controller.eIPC.allocator).To(HaveKey(node1.Name)) @@ -394,6 +400,13 @@ var _ = Describe("OVN master EgressIP Operations", func() { fmt.Sprintf("ovn-nbctl --timeout=15 set logical_switch_port etor-GR_node1 options:nat-addresses=router"), }, ) + + fakeOvn.fakeExec.AddFakeCmdsNoOutputNoError( + []string{ + fmt.Sprintf("ovn-nbctl --timeout=15 --may-exist lr-policy-add %s %v ip4.src == 10.128.0.0/14 && ip4.dst == %s allow", types.OVNClusterRouter, types.DefaultNoRereoutePriority, config.Gateway.V4JoinSubnet), + }, + ) + fakeOvn.controller.WatchEgressNodes() Eventually(getEgressIPAllocatorSizeSafely).Should(Equal(2)) Expect(fakeOvn.controller.eIPC.allocator).To(HaveKey(node1.Name)) @@ -1307,6 +1320,13 @@ var _ = Describe("OVN master EgressIP Operations", func() { fmt.Sprintf("ovn-nbctl --timeout=15 set logical_switch_port etor-GR_node2 options:nat-addresses=router"), }, ) + + fakeOvn.fakeExec.AddFakeCmdsNoOutputNoError( + []string{ + fmt.Sprintf("ovn-nbctl --timeout=15 --may-exist lr-policy-add %s %v ip4.src == 10.128.0.0/14 && ip4.dst == %s allow", types.OVNClusterRouter, types.DefaultNoRereoutePriority, config.Gateway.V4JoinSubnet), + }, + ) + fakeOvn.controller.WatchEgressNodes() Eventually(getEgressIPAllocatorSizeSafely).Should(Equal(0)) node1.Labels = map[string]string{ @@ -1378,6 +1398,12 @@ var _ = Describe("OVN master EgressIP Operations", func() { return len(fakeOvn.controller.eIPC.allocator) } + fakeOvn.fakeExec.AddFakeCmdsNoOutputNoError( + []string{ + fmt.Sprintf("ovn-nbctl --timeout=15 --may-exist lr-policy-add %s %v ip4.src == 10.128.0.0/14 && ip4.dst == %s allow", types.OVNClusterRouter, types.DefaultNoRereoutePriority, config.Gateway.V4JoinSubnet), + }, + ) + fakeOvn.controller.WatchEgressNodes() Eventually(allocatorItems).Should(Equal(0)) @@ -1446,6 +1472,7 @@ var _ = Describe("OVN master EgressIP Operations", func() { fakeOvn.fakeExec.AddFakeCmdsNoOutputNoError( []string{ fmt.Sprintf("ovn-nbctl --timeout=15 lr-policy-add ovn_cluster_router 101 ip4.src == 10.128.0.0/14 && ip4.dst == 10.128.0.0/14 allow"), + fmt.Sprintf("ovn-nbctl --timeout=15 --may-exist lr-policy-add %s %v ip4.src == 10.128.0.0/14 && ip4.dst == %s allow", types.OVNClusterRouter, types.DefaultNoRereoutePriority, config.Gateway.V4JoinSubnet), }, ) @@ -1584,8 +1611,10 @@ var _ = Describe("OVN master EgressIP Operations", func() { []string{ fmt.Sprintf("ovn-nbctl --timeout=15 --format=csv --data=bare --no-heading --columns=_uuid,external_ids,match find logical_router_policy priority=100"), fmt.Sprintf("ovn-nbctl --timeout=15 --format=csv --data=bare --no-heading --columns=_uuid,external_ids,logical_ip find nat"), + fmt.Sprintf("ovn-nbctl --timeout=15 --may-exist lr-policy-add %s %v ip4.src == 10.128.0.0/14 && ip4.dst == %s allow", types.OVNClusterRouter, types.DefaultNoRereoutePriority, config.Gateway.V4JoinSubnet), }, ) + fakeOvn.controller.WatchEgressNodes() fakeOvn.controller.WatchEgressIP() @@ -1677,8 +1706,10 @@ var _ = Describe("OVN master EgressIP Operations", func() { []string{ fmt.Sprintf("ovn-nbctl --timeout=15 --format=csv --data=bare --no-heading --columns=_uuid,external_ids,match find logical_router_policy priority=100"), fmt.Sprintf("ovn-nbctl --timeout=15 --format=csv --data=bare --no-heading --columns=_uuid,external_ids,logical_ip find nat"), + fmt.Sprintf("ovn-nbctl --timeout=15 --may-exist lr-policy-add %s %v ip4.src == 10.128.0.0/14 && ip4.dst == %s allow", types.OVNClusterRouter, types.DefaultNoRereoutePriority, config.Gateway.V4JoinSubnet), }, ) + fakeOvn.controller.WatchEgressNodes() fakeOvn.controller.WatchEgressIP() @@ -1811,6 +1842,13 @@ var _ = Describe("OVN master EgressIP Operations", func() { fmt.Sprintf("ovn-nbctl --timeout=15 set logical_switch_port etor-GR_node2 options:nat-addresses=router"), }, ) + + fakeOvn.fakeExec.AddFakeCmdsNoOutputNoError( + []string{ + fmt.Sprintf("ovn-nbctl --timeout=15 --may-exist lr-policy-add %s %v ip4.src == 10.128.0.0/14 && ip4.dst == %s allow", types.OVNClusterRouter, types.DefaultNoRereoutePriority, config.Gateway.V4JoinSubnet), + }, + ) + fakeOvn.fakeExec.AddFakeCmd( &ovntest.ExpectedCmd{ Cmd: fmt.Sprintf("ovn-nbctl --timeout=15 --if-exist get logical_router_port rtoj-GR_%s networks", node1.Name), @@ -1966,6 +2004,12 @@ var _ = Describe("OVN master EgressIP Operations", func() { }, ) + fakeOvn.fakeExec.AddFakeCmdsNoOutputNoError( + []string{ + fmt.Sprintf("ovn-nbctl --timeout=15 --may-exist lr-policy-add %s %v ip4.src == 10.128.0.0/14 && ip4.dst == %s allow", types.OVNClusterRouter, types.DefaultNoRereoutePriority, config.Gateway.V4JoinSubnet), + }, + ) + fakeOvn.controller.WatchEgressNodes() fakeOvn.controller.WatchEgressIP() @@ -2047,8 +2091,10 @@ var _ = Describe("OVN master EgressIP Operations", func() { []string{ fmt.Sprintf("ovn-nbctl --timeout=15 --format=csv --data=bare --no-heading --columns=_uuid,external_ids,match find logical_router_policy priority=100"), fmt.Sprintf("ovn-nbctl --timeout=15 --format=csv --data=bare --no-heading --columns=_uuid,external_ids,logical_ip find nat"), + fmt.Sprintf("ovn-nbctl --timeout=15 --may-exist lr-policy-add %s %v ip4.src == 10.128.0.0/14 && ip4.dst == %s allow", types.OVNClusterRouter, types.DefaultNoRereoutePriority, config.Gateway.V4JoinSubnet), }, ) + fakeOvn.controller.WatchEgressNodes() fakeOvn.controller.WatchEgressIP() @@ -2181,6 +2227,7 @@ var _ = Describe("OVN master EgressIP Operations", func() { fakeOvn.fakeExec.AddFakeCmdsNoOutputNoError( []string{ fmt.Sprintf("ovn-nbctl --timeout=15 lr-policy-add ovn_cluster_router 101 ip4.src == 10.128.0.0/14 && ip4.dst == 10.128.0.0/14 allow"), + fmt.Sprintf("ovn-nbctl --timeout=15 --may-exist lr-policy-add %s %v ip4.src == 10.128.0.0/14 && ip4.dst == %s allow", types.OVNClusterRouter, types.DefaultNoRereoutePriority, config.Gateway.V4JoinSubnet), }, ) @@ -2329,6 +2376,7 @@ var _ = Describe("OVN master EgressIP Operations", func() { []string{ fmt.Sprintf("ovn-nbctl --timeout=15 --format=csv --data=bare --no-heading --columns=_uuid,external_ids,match find logical_router_policy priority=100"), fmt.Sprintf("ovn-nbctl --timeout=15 --format=csv --data=bare --no-heading --columns=_uuid,external_ids,logical_ip find nat"), + fmt.Sprintf("ovn-nbctl --timeout=15 --may-exist lr-policy-add %s %v ip4.src == 10.128.0.0/14 && ip4.dst == %s allow", types.OVNClusterRouter, types.DefaultNoRereoutePriority, config.Gateway.V4JoinSubnet), }, )