OpenStack网络配置:一个tenant, 2个虚机
- Type driver: GRE, Mechanism driver: OVS
- 一个public network: ext-net 和相应的subnet ext-subnet
- 一个VM network:demo-net 和相应的subnet:demo-subnet
- 一个router连接ext-subnet和demo-subnet
1、Compute 节点上networking组件
下面会用到OVS的两个重要命令:
- ovs-vsctl: 查询和更新ovs-vswitchd的配置
- ovs-ofctl: 查询和控制OpenFlow交换机和控制器
首先查询Compute节点上ovs-vswitchd的配置的配置:
root@compute1:/var/lib/nova# ovs-vsctl show
205a13a2-1ad6-4ae0-8c84-abed97444aa9
Bridge br-int //OVS integration 桥 br-int
fail_mode: secure
Port "qvo37b25c08-e8" //端口,用来连接一个虚机网卡的TAP设备所连接的linux bridge
tag: 1
Interface "qvo37b25c08-e8"
Port patch-tun //端口,用来连接桥br-tun
Interface patch-tun
type: patch
options: {peer=patch-int} //和桥 br-tun上的patch-int是对等端口
Port br-int
Interface br-int
type: internal
Port "qvo155845ae-5e" //端口,用来连接另一个虚机网卡的TAP设备所连接的linux bridge
tag: 1
Interface "qvo155845ae-5e"
Bridge br-tun //OVS Tunnel 桥br-tun
Port br-tun
Interface br-tun
type: internal
Port patch-int //端口patch-int,用来连接桥br-int
Interface patch-int
type: patch
options: {peer=patch-tun}
Port "gre-0a000115" //端口,连接GRE Tunnel
Interface "gre-0a000115"
type: gre
options: {df_default="true", in_key=flow, local_ip="10.0.1.31", out_key=flow, remote_ip="10.0.1.21"}
ovs_version: "2.0.2" //GRE Tunnel是点到点之间建立的,这头的IP为10.0.1.31,那头的IP地址为 10.0.1.21
继续看桥 br-tun:
root@compute1:/var/lib/nova# ovs-ofctl show br-tun
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000f6b428614747
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:3e:7b:d5:fa:26:8d //端口 patch-int的ID 是 1
config: 0
state: 0
speed: 0 Mbps now, 0 Mbps max
2(gre-0a000115): addr:2a:26:b2:99:f3:5a //端口 gre-0a000115的ID 是 2
config: 0
state: 0
speed: 0 Mbps now, 0 Mbps max
LOCAL(br-tun): addr:f6:b4:28:61:47:47
config: 0
state: 0
speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
每个虚机有个虚机网卡 eth0,eth0和host上的一个TAP设备连接,该TAP设备直接挂载在一个Linux Bridge上,该Linux Bridge和OVS integration bridge br-int相连。其实理想情况下,TAP设备能和OVS Integration Bridge 直接相连就好了,但是,因为OpenStack实现Security Group的需要,这里要多加一层Linux bridge。OpenStack使用Linux TAP设备上的iptables来实现Security Group规则,而OVS不支持直接和br-int桥相连的TAP设备上的iptables。通过查看虚机的libvirt XML定义文件 /var/lib/nova/instances/<instance-id>/libvirt.xml可以看出来虚机所连接的TAP设备:
<interface type="bridge">
<mac address="fa:16:3e:fe:c7:87"/> //
<source bridge="qbr37b25c08-e8"/> //虚机TAP设备所挂接的linux bridge
<target dev="tap37b25c08-e8” /> //虚机所连接的interface
</interface>
通过以上信息,我们可以画出compute 节点上的网络组建图:
2. Neutron使用TAP设备的iptables来实现Security groups
查看第一个虚机的TAP设备上的iptables:
root@compute1:/var/lib/nova# iptables -S | grep tap37b25c08-e8
-A neutron-openvswi-FORWARD -m physdev --physdev-out tap37b25c08-e8 --physdev-is-bridged -j neutron-openvswi-sg-chain
-A neutron-openvswi-FORWARD -m physdev --physdev-in tap37b25c08-e8 --physdev-is-bridged -j neutron-openvswi-sg-chain
-A neutron-openvswi-INPUT -m physdev --physdev-in tap37b25c08-e8 --physdev-is-bridged -j neutron-openvswi-o37b25c08-e
-A neutron-openvswi-sg-chain -m physdev --physdev-out tap37b25c08-e8 --physdev-is-bridged -j neutron-openvswi-i37b25c08-e
-A neutron-openvswi-sg-chain -m physdev --physdev-in tap37b25c08-e8 --physdev-is-bridged -j neutron-openvswi-o37b25c08-e
OpenStack Neutron在neutron-openvswi-sg-chain上实现security groups。在使用默认security group的情况下:
- neutron-openvswi-o37b25c08-e 控制从虚机出去的traffic
-A neutron-openvswi-o37b25c08-e -p udp -m udp --sport 68 --dport 67 -j RETURN
-A neutron-openvswi-o37b25c08-e -j neutron-openvswi-s37b25c08-e
-A neutron-openvswi-o37b25c08-e -p udp -m udp --sport 67 --dport 68 -j DROP
-A neutron-openvswi-o37b25c08-e -m state --state INVALID -j DROP
-A neutron-openvswi-o37b25c08-e -m state --state RELATED,ESTABLISHED -j RETURN
-A neutron-openvswi-o37b25c08-e -j RETURN
-A neutron-openvswi-o37b25c08-e -j neutron-openvswi-sg-fallback
- neutron-openvswi-i37b25c08-e 控制进入虚机的traffic
-A neutron-openvswi-i37b25c08-e -m state --state INVALID -j DROP
-A neutron-openvswi-i37b25c08-e -m state --state RELATED,ESTABLISHED -j RETURN
-A neutron-openvswi-i37b25c08-e -s 10.0.0.116/32 -p udp -m udp --sport 67 --dport 68 -j RETURN
-A neutron-openvswi-i37b25c08-e -p tcp -m tcp --dport 22 -j RETURN
-A neutron-openvswi-i37b25c08-e -p icmp -j RETURN
-A neutron-openvswi-i37b25c08-e -m set --match-set IPv48c0dc337-0a6d-4ad7-9 src -j RETURN
-A neutron-openvswi-i37b25c08-e -j neutron-openvswi-sg-fallback
使用下面的命令来添加一条secrutiy group 规则来允许使用TCP 22端口:
neutron security-group-rule-create --protocol tcp --port-range-min 22 --port-range-max 22 --direction ingress default
那么该TAP设备的iptables会出现下面的变化:
root@compute1:/var/lib/nova# iptables -S | grep 22
-A FORWARD -d 192.168.122.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT
-A neutron-openvswi-i155845ae-5 -p tcp -m tcp --dport 22 -j RETURN
-A neutron-openvswi-i155845ae-5 -p tcp -m tcp --dport 22 -j RETURN
-A neutron-openvswi-i37b25c08-e -p tcp -m tcp --dport 22 -j RETURN
-A neutron-openvswi-i37b25c08-e -p tcp -m tcp --dport 22 -j RETURN
3. OVS integration 桥 br-int添加和删除traffic的VLAN ID
每一个使用 neutron net-create 命令创建的network都有一个新的
VLAN ID.本例中因为只有一个network,所以VLAN ID是1,见ovsctl-vsctl show命令中的port tag值。
4. OVS Tunnel 桥 br-tun 处理 VLAN ID 和 Tunnel ID的转化
从以下OpenFlow rule tables可见两种ID的处理过程:
root@compute1:/var/lib/nova# ovs-ofctl dump-flows br-tun
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=11509.036s, table=0, n_packets=1059, n_bytes=116533, idle_age=740, priority=1,in_port=1 actions=resubmit(,2) //从端口1及patch-int进来的traffic会被重新执行table 2的rule
cookie=0x0, duration=2089.491s, table=0, n_packets=1082, n_bytes=115494, idle_age=741, priority=1,in_port=2 actions=resubmit(,3) //从端口2 即 gre 端口进来的traffic重新执行table 3
cookie=0x0, duration=11508.939s, table=0, n_packets=5, n_bytes=390, idle_age=11500, priority=0 actions=drop
cookie=0x0, duration=11508.84s, table=2, n_packets=955, n_bytes=106446, idle_age=741, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20) //重新执行table 20的rule
cookie=0x0, duration=11508.745s, table=2, n_packets=104, n_bytes=10087, idle_age=740, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,22)
cookie=0x0, duration=2260.307s, table=3, n_packets=1082, n_bytes=115494, idle_age=741, priority=1,tun_id=0x1 actions=mod_vlan_vid:1,resubmit(,10) //从neutron node来的traffic,打上VLAN ID 1,重新执行table 10的 rule
cookie=0x0, duration=11508.646s, table=3, n_packets=15, n_bytes=1274, idle_age=2098, priority=0 actions=drop
cookie=0x0, duration=11508.495s, table=4, n_packets=0, n_bytes=0, idle_age=11508, priority=0 actions=drop
cookie=0x0, duration=11508.293s, table=10, n_packets=1082, n_bytes=115494, idle_age=741, 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,从port 1 即 patch-int发出
cookie=0x0, duration=11508.093s, table=20, n_packets=0, n_bytes=0, idle_age=11508, priority=0 actions=resubmit(,22) //重新执行table 22的rule
cookie=0x0, duration=2260.372s, table=22, n_packets=77, n_bytes=7817, idle_age=740, hard_age=2089, dl_vlan=1 actions=strip_vlan,set_tunnel:0x1,output:2,output:2 //去掉VLAN ID,打上TUNNEL ID 1 即 neutron 节点的TUNNEL ID,从端口2 即 gre 端口发出
cookie=0x0, duration=11507.901s, table=22, n_packets=27, n_bytes=2270, idle_age=1664, priority=0 actions=drop
下一节将neutron节点。
前两篇博文分别研究了Compute节点和Neutron节点内部的网络架构。本文通过一些典型流程案例来分析具体网络流程过程。
0. 环境
同 学习OpenStack之(7):Neutron 深入学习之 OVS + GRE 之 Neutron节点篇 中所使用的环境。
简单总结一下:
Compute 节点上由Neutron-OVS-Agent负责:
- br-int:每个虚机都通过一个Linux brige连到该OVS桥上
- br-tun:转化网络packet中的VLAN ID 和 Tunnel ID
- GRE tunnel:虚拟GRE通道
Neutron节点上:
- br-tun/br-int:同Compute节点,由Neutron-OVS-Agent负责
- br-ex:连接物理网卡,用于和外网通信
- Network namespace:用于tenant 网络DHCP服务的qDHCP由Neutron-DHCP-Agent负责,和用于网络间routing的qRouter由Neutron-L3-Agent负责
2. 几个典型流程案例
2.1 流程1: 同一个host上同一个子网内虚机之间的通信过程
因为br-int是个虚拟的二层交换机,所以同一个host上的同一个子网内的虚机之间的通信只是经过 br-int 桥,不需要经过 br-tun 桥。如下图中红线所示:
2.2 流程2: 不同主机上同一个子网内的虚机之间的通信过程
过程:
1. 从左边的虚机1出发的packet,经过Linux bridge到达br-int,被打上 VLAN ID Tag
2. 到达br-tun,将VLAN ID转化为Tunnel ID,从GRE Tunnel 发出,到达另一个compute节点
3. 在另一个compute节点上经过相反的过程,到达右边的虚机
注:本配置待不久之后的实验验证。
2.3 流程3: 虚机访问外网
1. Packet离开虚机,经过Linux bridge, 到达br-int,打上 VLAN ID Tag
2. 达到 br-tun,将 VLAN ID转化为 Tunnel ID
3. 从物理网卡进入GRE通道
4. 从GRE通道达到 Neutron 节点的网卡
5. 达到跟物理网卡相连的br-tun,将 Tunnel ID 转化为 VLAN ID
6. 达到 br-int,再达到 router,router的NAT 表 将 fixed IP 地址 转化为 floatiing IP 地址,再被route 到br-ex
7. 从br-ex相连的物理网卡上出去到外网
外网IP访问虚机是个相反的过程。
2.4 流程4:虚机发送DHCP请求
过程:
1. 虚机的packet -> br-int -> br-tun -> GRE Tunnel -> eth2 ------>eth2->br-tun->br-int->qDHCP
2. qDHCP返回其fixed IP地址,原路返回
例如:在虚机(IP为10.0.22.202)启动过程中,DHCP Server (10.0.22.201)所收到的请求及其回复:
root@network:/home/s1# ip netns exec qdhcp-d24963da-5221-481e-adf5-fe033d6e0b4e tcpdump
listening on tap15865c29-9b, link-type EN10MB (Ethernet), capture size 65535 bytes //dnsmasq在此TAP设备上监听
07:16:56.686349 IP (tos 0x0, ttl 64, id 41569, offset 0, flags [DF], proto UDP (17), length 287)
10.0.22.202.bootpc > 10.0.22.201.bootps: [udp sum ok] BOOTP/DHCP, Request from fa:16:3e:19:65:62 (oui Unknown), length 259, xid 0xab1b9011, secs 118, Flags [none] (0x0000)
Client-IP 10.0.22.202 //虚机eth0的IP地址
Client-Ethernet-Address fa:16:3e:19:65:62 (oui Unknown)
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message Option 53, length 1: Release
Client-ID Option 61, length 7: ether fa:16:3e:19:65:62 //虚机eth0的Mac地址
Server-ID Option 54, length 4: 10.0.22.201 //DHCP Server IP地址
2.5 不同tenant内虚机之间的通信
Neutron Tenant网络是为tenant中的虚机之间的通信。如果需要不同tenant内的虚机之间通信,需要在两个subnet之间增加Neutron路由。
3. 关于GRE/OVS/Neutron的一些快速结论
增加Tunnel ID,势必减少vm的mtu值,同样大小的数据,需要更多的ip包来传,传输效率有影响。
:可以针对每个vm做流量限制、流量监控、数据包分析,同时可以引入OpenFlow,使控制逻辑和物理交换相分离,并且sdn controller可以实现vxlan的跨机房大二层通信,但是可能性能是个潜在问题。
3. Neutron的优点:
(1)提供REST API
(2)Neutron 把部分传统网络管理的功能推到了租户方,租户通过它可以创建一个自己专属的虚拟网络及其子网,创建路由器等,在虚拟网络功能的帮助下,基础物理网络就可以向外提供额外的网络服务了,比如租户完全可以创建一个属于自己的类似于数据中心网络的虚拟网络。Neutron 提供了比较完善的多租户环境下的虚拟网络模型以及 API。像部署物理网络一样,使用 Neutron 创建虚拟网络时也需要做一些基本的规划和设计。
4. Neutron的可能问题:
(1)单点故障:Neutron节点做为network的中心控制节点,很容易导致单点故障。生产环境中HA应该是必须有的。
(2)性能降低:network traffic经过太多的层次,latency增加。
(3)可扩展性不够:当Compute 节点快速增加的时候,Neutron节点也需要扩展。