美文网首页
ovn 常规使用场景以及优化过程

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

作者: cloudFans | 来源:发表于2023-01-08 17:26 被阅读0次

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/

相关文章

  • UIViewController 预加载方案浅谈

    一. 引子 预加载作为常规性能优化手段,在所有性能敏感的场景都有使用。不同的场景会有不同的方案。举个例子,网易邮箱...

  • ovn 集成容器

    本文实验如何和容器集成,这里的场景指的是容器运行在vm中,而ovn运行在hypervisor上,可参考ovn-ar...

  • 你可能不知道的mpvue性能优化技巧

    最近一直在折腾mpvue写的微信小程序的性能优化,分享下实战的过程。 先上个优化前后的图: 常规优化 常规的Web...

  • 支付业务交互-付款码(2)

    项目背景 为了更好的体验,对于现在线下场景支付方式进行优化,进行竞品分析以及使用,基于体验的角度提出优化,继而开始...

  • 支付业务交互-扫一扫(3)

    项目背景 为了更好的体验,对于现在线下场景支付方式进行优化,进行竞品分析以及使用,基于体验的角度提出优化,继而开始...

  • 多线程iOS

    NSThread 常规使用场景 NSOperation& NSOperationQueue operation o...

  • ovn 3个选举 两种超时

    cms <----> ovn-nbdb <----> ovn-northd <----> ovn-sbdb <-...

  • 基于OVN的K8s网络组件Kube-OVN 企业版发布,现开放试

    1Kube-OVN社区版V1.3再升级支持容器网络硬件加速,自定义网关,网关Qos以及更多 Kube-OVN社区版...

  • GCD 中 Group的使用

    GCD 中的group 使用 在最近的业务场景中,考虑到性能的优化,以及建减少服务器的压力,使用到从并行到串行业务...

  • UI优化

    UI优化,也就是体验优化 常见优化场景 1) 过渡绘制 2) 布局复杂度 3) 逻辑优化 4) 内存使用优化 UI...

网友评论

      本文标题:ovn 常规使用场景以及优化过程

      本文链接:https://www.haomeiwen.com/subject/ewpucdtx.html