ovn 常规使用场景以及优化过程

2023-01-08  本文已影响0人  cloudFans

1. ovn trunk port

image.png

vm1 bound to worker1
vm2 bound to worker2
child1 (VLAN 30) inside vm1
child2 (VLAN 50) inside vm2

image.png

ovn nb 以及 sb db存储的网络资源


[root@central vagrant]# ovn-nbctl show
switch db4e7781-370c-4439-becd-35803c0e3f12 (network1)
    port vm1
        addresses: ["40:44:00:00:00:01 192.168.0.11"]
    port vm2
        addresses: ["40:44:00:00:00:02 192.168.0.12"]
switch 40ac144b-a32a-4202-bce2-3329f8f3e98f (network2)
    port child1
        parent: vm1
        tag: 30 # vlan
        addresses: ["40:44:00:00:00:03 192.168.1.13"]
    port child2
        parent: vm2
        tag: 50  # vlan
        addresses: ["40:44:00:00:00:04 192.168.1.14"]

[root@central vagrant]# ovn-sbctl show
Chassis worker2
    hostname: worker2
    Encap geneve
        ip: "192.168.50.101"
[root@central vagrant]# ovn-sbctl show
Chassis worker2
    hostname: worker2
    Encap geneve
        ip: "192.168.50.101"
        options: {csum="true"}
    Port_Binding child2
    Port_Binding vm2
Chassis worker1
    hostname: worker1
    Encap geneve
        ip: "192.168.50.100"
        options: {csum="true"}
    Port_Binding child1
    Port_Binding vm1

虚拟机内部的vlan配置


[root@worker1 vagrant]# ip netns exec vm1 ip -d link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
2: child1@vm1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 40:44:00:00:00:03 brd ff:ff:ff:ff:ff:ff promiscuity 0
    vlan protocol 802.1Q id 30 <REORDER_HDR> addrgenmode eui64 
# vlan 30
numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
24: vm1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether 40:44:00:00:00:01 brd ff:ff:ff:ff:ff:ff promiscuity 2
    openvswitch addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535


[root@worker2 vagrant]# ip netns exec vm2 ip -d link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
2: child2@vm2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 40:44:00:00:00:04 brd ff:ff:ff:ff:ff:ff promiscuity 0
    vlan protocol 802.1Q id 50 <REORDER_HDR> addrgenmode eui64  
# vlan 50
numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
15: vm2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether 40:44:00:00:00:02 brd ff:ff:ff:ff:ff:ff promiscuity 2
    openvswitch addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535

2. 优化neutron 内存占用

RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)

image.png

可以看到在优化之前,neutron-server实际使用物理内存高达73.5Gib。
经过定位分析发现,ovn sb db存在将近上百万调MAC_Binding 记录(也就是arp相关的ip和mac的对应记录)。 MAC_Binding 是由ovn-controller维护和传播的。一旦学习到一个新的MAC地址,ovn就会为每一个连接到外部的软路由添加一个MAC_Binding。

在这个场景中,连接到外部网络的软路由只有16个,并且有观察到近1M条记录。 这个不进会导致内存问题,也会对ovn sbbound server造成大量的流量和压力,ovn-controller会向ovn sbbound发起大量的事务请求,并且还要响应回复。

为什么neutron要关注MAC_Binding, 为了复用fip。但是内网ip和mac都在不断的发生切换。为了删除过期的MAC_Binding 记录,在neutron中维护了MAC_Binding 的全量copy,因为copy中的MAC_Binding没有过期机制,所以最终肯定会触发OOM。

为了解决该问题,ovn提供了一种机制用于在某个时间点清理过期的MAC_Binding 记录。 比如在绑定和取消绑定fip的时候。
为了让neutron触发清理,特别提供了一个ovsdb-client 工具。

该机制合入后,RSS从75GB 收敛到 7.5GB。

image.png

3. 定位ovn的扩展性问题

ovn 支持fip(dnat_and_snat) 在hypervisor本地直接进行南北向路由决策。而不必将流量转发到一个中心式的网络节点。

当出去的流量到达ovn网桥时,会对源ip进行snat,经过br-int到br-external 的patch port 经专用公网网卡直接转发出去。

该特性叫做DVR,路由阶段不需要转发到网关节点,直接经本地计算节点出去,没有下一跳,overlay 流量,以及分布式路由处理。

主要优势就是,只要伸缩计算节点即可,唯一的成本是公网ip。

但是在fip的使用场景中,我们留意到 fip相关的 逻辑流表非常巨大。这会导致客户端(ovn-controller)以及服务端ovsdb-server cpu和内存消耗非常高。

我想继续弄清楚流表是如何分发的,以及什么材质导致该泄漏的主要原因。我只是简单计算了一下每一个阶段的流表数量并对他们进行了排序。如下的数据中心展示了93%的逻辑流表都处于两个阶段中。

$ head -n 6 logical_flows_distribution_sorted.txt
lr_out_egr_loop: 423414  62.24%
lr_in_ip_routing: 212199  31.19%
lr_in_ip_input: 10831  1.59%
ls_out_acl: 4831  0.71%
ls_in_port_sec_ip: 3471  0.51%
ls_in_l2_lkup: 2360  0.34%

以下是对应的工具

# ovn-sbctl list Logical_Flow > logical_flows.txt

# Retrieve all the stages in the current pipeline
$ grep ^external_ids logical_flows.txt | sed 's/.*stage-name=//' | tr -d '}' | sort | uniq

# Count how many flows on each stage
$ while read stage; do echo $stage: $(grep $stage logical_flows.txt -c); done < stage_names.txt  > logical_flows_distribution.txt

$ sort  -k 2 -g -r logical_flows_distribution.txt  > logical_flows_distribution_sorted.txt

下一步就是弄清楚这两张表的内容
(lr_out_egr_loop & lr_in_ip_routing)


_uuid               : e1cc600a-fb9c-4968-a124-b0f78ed8139f
actions             : "next;"
external_ids        : {source="ovn-northd.c:8958", stage-name=lr_out_egr_loop}
logical_datapath    : 9cd315f4-1033-4f71-a26e-045a379aebe8
match               : "ip4.src == 172.24.4.10 &amp;&amp; ip4.dst == 172.24.4.209"
pipeline            : egress
priority            : 200
table_id            : 2
hash                : 0

_uuid               : c8d8400a-590e-4b7e-b433-7a1491d31488
actions             : "inport = outport; outport = \"\"; flags = 0; flags.loopback = 1; reg9[1] = 1; next(pipeline=ingress, table=0); "
external_ids        : {source="ovn-northd.c:8950", stage-name=lr_out_egr_loop}
logical_datapath    : 9cd315f4-1033-4f71-a26e-045a379aebe8
match               : "is_chassis_resident(\"vm1\") &amp;&amp; ip4.src == 172.24.4.218 &amp;&amp; ip4.dst == 172.24.4.220"
pipeline            : egress
priority            : 300
table_id            : 2
hash                : 0


_uuid               : 0777b005-0ff0-40cb-8532-f7e2261dae06
actions             : "outport = \"router1-public\"; eth.src = 40:44:00:00:00:06; eth.dst = 40:44:00:00:00:07; reg0 = ip4.dst; reg1 = 172.24.4.218; reg9[2] = 1; reg9[0] = 0; ne
xt;"
external_ids        : {source="ovn-northd.c:6945", stage-name=lr_in_ip_routing}
logical_datapath    : 9cd315f4-1033-4f71-a26e-045a379aebe8
match               : "inport == \"router1-net1\" &amp;&amp; ip4.src == 192.168.0.11 &amp;&amp; ip4.dst == 172.24.4.226"
pipeline            : ingress
priority            : 400
table_id            : 9
hash                : 0

可以看出来,这些流表用于处理fip之间的包。
基本上是,对于每一个可能的fip对都存在这些流表,以便为了这些fip间的流量不会流经过geneve隧道。

然而fip到fip的流量流经两个ovn 端口,这个场景并不是最常用的用例。这些流表就先存在着以便保证dvr,并且不经过overlay 网络。

目前该问题已解决,200fip情况的逻辑流表的梳理已经从127K下降为2.7k, 并且能够保证线性增长。


image.png image.png

4. 关于geneve的封装

http://dani.foroselectronica.es/wp-content/uploads/2019/02/icmp-geneve-decoding

image.png
  1. Logical Datapath (switch/router) identifier (24 bits) - Geneve VNI
  2. Ingress and Egress port identifiers - Option with class 0x0102 and type 0x80 with 32 bits of data:

关于vni id 实际上是逻辑交换机和逻辑路由器的标识符。

进出 端口标识符

# 查看ls lr的vni id

[root@pc-node-1 master]# k ko sbctl list Datapath_Binding
_uuid               : af422fb1-f006-40a0-a347-aebfb6d686e3
external_ids        : {logical-switch="9fc30bf4-a27f-4e43-900c-bc346d09e4b6", name=external204}
load_balancers      : []
tunnel_key          : 4

_uuid               : 65d9b655-bbd7-45a5-b382-430668803c36
external_ids        : {logical-switch="76f17a8b-6458-4edc-b886-89497c1e3347", name=vpc1-subnet1}
load_balancers      : []
tunnel_key          : 6

_uuid               : c81d45b5-a362-4ce7-bc3a-f6fc81cb45bf
external_ids        : {logical-switch="f451ee57-2ccd-47e5-956b-cbb78c7e69a0", name=join}
load_balancers      : []
tunnel_key          : 2

_uuid               : b154d04e-4a14-4a9d-b171-b952de1eea7a
external_ids        : {logical-switch="015926e7-4e12-464c-859b-ad309ec4904d", name=ovn-default}
load_balancers      : []
tunnel_key          : 3

_uuid               : a6cf5a4f-3ddb-4d2f-a293-235aa1d8d553
external_ids        : {logical-router="e3e5e1ea-5193-4c80-9b91-3046f229bcfb", name=vpc1}
load_balancers      : []
tunnel_key          : 5

_uuid               : f234ef33-0a32-46d2-a065-2caa1f4cec59
external_ids        : {logical-router="dcd93f0a-0706-4e6d-9e8b-17ee3de2e17b", name=ovn-cluster}
load_balancers      : []
tunnel_key          : 1

参考: http://dani.foroselectronica.es/category/uncategorized/

上一篇 下一篇

猜你喜欢

热点阅读