本文继续介绍在将Openstack多网络节点部署时的网络拓扑。
上一篇文章中在Opentack环境中创建了以下内容:
- 租户网络test-net,包含子网:test-net-subnet,并启用了dhcp。
- 外部网络external-net,包含子网:external-net-subnet。
- 虚机实例test-vm1和test-vm2,并接入网络test-net。
- 路由器router01, 接入了两个子网test-net-subnet和external-net-subnet。
1. 增加网络节点
参考《使用vagrant和virtualbox搭建openstack集群》添加一个网络节点。
增加网络节点后,3个节点的br-tun网桥拓扑如下:
# ovs-vsctl show
...
Bridge br-tun
Controller "tcp:127.0.0.1:6633"
is_connected: true
fail_mode: secure
Port "vxlan-c0a83810"
Interface "vxlan-c0a83810"
type: vxlan
options: {df_default="true", in_key=flow, local_ip="192.168.56.15", out_key=flow, remote_ip="192.168.56.16"}
Port "vxlan-c0a83811"
Interface "vxlan-c0a83811"
type: vxlan
options: {df_default="true", in_key=flow, local_ip="192.168.56.15", out_key=flow, remote_ip="192.168.56.17"}
Port patch-int
Interface patch-int
type: patch
options: {peer=patch-tun}
...
# ovs-vsctl show
...
Bridge br-tun
Controller "tcp:127.0.0.1:6633"
is_connected: true
fail_mode: secure
Port "vxlan-c0a83811"
Interface "vxlan-c0a83811"
type: vxlan
options: {df_default="true", in_key=flow, local_ip="192.168.56.16", out_key=flow, remote_ip="192.168.56.17"}
Port "vxlan-c0a8380f"
Interface "vxlan-c0a8380f"
type: vxlan
options: {df_default="true", in_key=flow, local_ip="192.168.56.16", out_key=flow, remote_ip="192.168.56.15"}
Port patch-int
Interface patch-int
type: patch
options: {peer=patch-tun}
...
# ovs-vsctl show
...
Bridge br-tun
Controller "tcp:127.0.0.1:6633"
is_connected: true
fail_mode: secure
Port "vxlan-c0a8380f"
Interface "vxlan-c0a8380f"
type: vxlan
options: {df_default="true", in_key=flow, local_ip="192.168.56.17", out_key=flow, remote_ip="192.168.56.15"}
Port "vxlan-c0a83810"
Interface "vxlan-c0a83810"
type: vxlan
options: {df_default="true", in_key=flow, local_ip="192.168.56.17", out_key=flow, remote_ip="192.168.56.16"}
Port patch-int
Interface patch-int
type: patch
options: {peer=patch-tun}
...
上述结果显示,3个节点的VTEP两两间建立了vxlan隧道。
2. 增加租户网络
Step 1 按照之前的方法添加一个租户网络
参数如下:
- Network Name:test-net2
- Subnet Name:test-net2-subnet
- Network Address:172.16.3.0/24
- Gateway IP:172.16.3.1
- Enable DHCP: true
可以预期,添加了这个租户网络后,系统会创建一个dhcp agent,分布在两个网络节点上检查一下,发现这个dhcp aent被创建在了新创建的网络节点os-net1上,并被分配了IP 172.16.3.2
[root@os-net1 ~]# ovs-vsctl show
...
Bridge br-int
Controller "tcp:127.0.0.1:6633"
is_connected: true
fail_mode: secure
Port "tapc03e248f-c4"
tag: 1
Interface "tapc03e248f-c4"
type: internal
Port patch-tun
Interface patch-tun
type: patch
options: {peer=patch-int}
Port int-br-ex
Interface int-br-ex
type: patch
options: {peer=phy-br-ex}
...
[root@os-net1 ~]# ip netns
qdhcp-641294ba-9d48-4181-85a4-6a86d4c8cb0d
[root@os-net1 ~]# ip netns exec qdhcp-641294ba-9d48-4181-85a4-6a86d4c8cb0d ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN qlen 1
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
9: tapc03e248f-c4: mtu 1450 qdisc noqueue state UNKNOWN qlen 1000
link/ether fa:16:3e:76:86:13 brd ff:ff:ff:ff:ff:ff
inet 172.16.3.2/24 brd 172.16.3.255 scope global tapc03e248f-c4
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fe76:8613/64 scope link
valid_lft forever preferred_lft forever
Step 2:将test-vm2移到新网络test-net2上来
在test-vm2实例上先detach原有网络的interface,再attach新网络的Interface,然后重启实例使之生效。
菜单路径:Project -> Compute -> Instances -> "test-vm2" -> Detach/Attach Interface
接入新网络后,test-vm2可以访问同一网络内的dhcp服务172.16.3.2并获取到IP,但是无法访问test-net中的实例test-vm1,也无法访问外网,这是因为test-net,test-net2和external-net在二层网络上都是隔离的,必须接入router才能将其连通。
Step 3:将新创建的网络加入router01
菜单路径:Project -> Network -> Routers -> "router01" -> Interfaces -> Add Interface
加入后,test-vm2就可以访问test-vm1和外网了。
$ ping 172.16.2.11
PING 172.16.2.11 (172.16.2.11): 56 data bytes
64 bytes from 172.16.2.11: seq=0 ttl=63 time=34.903 ms
�
--- 172.16.2.11 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 34.903/34.903/34.903 ms
$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=2 ttl=36 time=126.277 ms
�
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 1 packets received, 66% packet loss
round-trip min/avg/max = 126.277/126.277/126.277 ms
可以看到,在Underlay网络之上,建立了两个Overlay的租户网络,连通了3台宿主机上的5个通信实体。
- test-vm1,宿主机:os-ctl1。
- test-vm2,宿主机:os-cpu1。
- test-net DHCP Agent,宿主机:os-ctl1。
- test-net2 DHCP Agent,宿主机:os-net1。
- router01,宿主机:os-ctl1。
- 外部网关 10.0.2.2
两个租户网络在二层通过VXLAN ID隔离,VXLAN ID在创建网络的时候自动分配,VXLAN ID在openstack中被抽象为Segment ID,因为除了VXLAN这种网络隔离技术,openstack还支持VLAN和GRE等其他技术
我们创建的两个网络详细信息如下:
网络拓扑如下:
可以看到,因为上图中包括了物理和虚拟的所有实体,变得非常复杂。幸运的是,到了现在我们已经对虚拟网络的底层物理实现机制非常了解了,如果把上图简化一下,只将对普通租户可见的虚拟网络画出来,其实是一个非常简单的拓扑。
3. 增加新的外部网络
实际上,os-net1和os-ctl一样,也有用于访问外部网络的网口eth0和网桥br-ex,因此os-ctl1同样可以为openstack提供外网访问。但是由于extnet这个物理网络的标识已经被os-ctl1使用,我们可以另外定义一个物理网络标识,如extnet2。
Step 1:修改neutron配置文件
# vi /etc/neutron/plugins/ml2/openvswitch_agent.ini
将
bridge_mappings=extnet:br-ex
改为:
bridge_mappings=extnet2:br-ex
重启os-net1使配置生效。
Step 2:创建新的外部网络external-net2
参数为:
- Name:external-net2
- Subnet Name: external-net2-subnet
其余参数和external-net一样,因为VirtualBox为两台宿主机os-ctl1和os-net1提供的外网环境时一样的。
Step 3:创建新的路由器router02
创建router02后,将external-net2设为其的网关,将test-net2网络接入router02。
这样在整个集群内就建起了两个完全独立的网络:
- test-vm1, test-net, router01, external-net(extnet)
- test-vm2, test-net2, router02, external-net2(extnet2)
两个网络互不相通,但是均可以访问外网。
可以在两个网络节点上使用tcpdump命令监控网络流量,然后分别在test-vm1和test-vm2中运行ping 8.8.8.8指令,可以看到test-vm1的数据包经过了os-ctl1,而test-vm2的数据包经过了os-net1。
虚拟网络拓扑图如下:
4. 网络Agent的调度
网络节点上运行着提供各种网络服务的Agent,目前涉及到的Agent包括:
- DHCP agent,用于提供DHCP服务。
- l3 agent(即router),用于提供三层的路由服务。
这些agent在网络节点上体现为一个专有命名空间中的进程,当集群中有多个网络节点时,openstack同样会根据节点的负荷对这些进程进行调度,因此,这些agent启动在哪个节点上取决于他们被创建的时候所有网络节点的状态。
由于这些agent在每次集群启动的时候都会重新创建,而在Vagrant实验环境每台宿主机将按Vagrantfile定义顺序启动,因此可以观察到以下现象:
- 集群启动后所有agent都在os-ctl1运行(因为此时os-net1还未启动),
- 启动后新建的网络(启用dhcp就会创建新的dhcp agent)或者router,对应的agent就很大可能会运行在os-net1上(因为此时os-net1没有运行任何agent,负荷会比较低)。
- 调度结果还取决于宿主机的配置,实验中也观察到了新创建的agent仍然运行在os-ctl1上的情景(因为os-ctl1的配置比os-net1要高)。