2021-05-12 14:32:11
怎樣在 Ubuntu 和 Debian 中通過命令列管理 KVM
有很多不同的方式去管理執行在 KVM 管理程式上的虛擬機器。例如,virt-manager 就是一個流行的基於圖形介面的前端虛擬機器管理工具。然而,如果你想要在沒有圖形視窗的伺服器環境下使用 KVM ,那麼基於圖形介面的解決方案顯然是行不通的。事實上,你可以單純使用包裝了 kvm 命令列指令碼的命令列來管理 KVM 虛擬機器。作為替代方案,你可以使用 virsh 這個容易使用的命令列程式來管理客戶虛擬機器。在 virsh 中,它通過和 libvirtd 服務通訊來達到控制虛擬機器的目的,而 libvirtd 可以控制多個不同的虛擬機器管理器,包括 KVM,Xen,QEMU,LXC 和 OpenVZ。
當你想要對虛擬機器的前期準備和後期管理實現自動化操作時,像 virsh 這樣的命令列管理工具是非常有用的。同樣,virsh 支援多個管理器也就意味著你可以通過相同的 virsh 介面去管理不同的虛擬機器管理器。
在這篇文章中,我會示範怎樣在 Ubuntu 和 debian 上通過使用 virsh 命令列去執行 KVM。
第一步:確認你的硬體平台支援虛擬化
第一步,首先要確認你的 CPU 支援硬體虛擬化擴充套件(e.g.,Intel VT 或者 AMD-V),這是 KVM 對硬體的要求。下面的命令可以檢查硬體是否支援虛擬化。
$ egrep '(vmx|svm)'--color /proc/cpuinfo
如果在輸出中不包含 vmx 或者 svm 標識,那麼就意味著你的 cpu 不支援硬體虛擬化。因此你不能在你的機器上使用 KVM 。確認了 cpu 支援 vmx 或者 svm 之後,接下來開始安裝 KVM。
對於 KVM 來說,它不要求執行在擁有 64 位核心系統的主機上,但是通常我們會推薦在 64 位系統的主機上面執行 KVM。
第二步:安裝KVM
使用 apt-get
安裝 KVM 和相關的使用者空間工具。
$ sudoapt-get install qemu-kvm libvirt-bin
安裝期間,libvirtd 使用者組(在 debian 上是 libvirtd-qemu 使用者組)將會被建立,並且你的使用者 id 將會被自動新增到該組中。這樣做的目的是讓你可以以一個普通使用者而不是 root 使用者的身份去管理虛擬機器。你可以使用 id
命令來確認這一點,下面將會告訴你怎麼去顯示你的組 id:
$ id<your-userID>
如果因為某些原因,libvirt(在 debian 中是 libvirt-qemu)沒有在你的組 id 中被找到,你也可以手動將你自己新增到對應的組中,如下所示:
在 ubuntu 上:
$ sudo adduser [youruserID] libvirtd
在 debian 上:
$ sudo adduser [youruserID] libvirt-qemu
按照如下命令重新載入更新後的組成員關係。如果要求輸入密碼,那麼輸入你的登陸密碼即可。
$ execsu-l $USER
這時,你應該可以以普通使用者的身份去執行 virsh 了。做一個如下所示的測試,這個命令將會以列表的形式列出可用的虛擬機器(當前的列表是空的)。如果你沒有遇到許可權問題,那意味著到目前為止一切都是正常的。
$ virsh list
IdNameState
第三步:設定橋接網路
為了使 KVM 虛擬機器能夠存取外部網路,一種方法是通過在 KVM 宿主機上建立 Linux 橋來實現。建立之後的橋能夠將虛擬機器的虛擬網絡卡和宿主機的物理網絡卡連線起來,因此,虛擬機器能夠傳送和接收由物理網絡卡傳輸的封包。這種方式叫做網路橋接。
下面將告訴你如何建立並且設定網橋,我們建立一個網橋稱它為 br0。
首先,安裝一個必需的包,然後用命令列建立一個網橋。
$ sudoapt-get install bridge-utils
$ sudo brctl addbr br0
下一步就是設定已經建立好的網橋,即修改位於 /etc/network/interfaces
的組態檔。我們需要將該橋接網絡卡設定成開機啟動。為了修改該組態檔,你需要關閉你的作業系統上的網路管理器(如果你在使用它的話)。跟隨操作指南的說明去關閉網路管理器。
關閉網路管理器之後,接下來就是通過修改組態檔來設定網橋了。
#auto eth0
#iface eth0 inet dhcp
auto br0
iface br0 inet dhcp
bridge_ports eth0
bridge_stp off
bridge_fd 0
bridge_maxwait 0
在上面的設定中,我假設 eth0 是主要網絡卡,它也是連線到外網的網絡卡,同樣,我假設 eth0 將會通過 DHCP 協定自動獲取 ip 地址。注意,之前在 /etc/network/interfaces
中還沒有對 eth0 進行任何設定。橋接網絡卡 br0 參照了 eth0 的設定,而 eth0 也會受到 br0 的制約。
重新啟動網路服務,並確認網橋已經被成功的設定好。如果成功的話,br0 的 ip 地址將會是 eth0 自動分配的 ip 地址,而且 eth0 不會被分配任何 ip 地址。
$ sudo/etc/init.d/networking restart
$ ifconfig
如果因為某些原因,eth0 仍然保留了之前分配給了 br0 的 ip 地址,那麼你可能必須手動刪除 eth0 的 ip 地址。
第四步:用命令列建立一個虛擬機器
對於虛擬機器來說,它的設定資訊被儲存在它對應的xml檔案中。因此,建立一個虛擬機器的第一步就是準備一個與虛擬機器對應的 xml 檔案。
下面是一個範例 xml 檔案,你可以根據需要手動修改它。
<domaintype='kvm'>
<name>alice</name>
<uuid>f5b8c05b-9c7a-3211-49b9-2bd635f7e2aa</uuid>
<memory>1048576</memory>
<currentMemory>1048576</currentMemory>
<vcpu>1</vcpu>
<os>
<type>hvm</type>
<bootdev='cdrom'/>
</os>
<features>
<acpi/>
</features>
<clockoffset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/kvm</emulator>
<disktype="file"device="disk">
<drivername="qemu"type="raw"/>
<sourcefile="/home/dev/images/alice.img"/>
<targetdev="vda"bus="virtio"/>
<addresstype="pci"domain="0x0000"bus="0x00"slot="0x04"function="0x0"/>
</disk>
<disktype="file"device="cdrom">
<drivername="qemu"type="raw"/>
<sourcefile="/home/dev/iso/CentOS-6.5-x86_64-minimal.iso"/>
<targetdev="hdc"bus="ide"/>
<readonly/>
<addresstype="drive"controller="0"bus="1"target="0"unit="0"/>
</disk>
<interfacetype='bridge'>
<sourcebridge='br0'/>
<macaddress="00:00:A3:B0:56:10"/>
</interface>
<controllertype="ide"index="0">
<addresstype="pci"domain="0x0000"bus="0x00"slot="0x01"function="0x1"/>
</controller>
<inputtype='mouse'bus='ps2'/>
<graphicstype='vnc'port='-1'autoport="yes"listen='0.0.0.0'/>
<consoletype='pty'>
<targetport='0'/>
</console>
</devices>
</domain>
上面的主機xml組態檔定義了如下的虛擬機器內容。
-
1GB記憶體,一個虛擬cpu和一個硬體驅動
-
磁碟映象:
/home/dev/images/alice.img
-
從 CD-ROM 引導(
/home/dev/iso/CentOS-6.5-x86_64-minomal.iso
) -
網路:一個橋接到 br0 的虛擬網絡卡
-
通過 VNC 遠端存取
<uuid></uuid>
中的 UUID 字串可以隨機生成。為了得到一個隨機的 uuid 字串,你可能需要使用 uuid 命令列工具。
$ sudoapt-get install uuid
$ uuid
生成一個主機 xml 組態檔的方式就是通過一個已經存在的虛擬機器來匯出它的 xml 組態檔。如下所示。
$ virsh dumpxml alice > bob.xml
第五步:使用命令列啟動虛擬機器
在啟動虛擬機器之前,我們需要建立它的初始磁碟映象。為此,你需要使用 qemu-img 命令來生成一個 qemu-kvm 映象。下面的命令將會建立 10 GB 大小的空磁碟,並且它是 qcow2 格式的。
$ qemu-img create -f qcow2 /home/dev/images/alice.img 10G
使用 qcow2 格式的磁碟映象的好處就是它在建立之初並不會給它分配全部大小磁碟容量(這裡是 10 GB),而是隨著虛擬機器中檔案的增加而逐漸增大。因此,它對空間的使用更加有效。
現在,你可以通過使用之前建立的 xml 組態檔啟動你的虛擬機器了。下面的命令將會建立一個虛擬機器,然後自動啟動它。
$ virsh create alice.xml
Domain alice created from alice.xml
注意: 如果你對一個已經存在的虛擬機器執行了了上面的命令,那麼這個操作將會在沒有任何警告的情況下抹去那個已經存在的虛擬機器的全部資訊。如果你已經建立了一個虛擬機器,你可能會使用下面的命令來啟動虛擬機器。
$ virsh start alice.xml
使用如下命令確認一個新的虛擬機器已經被建立並成功的被啟動。
$ virsh list
IdNameState
----------------------------------------------------
3 alice running
同樣,使用如下命令確認你的虛擬機器的虛擬網絡卡已經被成功的新增到了你先前建立的 br0 網橋中。
$ sudo brctl show
遠端連線虛擬機器
為了遠端存取一個正在執行的虛擬機器的控制台,你可以使用VNC用戶端。
首先,你需要使用如下命令找出用於虛擬機器的VNC埠號。
$ sudonetstat-nap | egrep '(kvm|qemu)'
在這個例子中,用於 alice 虛擬機器的 VNC 埠號是 5900。 然後啟動一個VNC用戶端,連線到一個埠號為5900的VNC伺服器。在我們的例子中,虛擬機器支援由CentOS光碟檔案啟動。
使用 virsh 管理虛擬機器
下面列出了 virsh 命令的常規用法:
建立客戶機並且啟動虛擬機器:
$ virsh create alice.xml
停止虛擬機器並且刪除客戶機:
$ virsh destroy alice
關閉虛擬機器(不用刪除它):
$ virsh shutdown alice
暫停虛擬機器:
$ virsh suspend alice
恢復虛擬機器:
$ virsh resume alice
存取正在執行的虛擬機器的控制台:
$ virsh console alice
設定虛擬機器開機啟動:
$ virsh autostart alice
檢視虛擬機器的詳細資訊:
$ virsh dominfo alice
編輯虛擬機器的組態檔:
$ virsh edit alice
上面的這個命令將會使用一個預設的編輯器來呼叫主機組態檔。該組態檔中的任何改變都將自動被libvirt驗證其正確性。
你也可以在一個virsh對談中管理虛擬機器。下面的命令會建立並進入到一個virsh對談中:
$ virsh
在 virsh 提示中,你可以使用任何 virsh 命令。
問題處理
-
我在建立虛擬機器的時候遇到了一個錯誤:
error: internal error: no supported architecture for os type 'hvm'
如果你的硬體不支援虛擬化的話你可能就會遇到這個錯誤。(例如,Intel VT或者AMD-V),這是執行KVM所必需的。如果你遇到了這個錯誤,而你的cpu支援虛擬化,那麼這裡可以給你一些可用的解決方案:
首先,檢查你的核心模組是否丟失。
$ lsmod|grep kvm
如果核心模組沒有載入,你必須按照如下方式載入它。
$ sudomodprobe kvm_intel (forIntel processor)
$ sudomodprobe kvm_amd (for AMD processor)
第二個解決方案就是新增
--connect qemu:///system
引數到virsh
命令中,如下所示。當你正在你的硬體平台上使用超過一個虛擬機器管理器的時候就需要新增這個引數(例如,VirtualBox,VMware)。$ virsh --connect qemu:///system create alice.xml
-
當我試著存取我的虛擬機器的登陸控制台的時候遇到了錯誤:
$ virsh console alice
error: internal error: cannot find character device <null>
這個錯誤發生的原因是你沒有在你的虛擬機器組態檔中定義控制台裝置。在 xml 檔案中加上下面的內部裝置部分即可。
<consoletype='pty'>
<targetport='0'/>
</console>
--------------------------------------分割線 --------------------------------------
相關文章