在前邊的部落格中我們介紹瞭如何建立kvm虛擬機器,以及一些常用的工具的介紹和使用,今天我們來了解下kvm原始工具qemu-kvm;為什麼說qemu-kvm是一個原始的工具呢,如果你用kvm虛擬機器,心細的你一定會發現我們不管用什麼工具建立kvm虛擬機器,在宿主機上表現的都是一個以/usr/libexec/qemu-kvm的程式;這意味著我們之前用的工具它們都呼叫了qemu-kvm這個工具來建立虛擬機器,從而我們在宿主機上看到的都是qemu-kvm程式;如下所示:
提示:以上centos7這個虛擬機器是我們之前使用virt-install這個工具在命令列中直接建立的;
qemu-kvm這個工具是使用kvm虛擬機器時核心工具,從上面的程式資訊可以看到,它可以完整的實現一個虛擬機器例項,模擬出各種IO裝置;其實我們在使用核心kvm功能時,我們只安裝qemu-kvm就可以使用qemu-kvm這個使用者空間工具來使用核心kvm功能了;
好了,接下來我們來看看這個神奇的工具qemu-kvm吧!!qemu-kvm這個工具預設安裝以後,它會把二進位制檔案放到/usr/libexec/這個目錄下,它這樣做的主要目的是不讓使用者直接在命令列執行它,為了我們不用每次都寫絕對路徑,我們可以把這個工具連結到我們的PATH環境變數的目錄下。
1、連結qemu-kvm到/usr/bin/目錄下
[root@node1 ~]# ll /usr/libexec/qemu-kvm -rwxr-xr-x 1 root root 5259704 5月 12 23:44 /usr/libexec/qemu-kvm [root@node1 ~]# ln -sv /usr/libexec/qemu-kvm /usr/bin/ "/usr/bin/qemu-kvm" -> "/usr/libexec/qemu-kvm" [root@node1 ~]# ll /usr/bin/qemu-kvm lrwxrwxrwx 1 root root 21 8月 21 18:20 /usr/bin/qemu-kvm -> /usr/libexec/qemu-kvm [root@node1 ~]#
2、檢視qemu-kvm的幫助
提示:從上面的過濾資訊可瞭解到,qemu-kvm這個工具有標準選項,塊裝置相關選項,usb相關選項,顯示相關選項,網路相關選項,字元裝置相關選項,引導相關選項等等;
3、qemu-kvm工具使用語法格式
[root@node1 ~]# qemu-kvm -h QEMU emulator version 1.5.3 (qemu-kvm-1.5.3-173.el7_8.3), Copyright (c) 2003-2008 Fabrice Bellard WARNING: Direct use of qemu-kvm from the command line is not supported by Red Hat. WARNING: Use libvirt as the stable management interface. WARNING: Some command line options listed here may not be available in future releases. usage: qemu-kvm [options] [disk_image] 'disk_image' is a raw hard disk image for IDE hard disk 0
提示:從上面的幫助資訊可以看到,qemu-kvm這個工具使用很簡單,就是qemu-kvm +一堆選項來建立虛擬機器;
4、qemu-kvm標準選項
-machine [type=]name:-machine help是用來獲取支援的主機型別列表,該選項用來指定虛擬主機的型別;支援的型別有kvm, xen, tcg,預設不指定是tcg型別;
-cpu cpu:-cpu help來獲取支援的cpu型別列表;用於指定要模擬的CPU型號;-cpu hsot表示模擬和宿主機一樣訊號的cpu
-smp n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets]:用於指定cpu架構,其中socket表示有幾顆CPU;cores表示每顆cup有幾核心;threads表示每個CPU核心有機執行緒;maxcpus=socket*cores*threads;n等於小於maxcpus即可;
-boot [order=drives][,once=drives][,menu=on|off] [,splash=sp_name][,splash-time=sp_time][,reboot-timeout=rb_time][,strict=on|off]:該選項用於指定啟動裝置順序的;order:各裝置的引導次序:c表示第一塊硬碟,d表示第一個光碟機裝置;-boot order=dc,once=d;once表示第一次啟動使用什麼裝置引導,once=d表示第一次啟動使用光碟機裝置引導;
-m megs:以M為單位指定虛擬機器的記憶體大小;
-name NAME:指定當前虛擬機器的名稱,要惟一;
5、塊裝置相關的選項
-hda/-hdb file:指明IDE匯流排型別的磁碟對映檔案路徑;第0和第1個;依次類推-hdc/-hdd file就表示第2和第3個IDE型別的磁碟;通常這種方式使用的很少,比較常用的方式是直接用-drive 來指定裝置匯流排的型別;
-cdrom file:指定要使用光碟映像檔案;
-drive [file=file][,if=type][,media=d][,index=i] [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]:用來指定虛擬裝置的相關屬性;其中file表示映像檔案;if=TYPE:塊裝置匯流排型別,常用的匯流排型別有ide, scsi, sd, floppy, virtio等等;media=TYPE:介質型別,常用的介質型別有cdrom和disk;index=i:設定同一型別裝置多個裝置的編號;cache=writethrough|writeback|none|directsync|unsafe:快取方式;none表示不使用cache;format=f:磁碟映像檔案的格式;
6、顯示相關選項
-display type:顯示的型別,sdl, curses, none和vnc;
-nographic:不使用圖形介面; 不使用圖形介面就表示沒有顯示卡,沒有顯示卡就只能使用串列埠來序列顯示;
-vga [std|cirrus|vmware|qxl|xenfb|none]:模擬出的顯示卡的型號;
-vnc display[,option[,option[,...]]]]:啟動一個vnc server來顯示虛擬機器介面; 讓qemu程式監聽一個vnc介面;在前邊的部落格中我們也介紹過vnc,vnc會與視窗號進行關聯,第0號視窗就對應宿主機的5900埠;我們可以這樣理解,第n號視窗,它對應宿主機上的埠就是5900+n;這裡的n是從0開始;通常我們這裡指定的都是視窗號;當然也是可以值指定監聽的地址和埠,也可以指定密碼;
-monitor stdio:在標準輸出上顯示monitor介面;Ctrl-a, c:在console和monitor之間切換;
7、網路相關選項
-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]:用於指定建立虛擬機器時在虛擬機器上對應的介面相關屬性;model=type:指明模擬出的網路卡的型號,常用的網路卡型號有ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet,virtio;可以使用qemu-kvm -net nic,model=?來檢視支援虛擬的網路卡型號;macaddr=mac:指明mac地址;預設是52:54:00:開頭;
-net tap[,vlan=n][,name=str][,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile]:用於指定建立虛擬機器時在宿主機上對應的介面相關屬性;script=file:啟動虛擬機器時要執行的指令碼,預設為/etc/qemu-ifup(一般需要手動編寫);downscript=dfile:關閉虛擬機器時要執行的指令碼,/etc/qemu-ifdown(不需要手動編寫,它自身就可以不依賴指令碼從而解除安裝掉相關介面);ifname=NAME:自定義介面名稱;
8、其他選項
-daemonize:以守護程式執行;
好了,簡單的瞭解了上述的選項以後我們就可以來使用qemu-kvm建立一個虛擬機器了;
示例:用qemu-kvm來建立虛擬機器
準備工作
建立磁碟,這個步驟如果還不熟悉,請參考我的部落格《虛擬化技術之kvm磁碟管理工具qemu-img》;
[root@node1 ~]# ll /kvm/images/ 總用量 1560712 -rw-r--r-- 1 qemu qemu 1598226432 8月 21 19:08 centos7.qcow2 [root@node1 ~]# qemu-img create -f qcow2 /kvm/images/test.img 5G Formatting '/kvm/images/test.img', fmt=qcow2 size=5368709120 encryption=off cluster_size=65536 lazy_refcounts=off [root@node1 ~]# ll /kvm/images/ 總用量 1560908 -rw-r--r-- 1 qemu qemu 1598226432 8月 21 19:08 centos7.qcow2 -rw-r--r-- 1 root root 197120 8月 21 19:18 test.img [root@node1 ~]#
準備/etc/qemu-ifup指令碼
#!/bin/bash bridge=br0 if [ -n "$1" ];then ip link set $1 up sleep 1 brctl addif $bridge $1 [ $? -eq 0 ]&& exit 0 || exit 1 else echo "Error:no interface specified." exit 1 fi
提示:以上指令碼就做了一件事,判斷傳過來的網路卡是否存在,如果存在就把它關聯到$bridge指定的橋上,並啟動起來;如果傳過來的網路卡名稱不存在,則報錯沒有指定的網路卡,然後退出;最後別忘記給這個指令碼加上可執行許可權;
檢視宿主機上是否有br0,沒有就建立一個br0,並把宿主機網路卡ens33橋接到br0上;
[root@node1 ~]# ifconfig -a ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.0.41 netmask 255.255.255.0 broadcast 192.168.0.255 inet6 fe80::20c:29ff:fe9a:dbd6 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:9a:db:d6 txqueuelen 1000 (Ethernet) RX packets 3943 bytes 356924 (348.5 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 2719 bytes 545299 (532.5 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 40 bytes 3112 (3.0 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 40 bytes 3112 (3.0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 virbr0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255 ether 52:54:00:45:06:15 txqueuelen 1000 (Ethernet) RX packets 285 bytes 18774 (18.3 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 246 bytes 19814 (19.3 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 virbr0-nic: flags=4098<BROADCAST,MULTICAST> mtu 1500 ether 52:54:00:45:06:15 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vnet0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::fc54:ff:feff:51f1 prefixlen 64 scopeid 0x20<link> ether fe:54:00:ff:51:f1 txqueuelen 1000 (Ethernet) RX packets 285 bytes 22764 (22.2 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 4051 bytes 217914 (212.8 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@node1 ~]#
提示:從上面的輸出資訊可以看到br0並不存在;
手動建立br0配置檔案,並修改ens33的配置檔案
[root@node1 network-scripts]# cat ifcfg-br0 TYPE=Bridge NAME=br0 DEVICE=br0 ONBOOT=yes IPADDR=192.168.0.41 PREFIX=24 GATEWAY=192.168.0.1 DNS1=192.168.0.1 [root@node1 network-scripts]# cat ifcfg-ens33 TYPE=Ethernet NAME=ens33 DEVICE=ens33 ONBOOT=yes BRIDGE=br0 [root@node1 network-scripts]#
重啟網路
[root@node1 network-scripts]# systemctl restart network [root@node1 network-scripts]# [root@node1 network-scripts]# ifconfig br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.0.41 netmask 255.255.255.0 broadcast 192.168.0.255 inet6 fe80::cc1c:b2ff:fe49:1138 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:9a:db:d6 txqueuelen 1000 (Ethernet) RX packets 20 bytes 2000 (1.9 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 36 bytes 4708 (4.5 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether 00:0c:29:9a:db:d6 txqueuelen 1000 (Ethernet) RX packets 4544 bytes 411254 (401.6 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 3108 bytes 608414 (594.1 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 40 bytes 3112 (3.0 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 40 bytes 3112 (3.0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 virbr0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255 ether 52:54:00:45:06:15 txqueuelen 1000 (Ethernet) RX packets 287 bytes 18878 (18.4 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 248 bytes 19946 (19.4 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vnet0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::fc54:ff:feff:51f1 prefixlen 64 scopeid 0x20<link> ether fe:54:00:ff:51:f1 txqueuelen 1000 (Ethernet) RX packets 287 bytes 22896 (22.3 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 4312 bytes 231514 (226.0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@node1 network-scripts]#
提示:如果重啟網路後,crt沒有斷開,說明我們配置的網路沒有問題;從上面的資訊可以看到br0已經建立,並且擁有一個地址我們在配置檔案中指定的ip地址,而ens33它直接橋接到br0上了;
準備好以指令碼,磁碟檔案,網路環境後,我們就可以來建立一個橋接到br0的虛擬機器
[root@node1 network-scripts]# virsh list --all Id 名稱 狀態 ---------------------------------------------------- 1 centos7 running [root@node1 network-scripts]# qemu-kvm -name test \ > -smp 2,maxcpus=4,sockets=2,cores=2 \ > -m 1024 \ > -cpu host \ > -drive file=/kvm/images/test.img,media=disk,if=virtio,cache=writeback,format=qcow2, \ > -drive file=/kvm/iso/CentOS-7-x86_64-Minimal-1708.iso,media=cdrom \ > -boot order=dc,once=d \ > -vnc :1 \ > -net nic,macaddr=52:54:00:00:00:01,model=virtio \ > -net tap,script=/etc/qemu-ifup \ > -daemonize [root@node1 network-scripts]# virsh list --all Id 名稱 狀態 ---------------------------------------------------- 1 centos7 running [root@node1 network-scripts]#
提示:預設直接手動使用qemu-kvm建立的虛擬機器,在virsh list 中是看不到的;
提示:從上面的截圖來看,我們建立的虛擬機器應該正常跑起來了,我們指定的1號視窗對應的埠已經處於監聽狀態,在程式列表中也能看到我們手動執行的命令也執行成程式;
驗證:用vnc連線宿主機的1號視窗,看看是否有虛擬機器執行?
提示:通過vnc連線1號視窗,可以看到我們指定的虛擬機器已經建立好,正等著我們去裝系統;
提示:裝好系統以後,我們需要關閉虛擬機器(直接kill掉宿主機對應的程式即可),啟動虛擬機器時我們需要把光碟機給解除安裝掉(不指定光碟機裝置),或者修改啟動次序,不然它會一直以光碟機做系統引導;
關閉虛擬機器
修改啟動次序,再次啟動虛擬機器
提示:這裡我們在原有的命令上,把once=d修改成once=c,其他選項都不要變;意思本次建立虛擬機器,第一引導裝置上是第一塊硬碟;
現在用vnc連線宿主機的1號視窗,看看虛擬機器裡裝的系統是否啟動起來了呢?
提示:可以看到虛擬機器裡的系統已經正常啟動了;從上面的過程來看,qemu-kvm本質上沒有像virt-manager那樣用圖形介面建立虛擬機器,裝系統簡單,我們需要手動的去指定各種裝置,以及解決啟動順序,網路等等問題;所以通常qemu-kvm是通過一個磁碟映象模板(就是裝有系統的磁碟檔案),然後配合網路環境來啟動虛擬機器;
從上面vnc連線虛擬機器控制檯看,eth0處於關閉狀態,接下來我們把eth0啟動起來,看看它是否獲取同宿主機br0橋上同網段的ip地址呢?
提示:臨時啟動eth0以後,可以看到eth0上就獲取到了一個192.168.0.0網段地址,和宿主機br0在同一網段,說明虛擬機器的網路是橋接到宿主機上的物理網路卡上;以上是臨時啟動eth0,如果要開機自動啟動,需要修改其配置檔案即可;