昨天透過Flat Network,讓VM可以與實體網路互通。但使用Flat Network有一個最大的限制,就是一個Flat Network一定會拿一個NIC做為bridge的Port。舉例來說,昨天我們就拿eth2做為flat0 這個Flat Network的介面,如果要再建立第二個Flat Network,就必需再安裝一個未使用的NIC,這樣會非常沒有彈性。另一個缺點則是,使用同一個Flat Network的設備,不論是VM還是實體主機,都能互相通訊,雖然非常方便,但也有非常大的風險。基於這二個原因,一般來說,如果要和實體網路相連,通常不會採用Flat Netwrok,而是會採用另一種非常類似的VLAN Network。
採用VLAN Network,第一個優點是可以在同一個NIC上傳送多個不同VLAN Network的封包;第二,在真正的Production機房,大多會讓不同設備處在不同的VLAN,一旦採用VLAN Network,就可以VM與在不同的VLAN上的設備溝通,以達到安全的隔離。
如果是用Day-15: 多節點的OpenStack環境的操作建立的OpenStack,我們只有啟用geneve與flat二種Network,是無法使用VLAN Network。可以依照今天提供的Vagrantfile再重新安裝一次。今天修改後的packstack參數如下。差別--os-neutron-ml2-type-drivers
與 --os-neutron-ml2-vlan-ranges
加上VLAN的設定。
packstack \
--nova-libvirt-virt-type=kvm \
--keystone-admin-passwd=password \
--os-debug-mode=y \
--provision-demo=n \
--os-cinder-install=n \
--os-swift-install=n \
--os-aodh-install=n \
--os-ceilometer-install=n \
--os-horizon-install=n \
--os-neutron-ml2-type-drivers=flat,vlan \
--os-neutron-ml2-vlan-ranges=flat0:3001:4000 \
--os-neutron-ml2-flat-networks=* \
--os-neutron-ml2-tenant-network-types=' ' \
--os-neutron-ml2-mechanism-drivers=ovn \
--os-neutron-l2-agent=ovn \
--os-neutron-ovn-bridge-mappings=extnet0:br-ex,flat0:br-eth2 \
--os-neutron-ovn-bridge-interfaces=br-ex:eth0,br-eth2:eth2 \
--os-neutron-ovn-bridges-compute=br-eth2 \
--os-neutron-ovn-tunnel-if=eth1 \
--os-controller-host=192.168.33.10 \
--os-network-hosts=192.168.33.10 \
--os-compute-hosts=192.168.33.20,192.168.33.30 \
--install-hosts=192.168.33.10,192.168.33.20,192.168.33.30
若不想重新建立新的測試環境,其實也可以直接修改Neutron的設定檔,修改network-controller節點的/etc/neutron/plugins/ml2/ml2_conf.ini
加上如下設定,啟用VLAN driver,並設定對應的實體網路名稱後,再重啟neutron server也可益達到相同的結果。
[ml2]
type_drivers=flat,vlan,geneve
...
[ml2_type_vlan]
network_vlan_ranges=flat0:3001:4000
flat0:3001:4000
的數字代表建立VLAN時,若無指定VLAN ID,會從這個區段找一個來做為VLAN ID
systemctl restart neutron-server.service
openstack network create --provider-network-type vlan --provider-physical-network flat0 --provider-segment 100 n1
openstack subnet create --subnet-range 172.16.100/24 --network n1 n1subnet
openstack server group create --policy affinity odd_affinity
openstack server group create --policy anti-affinity odd_anti_affinity
IMAGE_ID=$(openstack image show cirros --format json | jq -r .id)
AFFINITY_ID=$(openstack server group show odd_affinity --format json | jq -r .id)
ANTI_AFFINITY_ID=$(openstack server group show odd_anti_affinity --format json | jq -r .id)
openstack server create --nic net-id=n1,v4-fixed-ip=172.16.100.10 --flavor m1.nano --image $IMAGE_ID --hint group=$AFFINITY_ID vm_1
openstack server create --nic net-id=n1,v4-fixed-ip=172.16.100.20 --flavor m1.nano --image $IMAGE_ID --hint group=$ANTI_AFFINITY_ID vm_2
openstack server list --long -c Name -c Status -c Host -c "Power State"
+------+--------+-------------+------------+
| Name | Status | Power State | Host |
+------+--------+-------------+------------+
| vm_2 | ACTIVE | Running | compute-02 |
| vm_1 | ACTIVE | Running | compute-01 |
+------+--------+-------------+------------+
# Network
openstack network list --long -c ID -c "Network Type" | abbrev
+--------+--------------+
| ID | Network Type |
+--------+--------------+
| a8877b | vlan |
+--------+--------------+
openstack port list --long -c ID -c "Fixed IP Addresses" -c "Device Owner" | abbrev
+--------+------------------------------------------------+---------------------+
| ID | Fixed IP Addresses | Device Owner |
+--------+------------------------------------------------+---------------------+
| 193921 | ip_address='172.16.100.10', subnet_id='ec52a9' | compute:nova |
| eca1f0 | ip_address='172.16.100.20', subnet_id='ec52a9' | compute:nova |
| 7b8408 | ip_address='172.16.100.2' , subnet_id='ec52a9' | network:distributed |
+--------+------------------------------------------------+---------------------+
查看North Bound DB的情況,與Day-17: Flat Tenant Network#OpenStack 與OVN 元件關係相比,完全都相同,就不在重複,讓大家自己練習解讀。唯一的差別就在於,VLAN Network的localnet port,會有一個tag
屬性,代表這個VLAN ID。
ovn-nbctl show| abbrev
switch 10b5d2 (neutron-a8877b) (aka n1)
port 7b8408
type: localport
addresses: ["fa:16:3e:87:29:42 172.16.100.2"]
port provnet-32ddcf
type: localnet
tag: 100
addresses: ["unknown"]
port 193921
addresses: ["fa:16:3e:6f:c5:bc 172.16.100.10"]
port eca1f0
addresses: ["fa:16:3e:73:c1:44 172.16.100.20"]
一旦二個VM建立後,我們檢查二個節點上的bridge長像,和使用Flat Network時是完全相同。這部份就也讓大家自行複習。
這裡的eth2是用來傳送有VLAN Network的封包,eth2可以傳送多個VLAN的封包,所以,在真正的情境下,實體交換機與eth2相連的port,必需設為trunk port。
最後,我們來看一下,由VM送出來的封包,是沒有VLAN ID的封包。而且,也和Flat Network相同,跨節點的傳輸,是經由eth2,而不是由eth1的geneve tunnel。
ovs-tcpdump -n -i tapbc3d8ce1-fb-8b icmp
12:30:21.327297 IP 172.16.100.10 > 172.16.100.20: ICMP echo request, id 29072, seq 1, length 64
12:30:21.328875 IP 172.16.100.20 > 172.16.100.10: ICMP echo reply, id 29072, seq 1, length 64
最後在eth2得到的,會是帶有VLAN 100的封包。
tcpdump -i eth2 -nn -e vlan
07:46:26.317437 fa:16:3e:f8:a7:fe > fa:16:3e:3a:64:cc, ethertype 802.1Q (0x8100), length 102: vlan 100, p 0, ethertype IPv4, 172.16.100.10 > 172.16.100.20: ICMP echo request, id 63195, seq 1, length 64
07:46:26.319151 fa:16:3e:3a:64:cc > fa:16:3e:f8:a7:fe, ethertype 802.1Q (0x8100), length 102: vlan 100, p 0, ethertype IPv4, 172.16.100.20 > 172.16.100.10: ICMP echo reply, id 63195, seq 1, length 64
我們只建了一個VLAN ID是100的Network,你們也可以自己建立另一個使用不同VLAN ID的VLAN Network。再eth2再試著抓封包,可以看到會有另一個VLAN的封包在eth2上。這就讓大家自行練習吧。