1. 程式人生 > >Open vSwitch實踐 -- 利用dnsmasq為虛機分配IP地址

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"