Open vSwitch實踐 -- 利用dnsmasq為虛機分配IP地址
OpenStack裡的所建立虛機的虛擬網絡卡都會先attach到一個linux bridge(主要是為了通過iptable實現安全組),然後再attach到整合網橋(br-int)上,並通過網路節點上attach到br-int的dhcp tap裝置獲得IP地址。這裡我們通過純手工的方式模擬一下這個過程,為了簡單起見,我們將排除linux bridge和namespace的影響,將虛擬網絡卡和dhcp裝置直接attach到同一個主機的br-int上,如下圖所示:
其中,VM1和VM2的虛機網絡卡的名字分別叫做tap1和tap2。DHCP裝置的名字叫tap-qdhcp。
下面是詳細的實現過程:
1. 安裝並啟動Open vSwitch。
# yum -y install openvswitch
# systemctl start openvswitch
# systemctl enable openvswitch
2. 建立整合網橋br-int。
# ovs-vsctl add-br br-int
3. 將DHCP裝置tap-qdhcp新增到br-int。注意一定要加上"-- set Interface tap-qdhcp type=internal",否則命令會報錯找不到tap-qdhcp裝置。
# ovs-vsctl add-port br-int tap-qdhcp -- set Interface tap-qdhcp type=internal
4. 為tap-qdhcp配置IP地址
# ifconfig tap-qdhcp 10.0.0.1 netmask 255.255.255.0 up # ifconfig tap-qdhcp tap-qdhcp: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255 inet6 fe80::2c37:27ff:fe72:e296 prefixlen 64 scopeid 0x20<link> ether 2e:37:27:72:e2:96 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 10 bytes 732 (732.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
5. 安裝dnsmasq,並在tap-qdhcp上啟動一個dnsmasq的監聽,dnsmasq負責監聽並響應dhcp請求。
# yum install dnsmasq
# mkdir /var/run/dnsmasq/
# /usr/sbin/dnsmasq --strict-order --bind-interfaces --except-interface lo --interface tap-qdhcp --dhcp-range 10.0.0.10,10.0.0.100 --dhcp-leasefile=/var/run/dnsmasq/tap-qdhcp.pid --dhcp-lease-max=253 --dhcp-no-override --log-queries --log-facility=/tmp/dnsmasq.log
# ps -ef|grep dnsmasq
nobody 1196 1 0 18:04 ? 00:00:00 /usr/sbin/dnsmasq --strict-order --bind-interfaces --except-interface lo --interface tap-qdhcp --dhcp-range 10.0.0.10,10.0.0.100 --dhcp-leasefile=/var/run/dnsmasq/tap-qdhcp.pid --dhcp-lease-max=253 --dhcp-no-override --log-queries --log-facility=/tmp/dnsmasq.log
6. 安裝libvirt, virt-install, qemu-kvm,並啟動libvirtd
# yum -y install libvirt virt-install qemu-kvm
# systemctl start libvirtd
# systemctl enable libvirtd
7. 用virt-install建立兩個虛機,分別命名為vm1和vm2。為了簡單起見,用cirros作為disk image。需要提前將image檔案cirros-0.3.1-x86_64-disk.img上傳到/tmp/vm1/和/tmp/vm2/下面。這裡用到的network就是安裝libvirt時自動建立的網路default。
# virt-install --connect=qemu:///system --name=vm1 --ram=50 --vcpus=1 --virt-type qemu --disk \
path=/tmp/vm1/cirros-0.3.1-x86_64-disk.img,format=qcow2 --import --network network:default
# virt-install --connect=qemu:///system --name=vm2 --ram=50 --vcpus=1 --virt-type qemu --disk \
path=/tmp/vm2/cirros-0.3.1-x86_64-disk.img,format=qcow2 --import --network network:default
# virsh list --all
Id 名稱 狀態
----------------------------------------------------
3 vm1 running
4 vm2 running
8. 為了讓新建立的vm1和vm2使用br-int,需要對兩個虛機的配置檔案進行重新編輯:
首先停止兩個虛機:
# virsh destroy vm1
# virsh destroy vm2
然後編輯/etc/libvirt/qemu/vm1.xml,原始的需要替換的部分如下:
<interface type='network'>
<mac address='52:54:00:99:81:00'/>
<source network='default'/>
<model type='rtl8139'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
最終需要將其替換為如下內容: <interface type='bridge'>
<source bridge='br-int'/>
<virtualport type='openvswitch'/>
<target dev='tap1'/>
<model type='virtio'/>
</interface>
然後對/etc/libvirt/qemu/vm2.xml做同樣修改,修改後的內容片段如下: <interface type='bridge'>
<source bridge='br-int'/>
<virtualport type='openvswitch'/>
<target dev='tap2'/>
<model type='virtio'/>
</interface>
9. 使用修改後的虛機配置檔案來重新定義虛機
首先將vm1.xml和vm2.xml拷貝到/tmp/下面:
# cp /etc/libvirt/qemu/vm1.xml /tmp/
# cp /etc/libvirt/qemu/vm2.xml /tmp/
刪除之前建立的舊的虛機的定義:# virsh undefine vm1
# virsh undefine vm2
將/tmp/vm1.xml和/tmp/vm2.xml拷貝回/etc/libvirt/qemu:# cp /tmp/vm*.xml /etc/libvirt/qemu/
使用新的配置檔案重新定義虛機:# virsh define /etc/libvirt/qemu/vm1.xml
# virsh define /etc/libvirt/qemu/vm2.xml
10. 啟動虛擬機器,可以在console上看到在啟動過程中得到了dhcp分配的IP地址,如下:
# virsh start vm1 --console
......
Starting network...
udhcpc (v1.20.1) started
Sending discover...
Sending select for 10.0.0.92...
Lease of 10.0.0.92 obtained, lease time 3600
# virsh start vm2 --console
......
Starting network...
udhcpc (v1.20.1) started
Sending discover...
Sending select for 10.0.0.42...
Lease of 10.0.0.42 obtained, lease time 3600
11. 登陸vm1,可以能夠ping通vm2
# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 52:54:00:E2:05:18
inet addr:10.0.0.92 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::5054:ff:fee2:518/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:29 errors:0 dropped:0 overruns:0 frame:0
TX packets:31 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3002 (2.9 KiB) TX bytes:2754 (2.6 KiB)
# ping 10.0.0.42
PING 10.0.0.42 (10.0.0.42): 56 data bytes
64 bytes from 10.0.0.42: seq=0 ttl=64 time=1.359 ms
64 bytes from 10.0.0.42: seq=1 ttl=64 time=2.026 ms
64 bytes from 10.0.0.42: seq=2 ttl=64 time=2.949 ms
12. 檢視OVS的配置,可以看到tap1, tap2和tap-qdhcp都attach到br-int上,如下:
# ovs-vsctl show
4daab0dc-86dc-4b09-b7c2-e93ba990166a
Bridge br-int
Port "tap2"
Interface "tap2"
Port br-int
Interface br-int
type: internal
Port tap-qdhcp
Interface tap-qdhcp
type: internal
Port "tap1"
Interface "tap1"
ovs_version: "2.4.0"