Bug 1877002
Summary: | [OVN SCALE] Combine Logical Flows inside Southbound DB. | |||
---|---|---|---|---|
Product: | Red Hat Enterprise Linux Fast Datapath | Reporter: | Ilya Maximets <i.maximets> | |
Component: | OVN | Assignee: | Ilya Maximets <i.maximets> | |
Status: | CLOSED ERRATA | QA Contact: | Jianlin Shi <jishi> | |
Severity: | high | Docs Contact: | ||
Priority: | high | |||
Version: | FDP 20.E | CC: | ctrautma, dblack, dcbw, dceara, jlema, mark.d.gray, nusiddiq, rsevilla | |
Target Milestone: | --- | Keywords: | TestBlocker | |
Target Release: | --- | |||
Hardware: | Unspecified | |||
OS: | Unspecified | |||
Whiteboard: | aos-scalability-47 | |||
Fixed In Version: | Doc Type: | If docs needed, set a value | ||
Doc Text: | Story Points: | --- | ||
Clone Of: | ||||
: | 1943314 (view as bug list) | Environment: | ||
Last Closed: | 2021-03-15 14:36:02 UTC | Type: | Bug | |
Regression: | --- | Mount Type: | --- | |
Documentation: | --- | CRM: | ||
Verified Versions: | Category: | --- | ||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | ||
Cloudforms Team: | --- | Target Upstream Version: | ||
Embargoed: | ||||
Bug Depends On: | ||||
Bug Blocks: | 1859924, 1903265, 1943314 |
Description
Ilya Maximets
2020-09-08 17:01:16 UTC
This week I tried to implement a PoC patch for this, i.e. to have a separate Logical Datapath Group table in Southbound DB and have a reference to it from the logical flow. Changes in northd are mostly straightforward and doesn't require much work (I started with 1 datapath group per lflow to simplify things for PoC, i.e. to not have several lfows referencing same datapath group). But ovn-controller turned out to be too hard to modify. Few main issues of the ovn-controller implementation: 1. ovn-controller works directly on the database all the time, it doesn't have any abstraction layer that could hide database schema modifications. Almost all parts of ovn-controller should be modified instead. 2. Unfortunately, almost all parts of lflow processing code depends on fact that each lflow corresponds to exactly one logical datapath. Even match expression parsing code requires to know for which logical datapath this expression is parse. Because of this it's required to re-write half of the lflow processing code in order to implement the change. So, because of the current ovn-controller code design it's very hard to implement the feature. Dumitru said that he will take a look on how to remove dependency on logical datapath from the expression parsing code. I'll wait for this to happen before continuing this work. Current unfinished PoC patches available here: https://github.com/igsilya/ovn/tree/logical-datapath-group (In reply to Ilya Maximets from comment #1) [...] > > 2. Unfortunately, almost all parts of lflow processing code depends on fact > that each lflow corresponds to exactly one logical datapath. Even match > expression parsing code requires to know for which logical datapath this > expression is parse. Because of this it's required to re-write half of > the lflow processing code in order to implement the change. As discussed offline, even though it's not ideal that match expression parsing depends on the datapath, I think we still need to call expr_to_matches() for each logical datapath when parsing the match expression for a flow because it filters out the ports that are not part of the datapath (e.g., if a port group includes ports from different logical switches): https://github.com/ovn-org/ovn/blob/e14b52a9f6ff455ccc0c8e6616ab474baa14643f/controller/lflow.c#L907 > > So, because of the current ovn-controller code design it's very hard to > implement the feature. Dumitru said that he will take a look on how to > remove > dependency on logical datapath from the expression parsing code. I'll wait > for this to happen before continuing this work. > I started looking at options but this might turn out to be quite a large change. As discussed offline, it's probably worth unblocking the PoC and just call consider_logical_flow() for every logical datapath referred by the logical_flow. This means that ovn-controller will be as inefficient as it is today (parsing the same flow multiple times for multiple datapaths) but it should show if the optimization is worth to alleviate the load on the Southbound DB. Once bug 1897201 is fixed we can take this a step further and optimize ovn-controller so that it parses a logical flow match exactly once. > Current unfinished PoC patches available here: > https://github.com/igsilya/ovn/tree/logical-datapath-group Thanks, Dumitru, for looking at the issue and summarizing our discussion here. I took the approach of calling consider_logical_flow() for every logical datapath referred by the logical_flow. This seems to work functionally. Patches sent upstream for review: https://patchwork.ozlabs.org/project/ovn/list/?series=214426 Fix allowes to reduce size of a database and number of logical flows in DBs from BZ 1859924 up to ~5.5x times. Few unit tests are failing, I need to look at them. Also, I didn't run any performance tests yet. And this is a required next step because processing steps in both northd and ovn-controller were modified. v2 of the patch set sent upstream: https://patchwork.ozlabs.org/project/ovn/list/?series=218369&state=* Together with Dumitru we fixed or worked around all the problems, so that this version is fully functional and can be accepted as is. Waiting for review. However, while debugging, we discovered many problems with the current implementation of ovn-controller that prevented us from implementing a better solution for handling datapath groups. Basically, everything that is said in comment #1 is true or even worse. Since we were unable to implement incremental processing in the ovn-controller that would only perform the necessary flow updates (code re-considers logical flow for all datapaths in a group instead of re-considering only for new/deleted datapath), this feature may have corner cases with poor performance on the ovn controller side. Presumably, such a case could be if we had many logical datapaths served by one ovn-controller. IIUC, this is not the case for ovn-k8s, but may be for OpenStack, so enabling this feature should be evaluated for specific use case/reference architecture. Feature could be enabled by updating NB_Global options: ovn-nbctl set NB_Global . options:use_logical_dp_groups=true ovn-controller needs a big rework, e.g. abstraction layer between the database and the application logic and many other stuff, to be flexible and extendible. v3 of the series is: https://patchwork.ozlabs.org/project/ovn/list/?series=218683&archive=both&state=* Current status update: - v3 of the patch-set merged upstream: https://patchwork.ozlabs.org/project/ovn/list/?series=218683&archive=both&state=* - One follow-up fix for multicast flows also merged: https://patchwork.ozlabs.org/project/ovn/patch/20201207115106.533958-1-i.maximets@ovn.org/ - One more fix for the performance regression in case where datapath groups disabled sent to the mail list and reviewed. Waiting for acceptance: https://patchwork.ozlabs.org/project/ovn/patch/20201211180115.3829253-1-i.maximets@ovn.org/ Everything is merged upstream and should be available in ovn2.13-20.12.0-1 package. build topo with following script: server: systemctl start openvswitch systemctl start ovn-northd ovn-nbctl set-connection ptcp:6641 ovn-sbctl set-connection ptcp:6642 ovs-vsctl set open . external_ids:system-id=hv1 external_ids:ovn-remote=tcp:20.0.163.101:6642 external_ids:ovn-encap-type=geneve external_ids:ovn-encap-ip=20.0.163.101 systemctl restart ovn-controller ip netns add server0 ip link add veth0_s0 netns server0 type veth peer name veth0_s0_p ip netns exec server0 ip link set lo up ip netns exec server0 ip link set veth0_s0 up ip netns exec server0 ip link set veth0_s0 address 00:00:00:01:01:02 ip netns exec server0 ip addr add 192.168.1.1/24 dev veth0_s0 ip netns exec server0 ip -6 addr add 2001::1/64 dev veth0_s0 ip netns exec server0 ip route add default via 192.168.1.254 dev veth0_s0 ip netns exec server0 ip -6 route add default via 2001::a dev veth0_s0 ovs-vsctl add-port br-int veth0_s0_p ip link set veth0_s0_p up ovs-vsctl set interface veth0_s0_p external_ids:iface-id=ls1p1 ovn-nbctl ls-add ls1 ovn-nbctl lsp-add ls1 ls1p1 #ovn-nbctl lsp-set-addresses ls1p1 "00:00:00:01:01:02 2001::1 192.168.1.1" ovn-nbctl lsp-set-addresses ls1p1 "00:00:00:01:01:02 192.168.1.1 2001::1" ovn-nbctl lsp-add ls1 ls1p2 ovn-nbctl lsp-set-addresses ls1p2 "00:00:00:01:02:02 192.168.1.2 2001::2" ovn-nbctl lr-add lr1 ovn-nbctl lrp-add lr1 lr1-ls1 00:00:00:00:00:01 192.168.1.254/24 2001::a/64 ovn-nbctl lsp-add ls1 ls1-lr1 ovn-nbctl lsp-set-addresses ls1-lr1 "00:00:00:00:00:01 192.168.1.254 2001::a" ovn-nbctl lsp-set-type ls1-lr1 router ovn-nbctl lsp-set-options ls1-lr1 router-port=lr1-ls1 ovn-nbctl lrp-add lr1 lr1-ls2 00:00:00:00:00:02 192.168.2.254/24 2002::a/64 ovn-nbctl ls-add ls2 ovn-nbctl lsp-add ls2 ls2-lr1 ovn-nbctl lsp-set-addresses ls2-lr1 "00:00:00:00:00:02 192.168.2.254 2002::a" ovn-nbctl lsp-set-type ls2-lr1 router ovn-nbctl lsp-set-options ls2-lr1 router-port=lr1-ls2 ovn-nbctl lsp-add ls2 ls2p1 ovn-nbctl lsp-set-addresses ls2p1 "00:00:00:02:01:02 192.168.2.1 2002::1" ovn-nbctl lsp-add ls1 ls1p3 ovn-nbctl lsp-set-addresses ls1p3 "00:00:00:01:03:02 192.168.1.3 2001::3" ovn-nbctl lb-add lb0 192.168.1.100 192.168.1.1,192.168.1.2 ovn-nbctl ls-lb-add ls2 lb0 client: #!/bin/bash systemctl start openvswitch ovs-vsctl set open . external_ids:system-id=hv0 external_ids:ovn-remote=tcp:20.0.163.101:6642 external_ids:ovn-encap-type=geneve external_ids:ovn-encap-ip=20.0.163.13 systemctl start ovn-controller ip netns add server1 ip link add veth0_s1 netns server1 type veth peer name veth0_s1_p ip netns exec server1 ip link set lo up ip netns exec server1 ip link set veth0_s1 up ip netns exec server1 ip link set veth0_s1 address 00:00:00:01:02:02 ip netns exec server1 ip addr add 192.168.1.2/24 dev veth0_s1 ip netns exec server1 ip -6 addr add 2001::2/64 dev veth0_s1 ip netns exec server1 ip route add default via 192.168.1.254 dev veth0_s1 ip netns exec server1 ip -6 route add default via 2001::a dev veth0_s1 ovs-vsctl add-port br-int veth0_s1_p ip link set veth0_s1_p up ovs-vsctl set interface veth0_s1_p external_ids:iface-id=ls1p2 ip netns add client0 ip link add veth0_c0 netns client0 type veth peer name veth0_c0_p ip netns exec client0 ip link set lo up ip netns exec client0 ip link set veth0_c0 up ip netns exec client0 ip link set veth0_c0 address 00:00:00:02:01:02 ip netns exec client0 ip addr add 192.168.2.1/24 dev veth0_c0 ip netns exec client0 ip -6 addr add 2002::1/64 dev veth0_c0 ip netns exec client0 ip route add default via 192.168.2.254 dev veth0_c0 ip netns exec client0 ip -6 route add default via 2002::a dev veth0_c0 ovs-vsctl add-port br-int veth0_c0_p ip link set veth0_c0_p up ovs-vsctl set interface veth0_c0_p external_ids:iface-id=ls2p1 result on 20.12.0-1: [root@wsfd-advnetlab16 bz1877002]# ovn-nbctl list nb_global _uuid : 6843ccad-a484-4449-808a-9c111a2cf235 connections : [3e7e5245-8b15-4c82-a23e-191e926cf419] external_ids : {} hv_cfg : 0 hv_cfg_timestamp : 0 ipsec : false name : "" nb_cfg : 0 nb_cfg_timestamp : 0 options : {mac_prefix="2e:9e:70", max_tunid="16711680", northd_internal_version="20.12.0-20.12.0-51.0", svc_monitor_mac="42:e7:5e:38:5a:16"} sb_cfg : 0 sb_cfg_timestamp : 0 ssl : [] [root@wsfd-advnetlab16 bz1877002]# ovn-sbctl list logical_dp_group <=== no logical_dp_group [root@wsfd-advnetlab16 bz1877002]# ovn-sbctl list logical_flow | wc -l 3343 [root@wsfd-advnetlab16 bz1877002]# ovn-nbctl --wait=hv set NB_Global . options:use_logical_dp_groups=true [root@wsfd-advnetlab16 bz1877002]# ovn-sbctl list logical_flow | wc -l 2661 <==== less flows [root@wsfd-advnetlab16 bz1877002]# ovn-sbctl list logical_dp_group _uuid : 944c3cf1-0b44-4d70-8c1b-c9ce0659db0c datapaths : [61dc573f-5e71-42ea-882f-96f3f4a29d7f, e472006a-aed2-4d82-9028-9bfacbac383f] [root@wsfd-advnetlab16 bz1877002]# ovn-sbctl list datapath_binding _uuid : ac83c9d2-8e94-4b45-96a6-7254b61ae556 external_ids : {logical-router="c790eba4-c177-49e6-a142-943df5e7afa1", name=lr1} load_balancers : [] tunnel_key : 2 _uuid : e472006a-aed2-4d82-9028-9bfacbac383f external_ids : {logical-switch="9ad7ebac-ad6d-4e81-9c40-1e45c712d660", name=ls1} load_balancers : [] tunnel_key : 1 _uuid : 61dc573f-5e71-42ea-882f-96f3f4a29d7f external_ids : {logical-switch="1e9421e7-b10e-4c74-aa76-4d40b31dbf6e", name=ls2} load_balancers : [2bf87375-7e32-43ec-bfad-85b8f58e40ed] tunnel_key : 3 <==== logical_dp_group contains dp for ls1 and ls2 [root@wsfd-advnetlab16 bz1877002]# ovn-sbctl find logical_flow logical_dp_group=944c3cf1-0b44-4d70-8c1b-c9ce0659db0c | wc -l 681 <=== flows contain the logical_dp_group [root@wsfd-advnetlab19 bz1877002]# ip netns exec client0 ping 192.168.1.3 -c 1 PING 192.168.1.3 (192.168.1.3) 56(84) bytes of data. 64 bytes from 192.168.1.3: icmp_seq=1 ttl=63 time=6.42 ms --- 192.168.1.3 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 6.425/6.425/6.425/0.000 ms [root@wsfd-advnetlab19 bz1877002]# ip netns exec client0 ping 192.168.1.2 -c 1 PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data. 64 bytes from 192.168.1.2: icmp_seq=1 ttl=63 time=1.60 ms --- 192.168.1.2 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 1.603/1.603/1.603/0.000 ms [root@wsfd-advnetlab19 bz1877002]# ip netns exec client0 ping 192.168.1.1 -c 1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=63 time=1.69 ms --- 192.168.1.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 1.698/1.698/1.698/0.000 ms [root@wsfd-advnetlab19 bz1877002]# ip netns exec client0 ping 192.168.1.100 -c 1 PING 192.168.1.100 (192.168.1.100) 56(84) bytes of data. 64 bytes from 192.168.1.100: icmp_seq=1 ttl=63 time=1.37 ms --- 192.168.1.100 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 1.378/1.378/1.378/0.000 ms <== ping works well [root@wsfd-advnetlab16 bz1877002]# rpm -qa | grep -E "ovn2.13|openvswitch2.13" openvswitch2.13-2.13.0-71.el7fdp.x86_64 ovn2.13-host-20.12.0-1.el7fdp.x86_64 ovn2.13-central-20.12.0-1.el7fdp.x86_64 ovn2.13-20.12.0-1.el7fdp.x86_64 set VERIFIED per comment 8 Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory (ovn2.13 bug fix and enhancement update), and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2021:0836 |