此篇文章將會介紹 VM 生命周期管理、Qemu Guest Agent、Virtual Video Card、Graphic Server … 等主題。
VM Lifecycle
在 KVM 中的 virtual machine 共會有以下幾種狀態:
Undefined:未定義
Defined / Shutoff:已定義,libvirtd 已經知道有此 VM 存在,但狀態為關機中(Stopped or Shutdown)
Running:執行中
Shutdown:關機中
Paused:暫停中,VM 記憶體中的資料暫時被保留,並且可以在 guest OS 無法知悉的狀況下回復
Saved:VM 處於完全暫停的狀態,記憶體中的資料被存到一般檔案中,並存在於 persistent storage (可回復到進行 save 時的狀態)
Idle:等待 I/O,或是因為沒有工作需要進行而休眠中
Crashed:可能因為 QEMU process 被強制移除 or core dump 所造成的 VM 損毀
Dying:在 shutdown 的過程中失敗所產生的況狀
Pmsuspended:透過 guest OS 中的電源管理功能進行 suspend 後進入的狀態
有了上面概念後,可以透過 virsh 來檢視目前 domain(virtual machine) 的狀態:
檢視 VM
1 | # 顯示所有 VM (包含關機中的) |
還有許多其他參數可用,使用者可透過
virsh help
orvirsh help list
來查詢更多使用方式
操作 VM
了解 VM 有這麼多狀態之後,自然就會有相對應的操作了,virsh 提供以下幾項對 VM 的操作:
start:啟動 VM
shutdown:關閉 VM (正常關機程序)
reboot:重新啟動 VM
reset:與 power cycle 相同效果
save:將 VM 狀態儲存到檔案中,並關閉 VM
restore:從指定的檔案將 VM 狀態回復為執行中
suspend:暫停 VM 運作
resume:回復 VM 運作
destroy:直接刪除 QEMU process (類似直接拔掉電腦電源線的效果)
create:使用指定的 XML 建立 VM,並啟動 VM
define:使用指定的 XML 建立 VM,但不啟動 VM
undefine:將 VM 從 libvird 的控制中移除
QEMU guest agent
在安裝 virtualbox or VMware 的 VM 時,安裝結束之後都會詢問要不要額外安裝 agent 在 guest VM 中,透過這個 agent,hypervisor 可以更有效率的管理每一個 VM;同樣的在 KVM 中,也是有相同的作法,稱為 QEMU guest agent。
QEMU guest agent 是一個裝在 guest VM 中的套件,會以 service 的形式存在於背景,接著 service 就變成了 hypervisor & guest OS 之間溝通的橋樑(channel),hypervisor 會透過這個 channle 取得 VM 的資訊,以及對 VM 進行後續更多的操作;而兩者相互通訊的協定稱為 **Qemu Machine Protocol(QMP)**。
其中 Hypervisor 與 guest agent 是透過一個名稱為 org.qemu.guest_agent.0
的 virtio-serial channel 或是 isa-serial channel 來處理;而在 Hypervisor 這一端,相對應處理這些資訊交換的 socket file 則是存在於 /var/lib/libvirt/qemu/channel/target
目錄中,且同一個 socket file 可以同時被多個 VM 所共享,因此不會產生太多檔案。
若 guest VM 為 Linux,可安裝名稱為 qemu-guest-agent
的套件,若是 windows,則可以參考以下連結:
除了安裝 qemu-guest-agent
套件之外,還要確認 qemu-guest-agent
service 是否有正確啟動:
1 | $ systemctl status qemu-guest-agent |
確認服務沒有問題,我們就可以使用類似以下的命令在 KVM host 端取得 guest VM 的相關資訊:
1 | $ virsh qemu-agent-command <GUEST_VM_NAME> '{"execute": "guest-info"}' --pretty |
QMP 資料通訊使用 JSON format
Virtual Video cards & graphics
為了可以”看見” VM 的運作狀態,QEMU 需要提供兩個元素來達成這件任務:
virtual video card:讓每個 VM 都擁有一張虛擬的顯示卡
從遠端存取 VM 虛擬顯示卡的方式 or 協定
Virtual Video Card
顯示卡的用途在於顯示圖形資料到顯示設備上,而虛擬顯示卡同樣也是為了這個目的而存在的。
然而在虛擬環境中當然沒有實體顯示卡,因此 QEMU 支援模擬以下幾種顯示卡:
Cirrus:libvirt 預設的顯示卡,可模擬 Cirrus Logic GD5446 顯示卡,Windows 95 之後的作業系統都支援這張顯示卡
VGA:搭配 Bochs VBE extensions 的標準顯示卡,Windows XP 以後的作業系統可以支援(可設定 >= 1280x1024x16 解析度 & 大小的畫質)
VMVGA:在 VGA 再更高階的虛擬顯示卡
QXL:半虛擬化顯示卡,搭配在 VM 內安裝 QXL guest driver,可得到很不錯的顯示效果,而且是搭配 spice protocol 的最佳選擇
在安裝 VM 時,libvirt 就會根據安裝的 OS,協助選擇一個最合適的顯示卡,通常安裝最近發佈的 OS,都會直接選配 QXL;若是 Windows 或是比較舊版的 Linux,可能就會使用 Cirrus。
Graphics
當 VM 有了顯示卡之後,接著需要一個可以存取圖形訊號的方法,在 KVM 中是透過 graphic server 的方式,目前提供了 VNC & *SPICE 兩種 graphic server。
當 VM 確定好顯示卡之後,QEMU 就會啟動相對應的 Spice or VNC server,並與 VM 的顯示卡進行連接,以便讓外部的 client 可以使用圖形化的方式存取 VM。
(1) VNC
要為 VM 設定一個 VNC graphic server,可在 XML 定義檔中的 <device>
section 內部加入類似以下的定義:(IP & port 都可以自己定義)
1 | <graphics type='vnc' port='-1' autoport='yes' listen='192.168.122.1'> |
(2) SPICE
SPICE(Simple Protocol for Independent Computing Environment) 僅有在 Linux 上支援,有以下特色:
可以提供雙向的 audio
高效率的 2D 圖像繪製能力
可利用到 client 端的顯示卡的能力
支援加密、資料壓縮
支援透過網路的 USB passthrough
因此若要規劃把 KVM 用在 VDI 的應用上,使用 QXL
+ SPICE
目前是最好的組合。
要為 VM 設定一個 SPICE graphic server,可在 XML 定義檔中的 <device>
section 內部加入類似以下的定義:(IP & port 都可以自己定義)
1 | <graphics type='spice' autoport='yes' listen='0.0.0.0'> |