linux中qemu-kvm橋接網絡報錯問題

準 確來說,KVM是Linux的一個模塊。可以用modprobe去加載KVM模塊。加載了模塊後,才能進一步通過其他工具創建虛擬機。但僅有KVM模塊是 遠遠不夠的,因爲用戶無法直接控制內核模塊去作事情:還必須有一個用戶空間的工具才行。這個用戶空間的工具,開發者選擇了已經成型的開源虛擬化軟件 QEMU。說起來QEMU也是一個虛擬化軟件。它的特點是可虛擬不同的CPU。比如說在x86的CPU上可虛擬一個Power的CPU,並可利用它編譯出 可運行在Power上的程序。KVM使用了QEMU的一部分,並稍加改造,就成了可控制KVM的用戶空間工具了。所以你會看到,官方提供的KVM下載有兩 大部分三個文件,分別是KVM模塊、QEMU工具以及二者的合集。也就是說,你可以只升級KVM模塊,也可以只升級QEMU工具。這就是KVM和QEMU 的關係

之前拿到的RHCE 虛擬機環境,被我通過將vmdk轉換爲qcow2格式後,通過原生的qemu-kvm命令啓動成功。由於通過virsh + xml 配置文件方式啓動時有問題。一直懶得出看了,沒次要使用時,直接qemu-kvm啓動之。不過每次通過vnc 再去連接感覺比較麻煩,索性給其加了一塊網卡,橋接當前物理網卡,這樣可以通SCRT直連。不過增加時確出現瞭如下報錯:

/etc/qemu-ifup: could not launch network script
qemu-kvm: -net tap,vlan=0,ifname=tap0: Device 'tap' could not be initialized
這裏記錄下具體的處理和解決的過程。

一、參考virsh 啓動的主機

原於virsh 命令啓時最終也是調用的qemu-kvm命令啓動的虛擬機,在通過ps auxf|grep kvm 查看時,發其他主機啓動時,使用的網絡部分參數如下:

-netdev tap,fd=22,id=hostnet0,vhost=on,vhostfd=23 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:1f:45:43,bus=pci.0,addr=0x3
依葫蘆畫瓢也通過qemu-kvm啓動時也增加這麼一串東西時。發現啓動報錯。

二、查看qemu-kvm幫助

通過查看qemu-kvm與網絡相關的幫助信息如下:

[root@361way ~]# /usr/libexec/qemu-kvm --help|grep -i net
                'drives': floppy (a), hard disk (c), CD-ROM (d), network (n)
Network options:
-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]
                create a new Network Interface Card and connect it to VLAN 'n'
-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=on|off]
                connect the user mode network stack to VLAN 'n', configure its
-net tap[,vlan=n][,name=str][,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile][,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off][,vhostfd=h][,vhostfds=x:y:...:z][,vhostforce=on|off][,queues=n]
                connect the host TAP network interface to VLAN 'n'
                use network scripts 'file' (default=/etc/qemu-ifup)
                use network helper 'helper' (default=/usr/libexec/qemu-bridge-helper) to
                use vnet_hdr=off to avoid enabling the IFF_VNET_HDR tap flag
                use vnet_hdr=on to make the lack of IFF_VNET_HDR support an error condition
                use 'vhostfd=h' to connect to an already opened vhost net device
                use 'vhostfds=x:y:...:z to connect to multiple already opened vhost net devices
-net bridge[,vlan=n][,name=str][,br=bridge][,helper=helper]
                connects a host TAP network interface to a host bridge device 'br'
-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]
-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port[,localaddr=addr]]
-net socket[,vlan=n][,name=str][,fd=h][,udp=host:port][,localaddr=host:port]
-net dump[,vlan=n][,file=f][,len=n]
-net none       use it alone to have zero network devices. If no -net option
                is provided, the default is '-net nic -net user'
-netdev [user|tap|bridge|socket|hubport],id=str[,option][,option][,...]
         [,server][,nowait][,telnet][,mux=on|off] (tcp)
-chardev socket,id=id,path=path[,server][,nowait][,telnet],[mux=on|off] (unix)
                emulate a standard HCI in virtual scatternet 'n'
                add host computer to virtual scatternet 'n' using VHCI
                emulate a bluetooth device 'dev' in scatternet 'n'
其中要使用-net tap項的相關幫助如下:

該配置表示連接宿主機的TAP網絡接口到n號VLAN中,並使用file和dfile兩個腳本在啓動客戶機時配置網絡和在關閉客戶機時取消網絡配置。

tap參數,表明使用TAP設備。TAP是虛擬網絡設備,它仿真了一個數據鏈路層設備(ISO七層網絡結構的第二層),它像以太網的數據幀一樣處理
第二層數據報。而TUN   與TAP類似,也是一種虛擬網絡設備,它是對網絡層設備的仿真。TAP被用於創建一個網絡橋,而TUN與路由相關。

vlan=n  設置該設備VLAN編號,默認值爲0。

name=name  設置名稱,在QEMU monior中可能用到,一般由系統自動分配即可。

fd=h 
連接到現在已經打開着的TAP接口的文件描述符,一般來說不要設置該選項,而是讓QEMU會自動創建一個TAP接口。當使用了fd=h的選項
後,ifname、script、downscript、helper、vnet_hdr等選項都不可使用了(不能與fd選項同時出現在命令行中)。

ifname=name  設置在宿主機中添加的TAP虛擬設備的名稱(如tap1、tap5等等),不設置這個參數時,QEMU會根據系統中目前的情況,產生一個TAP接口的名稱。

script=file  設置宿主機在啓動客戶機時自動執行的網絡配置腳本。如果不指定,其默認值爲“/etc/qemu-ifup”這個腳本,可指定自己的腳本路徑以取代默認值;如果不需要執行腳本,則設置爲“script=no”。

downscript=dfile  設置宿主機在客戶機關閉時自動執行的網絡配置腳本。如果不設置,其默認值爲“/etc/qemu-ifdown”;若客戶機關閉時宿主機不需要執行腳本,則設置爲“downscript=no”。

helper=helper  設置啓動客戶機時在宿主機中運行的輔助程序,包括去建立一個TAP虛擬設備,它的默認值爲/usr/local/libexec/qemu-bridge-helper,一般不用自定義,採用默認值即可。

sndbuf=nbytes  限制TAP設備的發送緩衝區大小爲n字節,當需要流量進行流量控制時可以設置該選項。其默認值爲“sndbuf=0”,即不限制發送緩衝區的大小。

這裏再通如下命令啓動虛擬機:

/usr/libexec/qemu-kvm -m 8096 -cpu qemu64,+vmx -net nic,vlan=0,macaddr=52:54:00:12:34:01 -net tap,vlan=0,ifname=tap0 -smp 4,sockets=4,cores=1,threads=1 -drive file=/data/img/rhce/jiaoshiji.qcow2 -vnc 0.0.0.0:20 &
還是發現最上面提到的報錯,見下圖:

qemu-ifup

三、網絡橋接檢查

通過網上查看相關資料確認需要默認啓動腳本文件/etc/qemu-ifup,經確認本機不存在。另外還需要安裝bridge-utils和tunctl 包,這裏按照順序先進行橋接檢查,再處理上面的報錯。

1、確認bridge使用的包

bridge-utils和tunctl,它們提供所需的brctl、tunctl命令行工具。是使用橋接時必要包,本機之前使用過,已經安裝。未安裝的可以通過如下方式安裝:

# yum install bridge-utils tunctl
2、模塊確認

# lsmod |grep tun
tun                    27183  8 vhost_net
如果tun模塊沒有加載,則運行“modprobe tun”命令來加載即可;當然,如果已經將tun編譯到內核(可查看內核config文件中是否有“CONFIG_TUN=y”選項),則不需要加載了。

3、驗證權限

檢查/dev/net/tun的權限,需要讓當前用戶擁有可讀可寫的權限:

# ll /dev/net/tun
crw-rw-rw- 1 root root 10, 200 10月 20 20:34 /dev/net/tun
4、橋接物理網口

建立一個bridge,並將其綁定到一個可以正常工作的網絡接口上,並讓bridge成爲連接本機與外部網絡的接口。主要的配置命令如下面命令行所示。

# brctl addbr br0    #添加br0這個bridge
# brctl addif br0 eth0    #將br0與eth0綁定起來
# brctl stp br0 on     #將br0加入到STP協議中
# dhclient br0    #將br0的網絡配置好
# route   #參看路由表是否正常配置
注:由於之前已經在virsh中的其他虛擬機使用直接橋接物理網卡的配置,所以以上四步無需配置可以直接跳過。除非在手動安裝的qemu-kvm,並且從未配置橋接的情況下需執行步驟1-4 。

四、解決qemu-ifup報錯

1、增加/etc/qemu-ifup腳本

由於網上已經查到是不存在qemu-ifup 腳本導致,這裏在/etc新建一個qemu-ifup,內容如下:

#!/bin/bash
#This is a qemu-ifup script for bridging.
#You can use it when starting a KVM guest with bridge mode network.
#set your bridge name
switch=br0
if [ -n "$1" ]; then
    #create a TAP interface; qemu will handle it automatically.
    #tunctl -u $(whoami) -t $1
    #start up the TAP interface
    ip link set $1 up
    sleep 1
    #add TAP interface to the bridge
    brctl addif ${switch} $1
    exit 0
else
    echo "Error: no interface specified"
    exit 1
fi
並且需要使用root用戶執行chmod u+x 給以可執行權限。

2、查看brctl 橋接網絡

手動通過qemu-kvm啓動虛擬機前,先通過如下命令查看橋接網絡信息如下:

# brctl show br0
bridge name     bridge id               STP enabled     interfaces
br0             8000.7824af46ca60       no              enp3s0
                                                        vnet0
                                                        vnet1
                                                        vnet2
再手動啓動過虛擬機,未發現報錯,而再查看brctl 的輸出時,發現多了自動啓用了一個tap0網卡,如下:

# brctl show br0
bridge name     bridge id               STP enabled     interfaces
br0             8000.7824af46ca60       no              enp3s0
                                                        tap0
                                                        vnet0
                                                        vnet1
                                                        vnet2
進入虛擬機後,通過配置網絡,通過SecureCRT 連接正常。

五、步驟回溯

手動啓動橋接網絡時,可以將啓動時的script設置爲no ,同樣不會出現上面的截圖中的報錯。

/usr/libexec/qemu-kvm -m 1024 \
-drive file=/data/images/CentOS6_4.qcow2,if=virtio \
-net nic,model=virtio -net tap,script=no -nographic -vnc :0
使用-net tap,script=no方式啓動之後,系統會生成tapX的虛擬網卡,默認是DOWN狀態的

# ip link show dev tap0
37: tap0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 500
    link/ether d2:b0:af:7b:23:0f brd ff:ff:ff:ff:ff:ff
如果想和外界通信,可以手動執行生效,如下所示當前與br0橋接的設備,並沒有tap相關的網卡:

# brctl show br0
bridge name     bridge id               STP enabled     interfaces
br0             8000.7824af46ca60       no              enp3s0
                                                        vnet0
                                                        vnet1
                                                        vnet2
不使用script時,就需要手動去啓新增的網卡,並把tap0也橋接到br0下以便和外界通信,方法如下

# ip link set tap0 up        //使tap0狀態變爲up
# brctl addif br0 tap0        //橋接tap0到br0
# brctl show br0   
通過腳本實現時,如下:

/usr/libexec/qemu-kvm -m 1024 \
-drive file=/data/images/CentOS6_4.qcow2,if=virtio \
-net nic,model=virtio -net tap,script=/tmp/qemu-ifup.sh -nographic -vnc :0
script默認是啓用的,而且位置是/etc/qemu-ifup,這裏也可以指定到另外一個路徑下。tap,script=/tmp/qemu-ifup.sh指定script網絡配置啓動前啓動腳本,腳本內容如下:

# cat /tmp/qemu-ifup.sh
#!/bin/bash
# 橋接網絡設備
switch=br0
if [ -n $1 ]; then          //$1爲qemu-kvm傳遞值,這裏是tap
    ip link set $1 up
    brctl addif ${switch} $1
    exit 0
else
   echo "no interface!"
   exit 1
fi
和上面的腳本內容大致一樣,不過稍微簡化了下,看起來更清爽。

注:brctl delif br0 tap0刪除橋接網絡,qemu-kvm工具在客戶機關閉時會自動解除TAP設備的bridge綁定,所以這一步無需操作。對應downscript,如果想要指定內容如下:

#!/bin/bash
#This is a qemu-ifdown script for bridging.
#You can use it when starting a KVM guest with bridge mode network.
#Don’t use this script in most cases; QEMU will handle it automatically.
#set your bridge name
switch=br0
if [ -n "$1" ]; then
    # Delete the specified interfacename
    tunctl -d $1
    #release TAP interface from bridge
    brctl delif ${switch} $1
    #shutdown the TAP interface
    ip link set $1 down
    exit 0
else
    echo "Error: no interface specified"
    exit 1
fi

以上是雲棲社區小編爲您精心準備的的內容,在雲棲社區的博客、問答、公衆號、人物、課程等欄目也有的相關內容,歡迎繼續使用右上角搜索按鈕進行搜索net , 網絡 , 接口 , 模塊 配置 qemu kvm 橋接、linux qemu kvm、linux kvm 橋接、linux mint kvm橋接、linux kvm 橋接網卡,以便於您獲取更多的相關知識。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章