[连载型] Neutron 系列 (18): Neutron 分布式虚拟路由【下】

问题导读:



1.Neutron的代码分析?
2.Neutron 其它服务有哪些?
3.后续版本中 DVR 开发?



[连载型] Neutron 系列 (18): Neutron 分布式虚拟路由【下】





4. 代码分析

DVR 代码修改包括几部分:

 

  • DVR Router network namespace 的创建和删除
  • DVR Router 相关的 flows
  • DVR Router 的 ARP 表


4.1 DVR Router 相关 network namespace 的创建和删除

4.1.1 qrouter 在计算和网络节点上的删除和创建

    对于每一个 DVR Router,在每个分布了和 router 连接的网段内的虚机的计算节点上,都会有一个 qrouter 实例。两种情况下会将一个 DVR Router 部署到一个 L3 Agent 上:


1. 当一个子网 subnet 被加入到一个 DVR Router 时,DVR Router 会被分布到所有包含在该子网内的虚机的计算节点上。

  • 计算节点上的 L3 Agent 会收到一个通知,它会配置 router
  • OVS Agent 会将 router 的端口 plug 到 OVS Bridge 上,并且配置 flows


2. 当一个虚机被创建,而且虚机所在的计算节点上不存在该虚机所在 subnet 连接的 DVR Router 时。

3. 当与 DVR Router 相关的最后一个虚机被删除时,router namespace 会被从虚机所在的计算节点上删除。

4.1.2 snat 在网络节点上的创建和删除

创建:当设置 router 的 external gateway 时

 

删除:当删除 router 的 external gateway 时


4.1.3 fip 在 计算节点上的创建和删除

创建:当一个浮动 IP 被分配给一个虚机的时候,如果虚机所在的计算节点上 fip namespace 不存在,则创建它

 

删除:(1)当计算节点上最后一个使用浮动 IP 的虚机被删除后 (2)所有虚机的浮动 IP 被删除后


4.2 DVR MAC 地址

    前面提到过,分布到多个计算节点上的 qrouter 的interface 的 MAC 地址都相同。这在传统的网络中是不允许的,在 neutron 网络中某些时候也会导致一些问题。Neutron的做法是会向每个计算节点分配一个唯一的 DVR Host MAC 地址。当使用了 DVR 的 OVS Agent 启动的时候,它通过 RPC 去从 neutron server 上申请该 MAC 地址。该 MAC 地址会被保存在 DB 中,与该计算节点强绑定。比如:

 

[AppleScript] 纯文本查看 复制代码 ?
1 2 3 4 5 6 7 8 MariaDB [neutron]> select * from dvr_host_macs; +----------+-------------------+ | host     | mac_address       | +----------+-------------------+ | network  | fa:16:3f:12:a3:38 | | compute1 | fa:16:3f:b2:34:82 | | compute2 | fa:16:3f:db:6f:73 | +----------+-------------------+



当数据包离开 DVR Router 经过 br-tun 时,OVS flows 会将 DVR Router interface 的源 MAC 地址替换成该 MAC 地址。

 

[AppleScript] 纯文本查看 复制代码 ?
1 2 3 4 root@compute1:/home/s1# ovs-ofctl dump-flows br-tun | grep mod_dl_src cookie=0x0, duration=6989.394s, table=1, n_packets=6405, n_bytes=627690, idle_age=510, priority=1,dl_vlan=1,dl_src=fa:16:3e:ec:f3:dd actions=mod_dl_src:fa:16:3f:b2:34:82,resubmit(,2) cookie=0x0, duration=8055.165s, table=1, n_packets=10, n_bytes=980, idle_age=4814, priority=1,dl_vlan=2,dl_src=fa:16:3e:63:3b:4c actions=mod_dl_src:fa:16:3f:b2:34:82,resubmit(,2) cookie=0x0, duration=8059.947s, table=1, n_packets=635, n_bytes=26950, idle_age=4843, priority=1,dl_vlan=1,dl_src=fa:16:3e:a9:da:b5 actions=mod_dl_src:fa:16:3f:b2:34:82,resubmit(,2)



而 src mac 地址分别是 qrouter 上的作为默认各网段的默认网关的 mac 地址:

 

[AppleScript] 纯文本查看 复制代码 ?
1 2 3 4 5 6 s1@controller:~$ neutron port-list | grep fa:16:3e:ec:f3:dd | f849ae46-4819-45f5-a805-5970d4e31951 |      | fa:16:3e:ec:f3:dd | {"subnet_id": "f8841500-b392-4053-bda1-acf419f4a86e", "ip_address": "90.1.180.1"} s1@controller:~$ neutron port-list | grep fa:16:3e:63:3b:4c | 517bdba3-b117-43ce-851b-bb1d039879dc |      | fa:16:3e:63:3b:4c | {"subnet_id": "4ec65731-35a5-4637-a59b-a9f2932099f1", "ip_address": "81.1.180.1"} s1@controller:~$ neutron port-list | grep fa:16:3e:a9:da:b5 | e47fca31-dbf6-47e5-9ccb-0950557a55e3 |      | fa:16:3e:a9:da:b5 | {"subnet_id": "13888749-12b3-462e-9afe-c527bd0a297e", "ip_address": "91.1.180.1"}



因此,这里假设你不会将多个 DVR Router 连接到一个 subnet。当数据包达到该计算节点时,OVS flows 会将其源 MAC 地址替换成 VM gateway 的 MAC 地址。

 

DVR-MAC-ADDRESS 的更新是 neutron server 通过 RPC Notifier 做的。每当一个新的地址被分配后,它通知所有的 L3 Agent 节点做处理。


4.3 DVR OVS flows

使用 DVR Router 的计算节点上,br-int 和 br-tun 中的 flows 会有修改。具体请参见上文的 3.2.4 部分。


4.3.1 br-int flows 的主要修改

table 1: DVR_TO_SRC_MAC

 

table 0:LOCAL_SWITCHING

 

[AppleScript] 纯文本查看 复制代码 ?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 root@compute1:/home/s1# ovs-ofctl dump-flows br-int NXST_FLOW reply (xid=0x4): #获取所有的 DVR_MAC_ADDRESS,然后 # 从 patch-tun 进入的 src mac 为 network 节点的 DVR HOST MAC 的网络帧(也就是从 network 节点来的帧),重新提交 table 1 处理 table=0, n_packets=0, n_bytes=0, idle_age=9734, priority=2,in_port=5,dl_src=fa:16:3f:12:a3:38 actions=resubmit(,1) # 从 compute 2 节点来的网络帧,提交到 table 1 table=0, n_packets=2321, n_bytes=227458, idle_age=0, priority=2,in_port=5,dl_src=fa:16:3f:db:6f:73 actions=resubmit(,1) #本机上的虚机产生的网络帧,走常规的转发模式发到虚机或者 br-tun table=0, n_packets=22797, n_bytes=2176300, idle_age=0, priority=1 actions=NORMAL   #目标网段是 81.1.180.0/24 网段的帧,去掉 vlan tag,修改 src mac 为 qrouter 的 81.1.180.1 interface 的 mac 地址,发到虚机 table=1, n_packets=0, n_bytes=0, idle_age=9725, priority=2,ip,dl_vlan=2,nw_dst=81.1.180.0/24 actions=strip_vlan,mod_dl_src:fa:16:3e:63:3b:4c,output:4 #目标网段是 90.1.180.0/24 网段的帧,去掉 vlan tag,修改 src mac 为qrouter 的 90.1.180.1 interface 的 mac 地址,发到虚机 table=1, n_packets=0, n_bytes=0, idle_age=2268, priority=2,ip,dl_vlan=1,nw_dst=90.1.180.0/24 actions=strip_vlan,mod_dl_src:fa:16:3e:ec:f3:dd,output:8 #dst mac 地址为 vm1,去掉 vlan tag,修改 src mac,发到虚机table=1, n_packets=2321, n_bytes=227458, idle_age=0, priority=4,dl_vlan=2,dl_dst=fa:16:3e:30:ee:23 actions=strip_vlan,mod_dl_src:fa:16:3e:63:3b:4c,output:4 #dst mac 为 vm2,则去掉 vlan tag,修改 src mac,发到虚机table=1, n_packets=0, n_bytes=0, idle_age=2268, priority=4,dl_vlan=1,dl_dst=fa:16:3e:4a:22:ff actions=strip_vlan,mod_dl_src:fa:16:3e:ec:f3:dd,output:8table=1, n_packets=0, n_bytes=0, idle_age=9734, priority=1 actions=drop table=23, n_packets=0, n_bytes=0, idle_age=9734, priority=0 actions=drop

 

<ignore_js_op>[连载型] Neutron 系列 (18): Neutron 分布式虚拟路由【下】


4.3.2 br-tun flows 主要的修改

br-tun flows 的主要修改是增加了 table 1 和 9.

 

<ignore_js_op>[连载型] Neutron 系列 (18): Neutron 分布式虚拟路由【下】


对于将要离开本机的网络帧:

  • Table 1 (DVR process Table): 如果网络帧的 src mac 是本机 qrouter 上的 interface 的 mac 地址(dvr-router-intf-mac),将其修改为 DVR-compute-node-unique-mac,然后交给table 2 处理;其它的帧,交给 table 2.

 

[AppleScript] 纯文本查看 复制代码 ?
1 table=1, n_packets=8655, n_bytes=848190, idle_age=1, priority=1,dl_vlan=1,dl_src=fa:16:3e:ec:f3:dd actions=mod_dl_src:fa:16:3f:b2:34:82,resubmit(,2)table=1, n_packets=10, n_bytes=980, idle_age=7987, priority=1,dl_vlan=2,dl_src=fa:16:3e:63:3b:4c actions=mod_dl_src:fa:16:3f:b2:34:82,resubmit(,2)table=1, n_packets=635, n_bytes=26950, idle_age=8015, priority=1,dl_vlan=1,dl_src=fa:16:3e:a9:da:b5 actions=mod_dl_src:fa:16:3f:b2:34:82,resubmit(,2)

 

  • table 2:单播帧转 table 20;多播帧转 table 22

 

[AppleScript] 纯文本查看 复制代码 ?
1 2 table=2, n_packets=8673, n_bytes=849786, idle_age=1, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20) table=2, n_packets=675, n_bytes=30798, idle_age=3727, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,22)

 

  • table 20:将 vlan id 转化为 tunnel id,并根据处理进入本机的网络帧的时候学习到的 mac 地址和 tunnel port,查找网络帧的出口 tunnel port

 

[AppleScript] 纯文本查看 复制代码 ?
1 table=20, n_packets=0, n_bytes=0, idle_age=10156, priority=2,dl_vlan=1,dl_dst=fa:16:3e:54:f8:b8 actions=strip_vlan,set_tunnel:0x4,output:3table=20, n_packets=4012, n_bytes=393176, idle_age=1, priority=2,dl_vlan=1,dl_dst=fa:16:3e:13:93:0d actions=strip_vlan,set_tunnel:0x4,output:2

 

  • table 22:将 vlan id 转化为 tunnel id,并泛洪到所有的 tunnel 端口

 

[AppleScript] 纯文本查看 复制代码 ?
1 table=22, n_packets=8, n_bytes=1126, idle_age=11018, hard_age=5501, dl_vlan=2 actions=strip_vlan,set_tunnel:0x6,output:3,output:2table=22, n_packets=642, n_bytes=27866, idle_age=3727, hard_age=5469, dl_vlan=1 actions=strip_vlan,set_tunnel:0x4,output:3,output:2table=22, n_packets=25, n_bytes=1806, idle_age=3772, priority=0 actions=drop


对于进入本机的网络帧:

  • table 0:交给 table 3 处理
  • table 3:只允许目的网络为本机上的虚机所在的网络的网络帧,修改其 vlan id,转 table 9

 

[AppleScript] 纯文本查看 复制代码 ?
1 2 3 table=3, n_packets=98, n_bytes=6514, idle_age=3731, priority=1,tun_id=0x4 actions=mod_vlan_vid:1,resubmit(,9)  # tunnel id 转换为 vlan id table=3, n_packets=3830, n_bytes=375768, idle_age=1, priority=1,tun_id=0x6 actions=mod_vlan_vid:2,resubmit(,9) #tunnel id 转换为 vlan id table=3, n_packets=0, n_bytes=0, idle_age=11238, priority=0 actions=drop

 

  • Table 9 (DVR Learning blocker):如果 src mac 是 DVR-Unique-MAC,不做 mac 学习,转发到 patch-int;否则,转到 table 10 做 mac 地址学习

 

[AppleScript] 纯文本查看 复制代码 ?
1 table=9, n_packets=0, n_bytes=0, idle_age=11236, priority=1,dl_src=fa:16:3f:12:a3:38 actions=output:1 #从 network node 过来的帧,发到 br-inttable=9, n_packets=3821, n_bytes=374458, idle_age=1, priority=1,dl_src=fa:16:3f:db:6f:73 actions=output:1 #从 compute 2 node 过来的帧,发到 br-inttable=9, n_packets=107, n_bytes=7824, idle_age=3731, priority=0 actions=resubmit(,10) #其余提交 table 10 处理,进行地址学习

 

  • table 10:mac 地址学习,结果存到 table 20

 

[AppleScript] 纯文本查看 复制代码 ?
1 table=10, n_packets=107, n_bytes=7824, idle_age=3731, priority=1 actions=learn(table=20,hard_timeout=300,priority=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]),output:1

 

注意:在 table 20 中,除了自己通过 mac 地址学习学到的 mac 地址外,还需要借助 l2population 。这就是为什么 DVR 依赖于 l2population 的缘故。没有使用的话,网络包无法发到正确的 tunnel interface。

 

具体设置 OVS flows 的代码在 setup_dvr_flows_on_integ_tun_br 函数中。更详细的说明可以参考官方文章。


4.4 qrouter 中的ARP 表

虚机 vm1 需要通过 ARP 获取两种 mac 地址:

 

1. 当目标计算机(vm2)不在其同一个网段时,它需要获取默认网关的 mac 地址,这个将由 qrouter 直接相应 arp 请求。 2. 当目标计算机(vm2)在其同一个网段时,它需要直接获取 vm2 的 mac 地址。这个应该仍然是通过 ARP 广播获得。简单的做法是使用 arp responder。

 

qrouter 在做完 vm1 的网络包的路由后,将网络包从 vm2 所在网段的 interface 上发出前,需要获取 vm2 的 mac 地址。而这个是通过它查询自身的 ARP table 获得的。这是 compute 1 上 qrouter netns 中的 ip neighbour 表:

 

[AppleScript] 纯文本查看 复制代码 ?
1 2 3 4 root@compute1:/home/s1# ip netns exec qrouter-e8f12f7a-6938-4e65-88c4-97e4cb211b27 ip neigh 90.1.180.6 dev qr-f849ae46-48 lladdr fa:16:3e:13:93:0d PERMANENT 81.1.180.10 dev qr-517bdba3-b1 lladdr fa:16:3e:c0:8f:2c PERMANENT 90.1.180.3 dev qr-e47fca31-db lladdr fa:16:3e:69:92:30 PERMANENT



这里面可以看到大量的 PERMANENT MAC 地址。这是因为,L3 Agent 配置 DVR Router 的时候,它通过 RPC 从 neturon server 获取该 router 各 interface 的 subnet 中获取所有虚机的 MAC 地址。当一个 subnet 被加到 DVR Router 的时候,每个相关的 L3 Agent 都会被通知到,然后它通过 RPC 获取各 MAC 地址。当一个新的 port 被创建,或者 port 的 MAC 有更新的时候,所有相关的 L3 Agent 会被通知到去更新 ARP 表。

 

通过该由 L3 Agent 动态维护的 ARP 表,qrouter 就能直接查到它要通信的 interface 的 MAC 地址了,而不需要通过广播的方式去被动获取。具体原因是:

 

Why all of this complexity? Remember that the router’s MAC addresses are present on all hosts and cannot leave the host. If a router scheduled on host 1 generated an ARP request for a port scheduled on host 2, host 2 would receive the message and its virtual switches would suddenly re-learn a MAC they supposedly already know to be connected to br-int. They would see it coming from a tunnel connected to br-tun!

 

大致的更新过程为:

 

  • 每个L2 Agent 进程循环检查其管理的 port 的状态
  • 当 port 状态由 down 变为 up 时,它通过 RPC 通知 neutron server 该变化,neutron server 然后发出 fanout 通知其他的 L2 agent 去添加 arp entry (add_arp_entry),再调用 ip neigh replace方法在 qrouter network namespace 中 增加一个 arp entry
  • 当 port 状态由 up 变为 down 时,它通过 RPC 通知 neutron server 该变化,neutron server 然后发出 fanout 通知其他的 L2 agent 去添加 delete entry (del_arp_entry),再调用 ip neigh del 方法在 qrouter network namespace 中 删除该 arp entry


4.5 ip rule 和 route 操作

4.5.1 增加一个 internal subnet 时

在 qrouter namespace 上:

 

(1)计算该 subnet  cidr(81.1.180.1/24)的 index 1359066113,作为新增 ip rule 的优先级和路由表的名称。 (2)增加 default gateway,运行 ['ip route replace default via 81.1.180.17 dev qr-517bdba3-b1 table 1359066113]。这里的 81.1.180.17 正是 snat namespace 的 IP。 (3)增加 ip rule, 允许 [ip rule add from 81.1.180.1/24 lookup 1359066113 priority 1359066113]。这样就将该 subnet 中的虚机的网络帧转到 route table (4)执行 ip netns exec qrouter-e8f12f7a-6938-4e65-88c4-97e4cb211b27 sysctl -w net.ipv4.conf.qr-517bdba3-b1.send_redirects=0

 

效果如下:

 

[AppleScript] 纯文本查看 复制代码 ?
1 2 3 4 5 6 7 root@compute1:/home/s1# ip netns exec qrouter-e8f12f7a-6938-4e65-88c4-97e4cb211b27 ip rule 0:      from all lookup local 32766:  from all lookup main 32767:  from all lookup default 1359066113:     from 81.1.180.1/24 lookup 1359066113 root@compute1:/home/s1# ip netns exec qrouter-e8f12f7a-6938-4e65-88c4-97e4cb211b27 ip route list table 1359066113 default via 81.1.180.17 dev qr-517bdba3-b1



这样,当虚机还没有配置浮动IP时,访问外网的话,网络帧的路线为:vm ---- qrouter subnet 1 interface --- SNAT  ---- external port ----- pc 因此,当 router 上连接有多个 subnet 时,qrouter 中也有相应数量的 ip rule 和 routing table:

 

[AppleScript] 纯文本查看 复制代码 ?
1 2 3 4 5 6 7 root@compute1:/home/s1# ip netns exec qrouter-e8f12f7a-6938-4e65-88c4-97e4cb211b27 ip rule 0:      from all lookup local 32766:  from all lookup main 32767:  from all lookup default 1359066113:     from 81.1.180.1/24 lookup 1359066113 1510061057:     from 90.1.180.1/24 lookup 1510061057 1526838273:     from 91.1.180.1/24 lookup 1526838273



4.5.2 给虚机绑定浮动 IP 时

在 qrouter namespace 中:

 

(1)增加 ip rule,通过运行 ['add', 'from', u'81.1.180.18', 'lookup', 16, 'priority', 32768],其中,ID 16 为写死的,其优先级是从 32768 开始到 36768 这个区间内依次分配。 (2)在路由表 16 中添加路由项 default via 169.254.31.239 dev rfp-e8f12f7a-6。这使得虚机访问外网的网络包会通过 rfp-e8f12f7a-6 发到 169.254.31.239。而这个 IP 正是 fip 上 pfr 端口的IP。

 

在 fip namespace 中:

 

(1)增加 route:192.168.1.0/24 dev fg-6b744484-88  proto kernel  scope link  src 192.168.1.119。这使得访问外网机器的网络包能从  fg-6b744484-88 出去。 (2)增加 route:192.168.1.116 via 169.254.31.238 dev fpr-e8f12f7a-6。使得访问虚机的网络包会发给 169.254.31.238,进入 qrouter。这个 router 上的每个浮动 IP 有这么一条 route。

 

配置了两个浮动 IP 的情况下是这样的结果:

 

[AppleScript] 纯文本查看 复制代码 ?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 root@compute1:/home/s1# ip netns exec qrouter-e8f12f7a-6938-4e65-88c4-97e4cb211b27 ip rule 32768: from 81.1.180.18 lookup 16 #去 fip 的 32769: from 90.1.180.8 lookup 16  #去 fip 的 1359066113: from 81.1.180.1/24 lookup 1359066113 #去 snat 的 1510061057: from 90.1.180.1/24 lookup 1510061057 #去 snat 的   root@compute1:/home/s1# ip netns exec qrouter-e8f12f7a-6938-4e65-88c4-97e4cb211b27 ip route list table 16 default via 169.254.31.239 dev rfp-e8f12f7a-6 # route 是一样的 root@compute1:/home/s1# ip netns exec fip-557e9f0c-9c66-46da-b289-218d49c218d2 ip route default via 192.168.1.1 dev fg-6b744484-88 169.254.31.238/31 dev fpr-e8f12f7a-6 proto kernel scope link src 169.254.31.239 192.168.1.0/24 dev fg-6b744484-88 proto kernel scope link src 192.168.1.119 192.168.1.104 via 169.254.31.238 dev fpr-e8f12f7a-6 #每个浮动 IP 一个 route item 192.168.1.116 via 169.254.31.238 dev fpr-e8f12f7a-6

 

这里能看到 qroute 的 ip rule 上,针对一个虚机/子网,有两条 rule,一条查路由表 16 到 fip,另一条查表到 snat。但是,在有浮动 IP 的情况下,前一条策略的优先级数值将小于后后一条的,这就决定了查路由表 16,数据包走 fip。


4.5.3 qrouter 的 main 路由表

main 路由表是为虚拟子网服务的,每个 subnet 对应一条路由规则,使得目的为每个 subnet 的网络包从指定的 qrouter 的 qr interface 上发出。

 

[AppleScript] 纯文本查看 复制代码 ?
1 2 3 4 5 root@compute1:/home/s1# ip netns exec qrouter-e8f12f7a-6938-4e65-88c4-97e4cb211b27 ip route 81.1.180.0/24 dev qr-517bdba3-b1  proto kernel  scope link  src 81.1.180.1 #为到子网 1 中的虚机的网络包做路由 90.1.180.0/24 dev qr-f849ae46-48  proto kernel  scope link  src 90.1.180.1 #为到子网 2 中的虚机的网络包做路由 91.1.180.0/24 dev qr-e47fca31-db  proto kernel  scope link  src 91.1.180.1 169.254.31.238/31 dev rfp-e8f12f7a-6  proto kernel  scope link  src 169.254.31.238 #为从 fip 进来的外网访问内部虚机的网络包做路由


5. Neutron 其它服务与 DVR

5.1 FWaas DVR

DVR 与传统的 FWaas 不兼容,因为它作用于neuron 网络节点上的 virtual router,过滤进出租户网络的网络包。传统的 FWaas 可以参考我的另一篇文章。

 

DVR 实现后,FWaas 需要做相应的修改。

 

官方文档在这里:

 

https://wiki.openstack.org/wiki/Neutron/FWaaS/FWaaS-DVR

 

Spec:https://review.openstack.org/#/c/106225/9/specs/juno/neutron-dvr-fwaas.rst

 

目标:FWaas 保持对 南-北流量做防火墙,而不影响东-西流量。

 

做法:Neutron 网络节点上的 FWaas Agent 安装在 SNAT network namespace 中;计算和网络节点上的 FWaas Agent 安装在 qrouter network namespace 中。


5.2 VPNaas DVR

Juno 版本中 VPNaas 不支持 DVR,只支持传统的 router。Kilo 版本中会实现 VPNaas 对 DVR  的支持。新的 VPN 服务只会在 dvr_snat 节点上的 snat namespace 上运行。


5.3 LBaas 与 DVR

两者之间没有相互依赖关系,所以 DVR 对 LBaas 没有影响。

 

总体情况:

 

<ignore_js_op>[连载型] Neutron 系列 (18): Neutron 分布式虚拟路由【下】


6. 后续版本中 DVR 开发

6.1 Kilo 版本中

  • VPNaaS 对 DVR 的支持
  • 从传统 router 迁移到 DVR router
  • 网络节点上 HA + DVR 支持
  • VLAN 支持


6.2 Liberty 版本中

  • L3 Agent 重构
  • 分布式 DHCP
  • 性能调优
  • 分布式 SNAT

 

    从第五和第六两个章节也可以看出,Juno 版本才添加的 DVR 功能还很不完善,难以满足生产环境的使用要求,主要是因为它还不支持目前实际部署中应该很广泛的 VLAN 组网模式,以及无法解决 HA 和 DVR 共存的问题。可喜的是这两个主要问题会在 K 版本中解决,因此 K 版本中的 DVR 至少可以用来做测试用了。等到 L 版本,实现分布式 DHCP 和 SNAT,以及性能优化以后,离生产环境的要求基本就差不多了。
上一篇:VS2019下使用.net core调试PP支付Checkout集成SmartPaymentButtons一直报错问题分析


下一篇:【PayPal接入(java)】【IPN通知问题】项目实战干货总结记录!