首页 文章 精选 留言 我的

精选列表

搜索[workflow],共826篇文章
优秀的个人博客,低调大师

Openstack Neutron DVR workflow

目前在Juno版本的trunk中已经合入了DVR相关的代码,我的理解是在Juno版本中DVR是一个experimental feature。最好需要稳定一个版本以后再上生产环境。之前写过一篇博文是DVR相关的,当时代码还没有实现,与实际的实现有一些出入。当前的DVR的实现是基于VXLAN的。关于VXLAN的优势,有时间会写一些体会,今天暂且不谈。 建议先看一下以下文档,对DVR有一些了解: https://docs.google.com/presentation/d/1ktCLAdglpKdsC--fQ2F_c2d3X1u-lyRGGUzRu9ITuWo/edit#slide=id.g2b6a14e30_036https://docs.google.com/presentation/d/1ktCLAdglpKdsC--fQ2F_c2d3X1u-lyRGGUzRu9ITuWo/edit#slide=id.g2b6a14e30_030 首先看一下,没有使用DVR的问题在哪里: 从图中可以明显看到东西向和南北向的流量会集中到网络节点,这会使网络节点成为瓶颈。 那如果启用的DVR,情况会变成如下: 对于东西向的流量, 流量会直接在计算节点之间传递。 对于南北向的流量,如果有floating ip,流量就直接走计算节点。如果没有floating ip,则会走网络节点。 我的实验环境如下: 然后起了两个私有网络和一个DVR 路由器,拓扑如下: 注: 可以看到每个网络与DVR连接时有两个接口,以private1为例,有10.0.1.1和10.0.1.6。 可以看到10.0.1.6是centralized_snat的网关,这个地址是在网络节点上的。 10.0.1.1是router_interface_distributed地址,它是在每一个计算节点上的。虚机获取到的默认网关就是这个IP。 虚机情况如下: 注: 虚机privateX-computeY-VM表示,此虚机起在privateX网络,computeY节点上。在compute1节点的两台虚机拥有floating ip。 下面分析三种情况下traffic的是怎么走的: 1. 东西向流量:以private1-compute1-VM和private2-compute2-VM之间的通信为例。 2. 南北向流量: a) 带floating ip, 以private1-compute1-VM对外通信为例。 b) 不带floating ip, 以private1-compute2-VM对外通信为例。 第一种情况 -- 东西向流量 首先我们看一下虚机private1-compute1-VM的IP和路由: 再看一下虚机private2-compute2-VM的IP和路由: 我们在private1-compute1-VM中ping 10.0.2.5(private2-compute2-VM的IP)。 当我们ping了之后,在首先会查询private1-compute1-VM的路由表,会将包发送到网关10.0.1.1。那么会首先会发送10.0.1.1的arp请求。 arp请求会发送到br-int上。 我们可以看到10.0.1.5的port id是4e843b99开头的: 最终会转发到br-int的qvo4e843b99-fb: root@dvr-compute1:~# ovs-vsctl show 67f121bd-cca7-41c2-95ab-23ed85d1305b Bridge br-tun Port patch-int Interface patch-int type: patch options: {peer=patch-tun} Port "vxlan-0ae09f91" Interface "vxlan-0ae09f91" type: vxlan options: {df_default="true", in_key=flow, local_ip="10.224.159.141", out_key=flow, remote_ip="10.224.159.145"} Port "vxlan-0ae09f88" Interface "vxlan-0ae09f88" type: vxlan options: {df_default="true", in_key=flow, local_ip="10.224.159.141", out_key=flow, remote_ip="10.224.159.136"} Port br-tun Interface br-tun type: internal Bridge br-int fail_mode: secure Port "qvo111517d8-c5" tag: 2 Interface "qvo111517d8-c5" Port patch-tun Interface patch-tun type: patch options: {peer=patch-int} Port "qr-001d0ed9-01" tag: 2 Interface "qr-001d0ed9-01" type: internal Port br-int Interface br-int type: internal Port "qr-ddbdc784-d7" tag: 1 Interface "qr-ddbdc784-d7" type: internal Port "qvo4e843b99-fb" tag: 1 Interface "qvo4e843b99-fb" Bridge br-ex Port br-ex Interface br-ex type: internal Port "fg-081d537b-06" Interface "fg-081d537b-06" type: internal ovs_version: "2.0.2" 而端口qvo4e843b99-fb是属于vlan 1的,arp广播包会转发到"qr-ddbdc784-d7"和"patch-tun"。 首先看"qr-ddbdc784-d7",这是interface_distributed的接口: 这个接口是在compute node的的DVR中的: root@dvr-compute1:~# ip netns fip-fbd46644-c70f-4227-a414-862a00cbd1d2 qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa qdhcp-401f678d-4518-446c-9a33-cd2fb054c104 qdhcp-db755841-0764-4a8f-b962-8df008ce6330 root@dvr-compute1:~# ip netns exec qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa ifconfig lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) qr-001d0ed9-01 Link encap:Ethernet HWaddr fa:16:3e:69:b4:05 inet addr:10.0.2.1 Bcast:10.0.2.255 Mask:255.255.255.0 inet6 addr: fe80::f816:3eff:fe69:b405/64 Scope:Link UP BROADCAST RUNNING MTU:1500 Metric:1 RX packets:35 errors:0 dropped:0 overruns:0 frame:0 TX packets:14 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:3510 (3.5 KB) TX bytes:1092 (1.0 KB) qr-ddbdc784-d7 Link encap:Ethernet HWaddr fa:16:3e:66:13:af inet addr:10.0.1.1 Bcast:10.0.1.255 Mask:255.255.255.0 inet6 addr: fe80::f816:3eff:fe66:13af/64 Scope:Link UP BROADCAST RUNNING MTU:1500 Metric:1 RX packets:401 errors:0 dropped:0 overruns:0 frame:0 TX packets:378 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:38224 (38.2 KB) TX bytes:36224 (36.2 KB) rfp-0fbb351e-a Link encap:Ethernet HWaddr ea:5c:56:9a:36:9c inet addr:169.254.31.28 Bcast:0.0.0.0 Mask:255.255.255.254 inet6 addr: fe80::e85c:56ff:fe9a:369c/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:12 errors:0 dropped:0 overruns:0 frame:0 TX packets:12 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1116 (1.1 KB) TX bytes:1116 (1.1 KB) 接口qr-ddbdc784-d7拥有10.0.1.1。所以他会响应ARP请求。 回过头来看"patch-tun", ARP请求转发到这个接口后,会转发到br-tun。看一下br-tun上的flow, 目前我们只需要看红色部分,他会将目标地址为10.0.1.1的ARP请求丢弃: root@dvr-compute1:~# ovs-ofctl dump-flows br-tun NXST_FLOW reply (xid=0x4): 。。。 cookie=0x0, duration=64720.432s, table=1, n_packets=4, n_bytes=168, idle_age=64607, priority=3,arp,dl_vlan=1,arp_tpa=10.0.1.1 actions=drop cookie=0x0, duration=62666.766s, table=1, n_packets=2, n_bytes=84, idle_age=62576, priority=3,arp,dl_vlan=2,arp_tpa=10.0.2.1 actions=drop 。。。 回到我们虚机,当获取到了10.0.1.1的MAC地址后,会发出如下的包: Dest IP: 10.0.2.5 Souce IP: 10.0.1.5 Dest MAC: MAC of 10.0.1.1 Source MAC: MAC of 10.0.1.5 之后包被转发到compute1的qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa的namespace: 这里利用了内核的高级路由到了,首先看一下ip rule: root@dvr-compute1:~# ip netns exec qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa ip rule 0: from all lookup local 32766: from all lookup main 32767: from all lookup default 32768: from 10.0.1.5 lookup 16 32769: from 10.0.2.3 lookup 16 167772417: from 10.0.1.1/24 lookup 167772417 167772417: from 10.0.1.1/24 lookup 167772417 167772673: from 10.0.2.1/24 lookup 167772673 可以看到会先查找main表: root@dvr-compute1:~# ip netns exec qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa ip route list table main 10.0.1.0/24 dev qr-ddbdc784-d7 proto kernel scope link src 10.0.1.1 10.0.2.0/24 dev qr-001d0ed9-01 proto kernel scope link src 10.0.2.1 169.254.31.28/31 dev rfp-0fbb351e-a proto kernel scope link src 169.254.31.28 在main表中满足以下路由: 10.0.2.0/24 dev qr-001d0ed9-01 proto kernel scope link src 10.0.2.1 因此会从qr-001d0ed9-01转发出去。 之后需要去查询10.0.2.5的MAC地址, MAC是由neutron使用静态ARP的方式设定的: root@dvr-compute1:~# ip netns exec qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa ip nei 10.0.1.5 dev qr-ddbdc784-d7 lladdr fa:16:3e:da:75:6d PERMANENT 10.0.2.3 dev qr-001d0ed9-01 lladdr fa:16:3e:a4:fc:98 PERMANENT 10.0.1.6 dev qr-ddbdc784-d7 lladdr fa:16:3e:9f:55:67 PERMANENT 10.0.2.2 dev qr-001d0ed9-01 lladdr fa:16:3e:13:55:66 PERMANENT 10.0.2.5 dev qr-001d0ed9-01 lladdr fa:16:3e:51:99:b8 PERMANENT 10.0.1.4 dev qr-ddbdc784-d7 lladdr fa:16:3e:da:e3:6e PERMANENT 10.0.1.7 dev qr-ddbdc784-d7 lladdr fa:16:3e:14:b8:ec PERMANENT 169.254.31.29 dev rfp-0fbb351e-a lladdr 42:0d:9f:49:63:c6 STALE 由于Neutron知道所有虚机的信息,因此他可以事先设定好静态ARP。 至此,我们的ICMP包会变成以下形式从qr-001d0ed9-01转发出去: Dest IP: 10.0.2.5 Souce IP: 10.0.1.5 Dest MAC: MAC of 10.0.2.5 Source MAC: MAC of 10.0.2.1 当包转发到"br-tun"后,进开始查询openflow表。 首先我们看一下br-tun的接口状况: root@dvr-compute1:~# ovs-ofctl show br-tun OFPT_FEATURES_REPLY (xid=0x2): dpid:0000e2b7aa5da34a n_tables:254, n_buffers:256 capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP actions: OUTPUT SET_VLAN_VID SET_VLAN_PCP STRIP_VLAN SET_DL_SRC SET_DL_DST SET_NW_SRC SET_NW_DST SET_NW_TOS SET_TP_SRC SET_TP_DST ENQUEUE 1(patch-int): addr:76:ae:9f:b3:bf:c6 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max 3(vxlan-0ae09f88): addr:92:61:e9:43:dd:99 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max 4(vxlan-0ae09f91): addr:2e:cc:c0:4a:4e:d4 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max LOCAL(br-tun): addr:e2:b7:aa:5d:a3:4a config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0 首先我们看一下br-tun的flowtable,首先会进入table 0,由于包是从br-int发过来的,因此in_port是patch-int(1),之后会查询表1: cookie=0x0, duration=66172.51s, table=0, n_packets=58, n_bytes=5731, idle_age=20810, hard_age=65534, priority=1,in_port=3 actions=resubmit(,4) cookie=0x0, duration=67599.526s, table=0, n_packets=273, n_bytes=24999, idle_age=1741, hard_age=65534, priority=1,in_port=1 actions=resubmit(,1) cookie=0x0, duration=64437.052s, table=0, n_packets=28, n_bytes=2980, idle_age=20799, priority=1,in_port=4 actions=resubmit(,4) cookie=0x0, duration=67601.704s, table=0, n_packets=5, n_bytes=390, idle_age=65534, hard_age=65534, priority=0 actions=drop 表1,这张表中会丢弃目标地址是interface_distributed接口的ARP和目的MAC是interface_distributed的包。以防止虚机发送给本地IR的包不会被转发到网络中。 我们的ICMP包会命中一下flow,它会把源MAC地址改为全局唯一和计算节点绑定的MAC: cookie=0x0, duration=66135.811s, table=1, n_packets=140, n_bytes=13720, idle_age=65534, hard_age=65534, priority=1,dl_vlan=1,dl_src=fa:16:3e:66:13:af actions=mod_dl_src:fa:16:3f:fe:49:e9,resubmit(,2) cookie=0x0, duration=64082.141s, table=1, n_packets=2, n_bytes=200, idle_age=64081, priority=1,dl_vlan=2,dl_src=fa:16:3e:69:b4:05 actions=mod_dl_src:fa:16:3f:fe:49:e9,resubmit(,2) cookie=0x0, duration=66135.962s, table=1, n_packets=1, n_bytes=98, idle_age=65301, hard_age=65534, priority=2,dl_vlan=1,dl_dst=fa:16:3e:66:13:af actions=drop cookie=0x0, duration=64082.297s, table=1, n_packets=0, n_bytes=0, idle_age=64082, priority=2,dl_vlan=2,dl_dst=fa:16:3e:69:b4:05 actions=drop cookie=0x0, duration=66136.115s, table=1, n_packets=4, n_bytes=168, idle_age=65534, hard_age=65534, priority=3,arp,dl_vlan=1,arp_tpa=10.0.1.1 actions=drop cookie=0x0, duration=64082.449s, table=1, n_packets=2, n_bytes=84, idle_age=63991, priority=3,arp,dl_vlan=2,arp_tpa=10.0.2.1 actions=drop cookie=0x0, duration=67599.22s, table=1, n_packets=123, n_bytes=10687, idle_age=1741, hard_age=65534, priority=0 actions=resubmit(,2) 这个全局唯一和计算节点绑定的MAC地址,是由neutron全局分配的,数据库中可以看到这个MAC是每个host一个: 它的base MAC是可以在neutron.conf中配置的: 继续查询流表2,表2是VXLAN表,如果是广播包就会查询表22,如果是单播包就查询表20: cookie=0x0, duration=67601.554s, table=2, n_packets=176, n_bytes=16981, idle_age=20810, hard_age=65534, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20) cookie=0x0, duration=67601.406s, table=2, n_packets=92, n_bytes=7876, idle_age=1741, hard_age=65534, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,22) ICMP包是单播包,因此会查询表20,由于开启了L2 pop功能,在表20中会事先学习到应该转发到哪个VTEP。 cookie=0x0, duration=64076.431s, table=20, n_packets=0, n_bytes=0, idle_age=64076, priority=2,dl_vlan=2,dl_dst=fa:16:3e:13:55:66 actions=strip_vlan,set_tunnel:0x3eb,output:3 cookie=0x0, duration=66130.899s, table=20, n_packets=152, n_bytes=14728, idle_age=65534, hard_age=65534, priority=2,dl_vlan=1,dl_dst=fa:16:3e:9f:55:67 actions=strip_vlan,set_tunnel:0x3e9,output:3 cookie=0x0, duration=66560.59s, table=20, n_packets=7, n_bytes=552, idle_age=65534, hard_age=65534, priority=2,dl_vlan=1,dl_dst=fa:16:3e:da:e3:6e actions=strip_vlan,set_tunnel:0x3e9,output:2 cookie=0x0, duration=64436.717s, table=20, n_packets=0, n_bytes=0, idle_age=64436, priority=2,dl_vlan=1,dl_dst=fa:16:3e:14:b8:ec actions=strip_vlan,set_tunnel:0x3e9,output:4 cookie=0x0, duration=64015.308s, table=20, n_packets=0, n_bytes=0, idle_age=64015, priority=2,dl_vlan=2,dl_dst=fa:16:3e:51:99:b8 actions=strip_vlan,set_tunnel:0x3eb,output:4 cookie=0x0, duration=64032.699s, table=20, n_packets=9, n_bytes=917, idle_age=20810, priority=2,dl_vlan=2,dl_dst=fa:16:3e:bb:cf:66 actions=strip_vlan,set_tunnel:0x3eb,output:3 cookie=0x0, duration=67600.802s, table=20, n_packets=8, n_bytes=784, idle_age=65534, hard_age=65534, priority=0 actions=resubmit(,22) 注: 由于L2 POP并不是本文的重点。因此不在此细说。如果有兴趣可以看以下blog: http://assafmuller.com/category/overlays/ 此时包会变成如下形式: Dest IP: 10.0.2.5 Souce IP: 10.0.1.5 Dest MAC: MAC of 10.0.2.5 Source MAC:fa:16:3f:fe:49:e9 之后包会从port 4发出: root@dvr-compute1:~# ovs-vsctl show 67f121bd-cca7-41c2-95ab-23ed85d1305b Bridge br-tun Port patch-int Interface patch-int type: patch options: {peer=patch-tun} Port "vxlan-0ae09f91" Interface "vxlan-0ae09f91" type: vxlan options: {df_default="true", in_key=flow, local_ip="10.224.159.141", out_key=flow, remote_ip="10.224.159.145"} Port "vxlan-0ae09f88" Interface "vxlan-0ae09f88" type: vxlan options: {df_default="true", in_key=flow, local_ip="10.224.159.141", out_key=flow, remote_ip="10.224.159.136"} Port br-tun Interface br-tun type: internal OVS会将此包进行VXLAN封装,将L2帧分装到VXLAN中,包头如下: OVS会将此包进行VXLAN封装,将L2帧分装到VXLAN中,包头如下: 本文并不想具体讨论VXLAN是如何封装的,简单的说就是讲二层帧封到了一个UDP包中。 之后compute2会收到这个包,在compute2的br-tun上查询流表: 首先看一下接口情况: root@dvr-compute2:~# ovs-ofctl show br-tun OFPT_FEATURES_REPLY (xid=0x2): dpid:000062e9fb8b8f42 n_tables:254, n_buffers:256 capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP actions: OUTPUT SET_VLAN_VID SET_VLAN_PCP STRIP_VLAN SET_DL_SRC SET_DL_DST SET_NW_SRC SET_NW_DST SET_NW_TOS SET_TP_SRC SET_TP_DST ENQUEUE 1(patch-int): addr:02:dc:f1:96:db:bd config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max 3(vxlan-0ae09f88): addr:b6:4b:d0:83:07:52 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max 4(vxlan-0ae09f8d): addr:12:e5:36:2c:1a:36 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max LOCAL(br-tun): addr:62:e9:fb:8b:8f:42 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0 在table0中可以看到,如果包是从外部发来的就会去查询表4: cookie=0x0, duration=66293.658s, table=0, n_packets=31, n_bytes=3936, idle_age=22651, hard_age=65534, priority=1,in_port=3 actions=resubmit(,4) cookie=0x0, duration=69453.368s, table=0, n_packets=103, n_bytes=9360, idle_age=22651, hard_age=65534, priority=1,in_port=1 actions=resubmit(,1) cookie=0x0, duration=66292.808s, table=0, n_packets=20, n_bytes=1742, idle_age=3598, hard_age=65534, priority=1,in_port=4 actions=resubmit(,4) cookie=0x0, duration=69455.675s, table=0, n_packets=5, n_bytes=390, idle_age=65534, hard_age=65534, priority=0 actions=drop 在表4中,会将tun_id对应的改为本地vlan id,之后查询表9: cookie=0x0, duration=65937.871s, table=4, n_packets=32, n_bytes=3653, idle_age=22651, hard_age=65534, priority=1,tun_id=0x3eb actions=mod_vlan_vid:3,resubmit(,9) cookie=0x0, duration=66294.732s, table=4, n_packets=19, n_bytes=2025, idle_age=3598, hard_age=65534, priority=1,tun_id=0x3e9 actions=mod_vlan_vid:2,resubmit(,9) cookie=0x0, duration=69455.115s, table=4, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=0 actions=drop 在表9中,如果发现包的源地址是全局唯一并与计算节点绑定的MAC地址,就将其转发到br-int: cookie=0x0, duration=69453.507s, table=9, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=1,dl_src=fa:16:3f:fe:49:e9 actions=output:1 cookie=0x0, duration=69453.782s, table=9, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=1,dl_src=fa:16:3f:72:3f:a7 actions=output:1 cookie=0x0, duration=69453.23s, table=9, n_packets=56, n_bytes=6028, idle_age=3598, hard_age=65534, priority=0 actions=resubmit(,10) 由于我们的源MAC为fa:16:3f:fe:49:e9,我们的ICMP包就被转发到了br-int,之后查询br-int的流表: 在表0中,如果是全局唯一并与计算节点绑定的MAC地址就查询表1,否则就正常转发: cookie=0x0, duration=70039.903s, table=0, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=2,in_port=6,dl_src=fa:16:3f:72:3f:a7 actions=resubmit(,1) cookie=0x0, duration=70039.627s, table=0, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=2,in_port=6,dl_src=fa:16:3f:fe:49:e9 actions=resubmit(,1) cookie=0x0, duration=70040.053s, table=0, n_packets=166, n_bytes=15954, idle_age=4184, hard_age=65534, priority=1 actions=NORMAL 在表1中,事先设定好了flow,如果目的MAC是发送给private2-compute2-VM,就将源MAC改为private2的网关MAC地址: cookie=0x0, duration=66458.695s, table=1, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=4,dl_vlan=3,dl_dst=fa:16:3e:51:99:b8 actions=strip_vlan,mod_dl_src:fa:16:3e:69:b4:05,output:12 cookie=0x0, duration=66877.515s, table=1, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=4,dl_vlan=2,dl_dst=fa:16:3e:14:b8:ec actions=strip_vlan,mod_dl_src:fa:16:3e:66:13:af,output:9 cookie=0x0, duration=66877.369s, table=1, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=2,ip,dl_vlan=2,nw_dst=10.0.1.0/24 actions=strip_vlan,mod_dl_src:fa:16:3e:66:13:af,output:9 cookie=0x0, duration=66458.559s, table=1, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=2,ip,dl_vlan=3,nw_dst=10.0.2.0/24 actions=strip_vlan,mod_dl_src:fa:16:3e:69:b4:05,output:12 还可以看到下面两条rule是网段flow的rule,他们的output是一个list,会将此包转发到所有连接到此network上。 如果所有的虚机的rule都已经事先设定好的话,这两条rule应该并没有实际作用,等到代码稳定后,这两条rule应该会被删除。 经过br-int的流表后,包会变成如下形式: Dest IP: 10.0.2.5 Souce IP: 10.0.1.5 Dest MAC: MAC of 10.0.2.5 Source MAC:fa:16:3e:69:b4:05(MAC of 10.0.2.1 网关地址) 至此,虚机private2-compute2-VM就会收到来自private1-compute1-VM的包了。从通信的过程可以看到,跨网段的东西向流量没有经过网络节点。 第二种情况 -- 南北向流量(虚机有floating ip) 以虚机private1-compute1-VM对外通信为例,此虚机拥有floating ip: 比如我们在虚机中ping 8.8.8.8 。首先在虚机中查询路由,和第一种情况一样,虚机会发送给网关。发送的包如下: Dest IP: 8.8.8.8 Souce IP: 10.0.1.5 Dest MAC: MAC of 10.0.1.1 Source MAC: MAC of 10.0.1.5 查看ip rule: root@dvr-compute1:~# ip netns exec qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa ip rule 0: from all lookup local 32766: from all lookup main 32767: from all lookup default 32768: from 10.0.1.5 lookup 16 32769: from 10.0.2.3 lookup 16 167772417: from 10.0.1.1/24 lookup 167772417 167772417: from 10.0.1.1/24 lookup 167772417 167772673: from 10.0.2.1/24 lookup 167772673 在main表中没有合适的路由: root@dvr-compute1:~# ip netns exec qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa ip route list table main 10.0.1.0/24 dev qr-ddbdc784-d7 proto kernel scope link src 10.0.1.1 10.0.2.0/24 dev qr-001d0ed9-01 proto kernel scope link src 10.0.2.1 169.254.31.28/31 dev rfp-0fbb351e-a proto kernel scope link src 169.254.31.28 由于包是从10.0.1.5发来的之后会查看table 16: root@dvr-compute1:~# ip netns exec qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa ip route list table 16 default via 169.254.31.29 dev rfp-0fbb351e-a 包会命中这条路由。 路由之后会通过netfilter的POSTROUTING链中进行SNAT: root@dvr-compute1:~# ip netns exec qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa iptables -nvL -t nat 。。。 Chain neutron-l3-agent-float-snat (1 references) pkts bytes target prot opt in out source destination 0 0 SNAT all -- * * 10.0.2.3 0.0.0.0/0 to:172.24.4.7 0 0 SNAT all -- * * 10.0.1.5 0.0.0.0/0 to:172.24.4.5 。。。 之后就可以看到包会通过rfp-0fbb351e-a发送给169.254.31.29。 端口rfp-0fbb351e-a和fpr-0fbb351e-a是一对veth pair。在fip namespace中你可以看到这个接口: root@dvr-compute1:~# ip netns exec fip-fbd46644-c70f-4227-a414-862a00cbd1d2 ifconfig fg-081d537b-06 Link encap:Ethernet HWaddr fa:16:3e:a4:eb:6b inet addr:172.24.4.6 Bcast:172.24.4.255 Mask:255.255.255.0 inet6 addr: fe80::f816:3eff:fea4:eb6b/64 Scope:Link UP BROADCAST RUNNING MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:50 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:2512 (2.5 KB) fpr-0fbb351e-a Link encap:Ethernet HWaddr 42:0d:9f:49:63:c6 inet addr:169.254.31.29 Bcast:0.0.0.0 Mask:255.255.255.254 inet6 addr: fe80::400d:9fff:fe49:63c6/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:12 errors:0 dropped:0 overruns:0 frame:0 TX packets:12 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1116 (1.1 KB) TX bytes:1116 (1.1 KB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:13 errors:0 dropped:0 overruns:0 frame:0 TX packets:13 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1250 (1.2 KB) TX bytes:1250 (1.2 KB) 到了fip的namespace之后,会查询路由, 这里有通往公网的默认路由: root@dvr-compute1:~# ip netns exec fip-fbd46644-c70f-4227-a414-862a00cbd1d2 ip route default via 172.24.4.1 dev fg-081d537b-06 169.254.31.28/31 dev fpr-0fbb351e-a proto kernel scope link src 169.254.31.29 172.24.4.0/24 dev fg-081d537b-06 proto kernel scope link src 172.24.4.6 172.24.4.5 via 169.254.31.28 dev fpr-0fbb351e-a 172.24.4.7 via 169.254.31.28 dev fpr-0fbb351e-a 通过fg-081d537b-06 发送到br-ex。这是从虚机发送到公网的过程。 反过来,从外网发起连接到虚机时,在fip的namespace会做arp代理: root@dvr-compute1:~# ip netns exec fip-fbd46644-c70f-4227-a414-862a00cbd1d2 sysctl net.ipv4.conf.fg-081d537b-06.proxy_arp net.ipv4.conf.fg-081d537b-06.proxy_arp = 1 可以看到接口的arp代理是打开的,对于floating ip 有以下两条路由: root@dvr-compute1:~# ip netns exec fip-fbd46644-c70f-4227-a414-862a00cbd1d2 ip route 。。。 172.24.4.5 via 169.254.31.28 dev fpr-0fbb351e-a 172.24.4.7 via 169.254.31.28 dev fpr-0fbb351e-a 。。。 ARP会去通过VETH Pair到IR的namespace中去查询,在IR中可以看到,接口rfp-0fbb351e-a配置了floating ip: root@dvr-compute1:~# ip netns exec qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: rfp-0fbb351e-a: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether ea:5c:56:9a:36:9c brd ff:ff:ff:ff:ff:ff inet 169.254.31.28/31 scope global rfp-0fbb351e-a valid_lft forever preferred_lft forever inet 172.24.4.5/32 brd 172.24.4.5 scope global rfp-0fbb351e-a valid_lft forever preferred_lft forever inet 172.24.4.7/32 brd 172.24.4.7 scope global rfp-0fbb351e-a valid_lft forever preferred_lft forever inet6 fe80::e85c:56ff:fe9a:369c/64 scope link valid_lft forever preferred_lft forever 17: qr-ddbdc784-d7: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default link/ether fa:16:3e:66:13:af brd ff:ff:ff:ff:ff:ff inet 10.0.1.1/24 brd 10.0.1.255 scope global qr-ddbdc784-d7 valid_lft forever preferred_lft forever inet6 fe80::f816:3eff:fe66:13af/64 scope link valid_lft forever preferred_lft forever 19: qr-001d0ed9-01: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default link/ether fa:16:3e:69:b4:05 brd ff:ff:ff:ff:ff:ff inet 10.0.2.1/24 brd 10.0.2.255 scope global qr-001d0ed9-01 valid_lft forever preferred_lft forever inet6 fe80::f816:3eff:fe69:b405/64 scope link valid_lft forever preferred_lft forever 因此fip的namespace会对这两个floating ip进行ARP回应。 外部发起目标地址为floating ip的请求后,fip会将其转发到IR中,IR的RPOROUTING链中规则如下: root@dvr-compute1:~# ip netns exec qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa iptables -nvL -t nat 。。。 Chain neutron-l3-agent-PREROUTING (1 references) pkts bytes target prot opt in out source destination 0 0 REDIRECT tcp -- * * 0.0.0.0/0 169.254.169.254 tcp dpt:80 redir ports 9697 0 0 DNAT all -- * * 0.0.0.0/0 172.24.4.7 to:10.0.2.3 0 0 DNAT all -- * * 0.0.0.0/0 172.24.4.5 to:10.0.1.5 。。。 这条DNAT规则会将floating ip地址转换为内部地址,之后进行路由查询: root@dvr-compute1:~# ip netns exec qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa ip route 10.0.1.0/24 dev qr-ddbdc784-d7 proto kernel scope link src 10.0.1.1 10.0.2.0/24 dev qr-001d0ed9-01 proto kernel scope link src 10.0.2.1 169.254.31.28/31 dev rfp-0fbb351e-a proto kernel scope link src 169.254.31.28 目的地址是10.0.1.0/24网段的,因此会从qr-ddbdc784-d7转发出去。之后就会转发到br-int再到虚机。 第三种情况 -- 南北向流量(虚机没有floating ip) 在虚机没有floating ip的情况下,从虚机发出的包会首先到IR,IR中查询路由: root@dvr-compute1:~# ip netns exec qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa ip rule 0: from all lookup local 32766: from all lookup main 32767: from all lookup default 32768: from 10.0.1.5 lookup 16 32769: from 10.0.2.3 lookup 16 167772417: from 10.0.1.1/24 lookup 167772417 167772417: from 10.0.1.1/24 lookup 167772417 167772673: from 10.0.2.1/24 lookup 167772673 会先查询main表,之后查询167772417表。 root@dvr-compute1:~# ip netns exec qrouter-0fbb351e-a65b-4790-a409-8fb219ce16aa ip route list table 167772417 default via 10.0.1.6 dev qr-ddbdc784-d7 这个表会将其转发给10.0.1.6,而这个IP就是在network node上的router_centralized_snat接口。 在network node的snat namespace中,我们可以看到这个接口: stack@dvr-controller:/root$ sudo ip netns exec snat-0fbb351e-a65b-4790-a409-8fb219ce16aa ifconfig lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) qg-4d15b7f6-cb Link encap:Ethernet HWaddr fa:16:3e:24:0b:6b inet addr:172.24.4.4 Bcast:172.24.4.255 Mask:255.255.255.0 inet6 addr: fe80::f816:3eff:fe24:b6b/64 Scope:Link UP BROADCAST RUNNING MTU:1500 Metric:1 RX packets:5 errors:0 dropped:0 overruns:0 frame:0 TX packets:144 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:210 (210.0 B) TX bytes:13320 (13.3 KB) sg-427653e4-a3 Link encap:Ethernet HWaddr fa:16:3e:9f:55:67 inet addr:10.0.1.6 Bcast:10.0.1.255 Mask:255.255.255.0 inet6 addr: fe80::f816:3eff:fe9f:5567/64 Scope:Link UP BROADCAST RUNNING MTU:1500 Metric:1 RX packets:167 errors:0 dropped:0 overruns:0 frame:0 TX packets:52 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:16260 (16.2 KB) TX bytes:4460 (4.4 KB) sg-5df1ec71-d3 Link encap:Ethernet HWaddr fa:16:3e:13:55:66 inet addr:10.0.2.2 Bcast:10.0.2.255 Mask:255.255.255.0 inet6 addr: fe80::f816:3eff:fe13:5566/64 Scope:Link UP BROADCAST RUNNING MTU:1500 Metric:1 RX packets:34 errors:0 dropped:0 overruns:0 frame:0 TX packets:12 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:3412 (3.4 KB) TX bytes:952 (952.0 B) stack@dvr-controller:/root$ sudo ip netns exec snat-0fbb351e-a65b-4790-a409-8fb219ce16aa iptables -nvL -t nat 。。。 Chain neutron-l3-agent-snat (1 references) pkts bytes target prot opt in out source destination 0 0 SNAT all -- * * 10.0.1.0/24 0.0.0.0/0 to:172.24.4.4 0 0 SNAT all -- * * 10.0.2.0/24 0.0.0.0/0 to:172.24.4.4 。。。 这里就和以前的L3类似,会将没有floating ip的包SNAT成一个172.24.4.4(DVR的网关臂)。这个过程是和以前L3类似的,不再累述。 stack@dvr-controller:/root$ sudo ip netns exec snat-0fbb351e-a65b-4790-a409-8fb219ce16aa iptables -nvL -t nat 。。。 Chain neutron-l3-agent-snat (1 references) pkts bytes target prot opt in out source destination 0 0 SNAT all -- * * 10.0.1.0/24 0.0.0.0/0 to:172.24.4.4 0 0 SNAT all -- * * 10.0.2.0/24 0.0.0.0/0 to:172.24.4.4 。。。 这里就和以前的L3类似,会将没有floating ip的包SNAT成一个172.24.4.4(DVR的网关臂)。这个过程是和以前L3类似的,不再累述。 本文转自feisky博客园博客,原文链接:http://www.cnblogs.com/feisky/p/4040470.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

.net core 工作流 WorkFlow 流程

WikeFlow官网:http://www.wikesoft.com WikeFlow2.0帮助文档:http://wikeflowhelp.wikesoft.com/ WikeFlow2.0简介 为什么我们要自已开发流程引擎? .net 平台下面有一些三方的流程引擎,这些流程引擎很多都不好用或者是很难满足用户的业务需求,功能臃肿导致学习难度大,条件限制多导致集成难度大或者根本就没办法集成,无法使用客户自己的权限系统跑流程,针对于行业现状,我们才决定自己研发流程引擎。 1、WikeFlow2.0几乎能满足各行各业的流程审批业务场景,流程引擎最大的优点:小巧,灵活,高度可扩展性,集成容易。 2、WikeFlow2.0的核心团队具有10年以上开发经验,具有非常丰富的流程引擎相关经验。 3、WikeFlow2.0总结了国内外的流程引擎,取长补短,WikeFlow2.0一直也在收集客户的反馈并不断进化。 4、WikeFlow2.0经过公司多个项目的实际运用中不断修改并完善后,我们决定独立成一个产品,产品具体很强的实践经验。 5、WikeFlow2.0有两个版本:支持.Net FrameWork的版本和支持.net Core 的版本,后期可能会支持Java(WikeFlow For Java版本) 6、WikeFlow2.0并不是对WikeFlow的升级,而是完全的重构,如你的项目在使用WikeFlow,需要自行调整代码。 7、WikeFlow2.0的流程审批是支持WinForm程序的,你只需要将每个节点的待办路径设置为你的Winform窗体就可以了。 如果你需要在Winform程序里面进行流程设计,,则在Winform程序里面加一个WebBrower,将流程设计的Url加入到WebBrower。 WikeFlow2.0 主要功能 1、流程审批,一般的业务审批 2、流程会签,一个任务节点多人审批 3、流程驳回,流程不同意 4、流程转办,流程从一个人转交给另外的人处理 5、流程传阅,将流程传递给其他的人查阅 6、流程撤回,提交后可以撤回 7、流程附件,支持节点附件 8、流程审批中修改业务数据 9、流程审批中业务数据权限设 WikeFlow2.0 系统框架 WikeFlow2.0同时有支持.net framework和.net core 的两个版本,WikeFlow for java正在开发中。 后端框架 .net framework asp.net Mvc5和asp.net Webform ORM:EntityFrameWork6.0 后端框架 .net core .net core Mvc ORM:EFCore/Sqlsugar MVC前端框架: bootstrap3,jqGrid,jQuery,layer,jsPlumb等。 Vue3前端框架: Vue3、Element plus、Axios、Vite等。 容易集成: WikeFlow2集成使用方便,如何集成到你的项目中,请查看《如何集成WikeFlow2.0》 WikeFlow2.0 多数据库支持 同时支持多数据库,MySql,Oracle,SQLServer,达梦、人大金仓。 .net framework版本只需要修改Web.config里面的数据库连接字符串就可以实现不同数据库之间的轻松切换。 .net core版本只需要修改StartUp.cs里面的ConfigureServices中的代码就可以实现不同数据库之间的轻松切换。

优秀的个人博客,低调大师

DRYCC Workflow v1.6.0 版本发布

RYCC 工作流是一个开源的超融合 PAAS 云,它基于 kubernetes、servicebroker 等技术,为运维人员、开发人员添加提供了一个方便快捷的工具,使应用程序的部署和管理变得容易。 DRYCC 工作流包括通过 git push 从源代码构建和部署的功能、简单的应用程序配置、创建和回滚发布、管理域名和 SSL 证书、提供无缝边缘路由、聚合日志以及与团队共享应用程序。 安装方法 首先准备一台纯净的 ubuntu/centos 主机,我们假设它的外网 IP 为209.119.4.8,系统为 ubuntu20.04,假设使用 nip.io 作为域名服务,我们需要导入如下环境变量: export CHANNEL=stable export DRYCC_REGISTRY=registry.drycc.cc export PLATFORM_DOMAIN=43.129.186.72.nip.io export DRYCC_ADMIN_USERNAME=admin export DRYCC_ADMIN_PASSWORD=admin export MINIO_PERSISTENCE_SIZE=60Gi 如果主机在国内,则需要增加如下环境变量做镜像加速: export INSTALL_DRYCC_MIRROR=cn 如果主机在内网,不存在外网 IP,则需要关闭 ACME 自动证书: export CERT_MANAGER_ENABLED=false 安装系统软件 apt-get update apt-get install curl haproxy nfs-common open-iscsi 安装 DRYCC curl -sfL https://www.drycc.cc/install.sh | bash - 发布内容 Drycc 从 21 年 9 月份到现在,过去了一年整整时间,在过去的一年里发生了很多激动人心的变化,从存储到网络Drycc做到了真正统一,Drycc storage组件支持对象存储和多写卷存储,因此不再需要诸如longhorn等外部的存储组件;同时将drycc的所有组件均支持云原生部署,本次主要更新如下: * Database组件中引入Patron,支持高可用、多副本、故障自动切换。 * Influxdb组件支持多写方案,很简陋的实现,虽然不完美,但是可以工作。 * drycc-cli支持远程执行命令,从此以后小伙伴们不用再羡慕`kubectl exec`了。 * drycc-cli支持持续输出日志流,小伙伴们也不用羡慕`tail -f`了,drycc也能做到。 时光飞逝,由于时隔整整一年的时间,有太多的变化,真是一言难尽;Drycc,未来已来,你来不来? 小编先不要审核通过,我没发现草稿功能,这个是先保存草稿用的。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册