Openstack Neutron网络实验-02

0 阅读

本文将继续介绍在将Openstack的nova实例连接到外网过程中网络拓扑的变化。

上一篇文《Openstack Neutron网络实验-01》中在Openstack中创建了以下内容:

  1. 租户网络test-net,包含子网:test-net-subnet,并启用了dhcp。
  2. 虚机实例test-vm1,并接入网络test-net。
  3. 路由器router01, 并接入子网test-net-subnet。

0. 准备-宿主机网络介绍

按照《使用vagrant和virtualbox搭建openstack集群》安装完Openstack后,两台宿主机os-ctl1和os-cpu1可通过网口eth0使用NAT访问外部网络,ip是virtualbox自动分配的10.0.2.15/24。而网口eth1则作为两台宿主机之间的通信和管理使用,ip由Vagrantfile中的网络配置指定。

本次实验的目的使得虚机实例test-vm1能够访问外部网络,任务是要创建一个External Network将之前创建的租户网络接入到网络节点os-ctl1的网口eth0。

1. 创建外部网络

在Openstack上创建一个外部网络,菜单路径为:Admin -> Network -> Networks -> Create Network。

注意:仅能在Admin菜单下才能创建External Network, Project菜单下只能创建租户内部网络

填入如下参数:

  • Name:external-net
  • Project:admin
  • Provider Network Type: Flat
  • Physical Network: extnet,该参数为物理网络的标识,需要和Neutron配置文件中的定义一致,packstack的安装参数文件中默认定义如下,表示extnet这个物理网络实际上由br-ex网桥承载。
    • CONFIG_NEUTRON_OVS_BRIDGE_MAPPINGS=extnet:br-ex
    • CONFIG_NEUTRON_OVS_EXTERNAL_PHYSNET=extnet
  • Subnet Name: external-net-subnet
  • Network Address: 10.0.2.0/24,该参数应和实际的物理网络情况相符,VirtualBox的NAT网络默认使用10.0.2.0/24。
  • Gateway IP: 10.0.2.2,该参数应和实际的物理网络情况相符,VirtualBox的NAT网络默认网关为10.0.2.2。
  • Enable DHCP: False,该网络中的IP由实际物理网络决定,不需要Openstack的DHCP agent分配。

创建External Network后,网络节点拓扑没有变化。和test-net不一样,external-net没有启用DHCP, 所以其端口列表为空。

2. 将外部网络接入租户Router

将之前创建的租户router01的网关设置为新创建的外部网络,由于上一篇中这个Router已经连接了内部网络test-net,设置网关后将使得两个网络连通起来。

菜单路径为:Project -> Network -> Routers -> router01 -> Set GateWay。填入如下参数:

  • External Network:external-net
  • Enable SNAT: True,打开SNAT使得从租户网络出去的数据包的源地址被转换成外部网络地址。
# ovs-vsctl show
...
    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port int-br-ex
            Interface int-br-ex
                type: patch
                options: {peer=phy-br-ex}
        Port "tape68eed07-f5"
            tag: 1
            Interface "tape68eed07-f5"
                type: internal
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
        Port "qg-95f2615e-cd"
            tag: 9
            Interface "qg-95f2615e-cd"
                type: internal
        Port br-int
            Interface br-int
                type: internal
        Port "qvo5d07f509-f1"
            tag: 1
            Interface "qvo5d07f509-f1"
        Port "qr-9516320e-52"
            tag: 1
            Interface "qr-9516320e-52"
                type: internal
...
# ip netns exec qrouter-7d360e8e-e392-4def-816b-f92f7e5f9bc5 ip address
1: lo: <LOOPBACK,UP,LOWER_UP> 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
12: qr-9516320e-52: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN qlen 1000
    link/ether fa:16:3e:f6:ec:e8 brd ff:ff:ff:ff:ff:ff
    inet 172.16.2.1/24 brd 172.16.2.255 scope global qr-9516320e-52
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fef6:ece8/64 scope link
       valid_lft forever preferred_lft forever
24: qg-95f2615e-cd: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN qlen 1000
    link/ether fa:16:3e:22:4c:c8 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.10/24 brd 10.0.2.255 scope global qg-95f2615e-cd
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe22:4cc8/64 scope link
       valid_lft forever preferred_lft forever
# ip netns exec qrouter-7d360e8e-e392-4def-816b-f92f7e5f9bc5 netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.0.2.2        0.0.0.0         UG        0 0          0 qg-95f2615e-cd
10.0.2.0        0.0.0.0         255.255.255.0   U         0 0          0 qg-95f2615e-cd
172.16.2.0      0.0.0.0         255.255.255.0   U         0 0          0 qr-9516320e-52

拓扑图如下:

neutron-4.jpg

进入虚机,发现可以ping通网关新增的接口10.0.2.10,但是外部网关没有ping通。

$ ping 10.0.2.10
PING 10.0.2.10 (10.0.2.10): 56 data bytes
64 bytes from 10.0.2.10: seq=0 ttl=64 time=8.391 ms

--- 10.0.2.10 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 8.391/8.391/8.391 ms
$ ping 10.0.2.2
PING 10.0.2.2 (10.0.2.2): 56 data bytes

--- 10.0.2.2 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

3. 将访问外部网络的网口eth0加入网桥br-ex中

上述定义的外部网络extnet被映射到了OVS网桥,即Openstack实例将通过网桥br-ex访问外部网络,因此我们需要将网络节点用于访问外部网络的eth0接口加入到br-ex网桥中。

# ovs-vsctl add-port br-ex eth0
# ovs-vsctl show
...
    Bridge br-ex
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port "eth0"
            Interface "eth0"
        Port br-ex
            Interface br-ex
                type: internal
        Port phy-br-ex
            Interface phy-br-ex
                type: patch
                options: {peer=int-br-ex}
...

进入虚机,确认外部网关10.0.2.2已经外网Google DNS IP 8.8.8.8均能ping通。

$ ping 10.0.2.2
PING 10.0.2.2 (10.0.2.2): 56 data bytes
64 bytes from 10.0.2.2: seq=0 ttl=62 time=1.752 ms

--- 10.0.2.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 1.752/1.752/1.752 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

4. 配置提供对外访问的网口

eth0加入网桥后,必须将其ip配到网桥br-ex上,否则外部无法访问这个IP,呈现为两个问题:

  1. floating ip无法访问openstack实例,因为网络节点没有floating ip的路由。
  2. vagrant ssh无法登陆宿主机。

修改/etc/sysconfig/network-scripts/下的ifcfg-br-ex和ifcfg-eth0文件,内容如下,然后重启网络服务

$ sudo vi /etc/sysconfig/network-scripts/ifcfg-br-ex
$ sudo cat /etc/sysconfig/network-scripts/ifcfg-br-ex
DEVICE=br-ex  
OVSBOOTPROTO=dhcp
ONBOOT=yes  
NM_CONTROLLED=no  
TYPE=OVSBridge
DEVICETYPE=ovs
PERSISTENT_DHCLIENT=yes
OVSDHCPINTERFACES=eth0
$ sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0
$ sudo cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0  
ONBOOT=yes  
NM_CONTROLLED=no  
TYPE=OVSPort
DEVICETYPE=ovs
OVS_BRIDGE=br-ex
$ sudo systemctl restart network

上述配置使得eth0在启动时加入到br-ex网桥中,而br-ex网桥通过eth0进行dhcp获取ip,即VirtualBox分配的10.0.2.15/24。 这些配置应该在安装部署Openstack的时候完成,如果使用packstack安装,可以通过设置以下参数指定:

CONFIG_NEUTRON_OVS_BRIDGE_IFACES=br-ex:eth0

5. 分配浮动IP

到此为止,我们已经成功在Openstack中创建了两个网络,并且通过路由器将其连通。当前两个网络如下图显示:

neutron-5.jpg

接入外部网络的时候启用了SNAT,因此当数据包由内网发往外网时,路由器会将数据包的源地址转换为外网地址,不同实例的源地址可共享同一个外网地址,即router01的external-net地址10.0.2.10。

但是当数据包由外网发往内网时,则需要使用DNAT协议将目的地址转换为内网地址,此时,每个实例的内网地址均需对应一个外网地址才能供外部访问。

菜单路径为:Project -> Network -> Floating IPs -> Allocate IP to Project。填入如下参数:

  • Pool: external-net

分配完成后对该IP点击“Associate”,将其绑定到实例test-vm1中。

floating-ip.jpg

绑定完成后,可以看到新分配的外网IP 10.0.2.11被映射到了内网IP 172.16.2.7。

实际上,浮动IP的分配是在router的iptables中添加了一条NAT规则:

# ip netns exec qrouter-7d360e8e-e392-4def-816b-f92f7e5f9bc5 iptables-save -t nat
...
-A neutron-l3-agent-OUTPUT -d 10.0.2.11/32 -j DNAT --to-destination 172.16.2.7
...

5. 修改Security Group

菜单路径为:Project -> Network -> Security Groups -> “default” -> “Manage Rules” -> “Add Rule”。

添加ICMP和SSH两项规则:

  • Rule: ALL ICMP
  • Rule: SSH

在宿主机上分别使用ping和ssh访问test-vm1实例,均能成功。

# ping 10.0.2.11
PING 10.0.2.11 (10.0.2.11) 56(84) bytes of data.
64 bytes from 10.0.2.11: icmp_seq=1 ttl=63 time=7.74 ms
^C
--- 10.0.2.11 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 7.747/7.747/7.747/0.000 ms
$ ssh cirros@10.0.2.11  
cirros@10.0.2.11's password:
$ exit
Connection to 10.0.2.11 closed.

实际上,Security Group通过修改网络节点的iptables来实现防火墙功能:

# iptables-save | grep neutron-openvswi        
...
-A neutron-openvswi-i5d07f509-f -p icmp -j RETURN
...
-A neutron-openvswi-i5d07f509-f -p tcp -m tcp --dport 22 -j RETURN
...
-A neutron-openvswi-sg-chain -m physdev --physdev-out tap5d07f509-f1 --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-openvswi-i5d07f509-f
-A neutron-openvswi-sg-chain -m physdev --physdev-in tap5d07f509-f1 --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-openvswi-o5d07f509-f
-A neutron-openvswi-sg-chain -j ACCEPT
...

上述规则的意思是指对于在neutron-openvswi-i5d07f509-f链中匹配到了icmp和ssh数据包,返回到其父链neutron-openvswi-sg-chain中继续判断,而父链neutron-openvswi-sg-chain中将接受所有的数据包。

问题:

  1. 如果把eth0加入到br-int桥,无法访问外网,为什么?
更新于

本文遵守 CC-BY-NC-4.0 许可协议。

Creative Commons License

欢迎转载,转载需注明出处,且禁止用于商业目的。

上篇Openstack Neutron网络实验-03
下篇Openstack Neutron网络实验-01