在 CachyOS 安裝 Virt-manager 的必要依賴與服務
我在 CachyOS 遷移心得 2 提到了為什麼要從 VMware Workstation 遷移到 Virt-manager,想知道我替換原因的可以回去看那篇文章。
這篇會著重在換到 Virt-manager 怎麼安裝 Virt-manager 以及部分比較方便的功能怎麼還原。
Ubuntu 安裝 Virt-manager 時候很多東西會跟著包進來,甚至開啟必要的服務,Kubuntu 24.04 更是預設就裝好和設定好,但是 CachyOS 安裝 Virt-manager 時,僅會安裝必要,能夠順利開啟 Virt-manager 介面的依賴。
由於 Virt-manager 是 libvirt 的 GUI 前端,所以很多依賴和設定你會需要去看 libvirt 會比較準確,包括 QEMU 或者服務的部分。
我在用 Shelly 安裝時它有詢問可選依賴的部分,我把上面跳出來建議安裝的都有勾上,所以會預先安裝好一部分可選依賴,我會以此為基礎說明要額外安裝哪些東西。
如果對我踩坑過程沒興趣的,可以跳到看 Docs 那段
如果沒看 Docs 裝好直接開會踩到的坑
正確的連線協定
如果你像我一樣安裝時看到錯誤,預設是走 LXC,或者沒開啟 QEMU 協定應該會看到類似的錯誤

首先在上面選「檔案」,然後按「新增連線」,然後選「QEMU/KVM」

如果選使用者工作階段除了只能在家目錄建立虛擬機以外,網路也只能用 libvirt 的 NAT ,不能用 Linux Bridge 或者 OVS ,同時幾乎不能 VFIO。
然後你可能會碰到以下錯誤
無法連接至 libvirt qemu:///system。
請驗證是否有適當的 'libvirtd' 守護程式正在運轉。
Libvirt URI is: qemu:///system
Traceback (most recent call last):
File "/usr/share/virt-manager/virtManager/connection.py", line 940, in _do_open
self._backend.open(cb, data)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/usr/share/virt-manager/virtinst/connection.py", line 173, in open
conn = libvirt.openAuth(self._open_uri, [valid_auth_options, authcb, cbdata], open_flags)
File "/usr/lib/python3.14/site-packages/libvirt.py", line 148, in openAuth
raise libvirtError('virConnectOpenAuth() failed')
libvirt.libvirtError: Failed to connect socket to '/var/run/libvirt/virtqemud-sock': 沒有此一檔案或目錄
以這個錯誤來說,如果你夠聰明會用 Tab 大法,只輸入 virtq 你會看到 virtqemud.socket 和 virtqemud.service。
仔細閱讀過錯誤的你,剛好又是比較傳統的維運派,可能會說「上面不是缺 virtqemud-sock 嗎?那就是開啟 virtqemud.service 阿。」
我們來看一下兩者的區別:
~
❯ sudo systemctl status virtqemud.service
○ virtqemud.service - libvirt QEMU daemon
Loaded: loaded (/usr/lib/systemd/system/virtqemud.service; disabled; preset: disabled)
Active: inactive (dead)
TriggeredBy: ○ virtqemud-admin.socket
○ virtqemud.socket
○ virtqemud-ro.socket
Docs: man:virtqemud(8)
https://libvirt.org/
~
❯ sudo systemctl status virtqemud.socket
○ virtqemud.socket - libvirt QEMU daemon socket
Loaded: loaded (/usr/lib/systemd/system/virtqemud.socket; disabled; preset: disabled)
Active: inactive (dead)
Triggers: ● virtqemud.service
Listen: /run/libvirt/virtqemud-sock (Stream)
事實上這裡的 Socket 跟我們傳統意義上的 Socket 不太一樣,總之你要看 Triggers 和 TriggeredBy,如果看到 TriggeredBy,那就代表你應該除了打開 virtqemud.socket 以外,另外兩個我也建議打開,Socket 開著本身也不占據資源 (Port 除外)。
virtqemud-admin.socket是用來管理virtqemud本身的 Socket (對應指令是virt-admin)
virtqemud-ro.socket則是用以唯讀模式訪問 libvirt ,比如用virsh -c qemu:///system?readonly連線
由於 Service vs Socket 的坑很多,所以我日後應該會因此寫一篇 Blog 介紹 Systemd 的 Service 和 Socket 的區別。
啟動指令如下:
sudo systemctl enable --now virtqemud.socket
在 CachyOS 啟動 virtqemud.socket 就會啟動另外兩個 Socket:
Created symlink '/etc/systemd/system/sockets.target.wants/virtqemud.socket' → '/usr/lib/systemd/system/virtqemud.socket'.
Created symlink '/etc/systemd/system/sockets.target.wants/virtqemud-ro.socket' → '/usr/lib/systemd/system/virtqemud-ro.socket'.
Created symlink '/etc/systemd/system/sockets.target.wants/virtqemud-admin.socket' → '/usr/lib/systemd/system/virtqemud-admin.socket'.
如果少了另外兩個就手動輸入這些指令就好:
sudo systemctl enable --now virtqemud-ro.socket
sudo systemctl enable --now virtqemud-admin.socket
狀態檢查:
~
❯ sudo systemctl status virtqemud.socket
● virtqemud.socket - libvirt QEMU daemon socket
Loaded: loaded (/usr/lib/systemd/system/virtqemud.socket; enabled; preset: disabled)
Active: active (listening) since Mon 2026-05-25 00:45:50 CST; 1min 51s ago
Invocation: e273e42f5d0843e18e9fbaf9c064c0ee
Triggers: ● virtqemud.service
Listen: /run/libvirt/virtqemud-sock (Stream)
5月 25 00:45:50 CachyOS-X870-Elite-Ice systemd[1]: Listening on libvirt QEMU daemon socket.
~
❯ sudo systemctl status virtqemud.service
○ virtqemud.service - libvirt QEMU daemon
Loaded: loaded (/usr/lib/systemd/system/virtqemud.service; disabled; preset: disabled)
Active: inactive (dead)
TriggeredBy: ● virtqemud-admin.socket
● virtqemud.socket
● virtqemud-ro.socket
Docs: man:virtqemud(8)
https://libvirt.org/
好了,接著你終於可以連線了,他會要你輸入 sudo 密碼。
但不對阿,我怎麼每次打開 Virt-manager 變成都要輸入 root 密碼?
Virt-manager 安裝時有個 libvirt,把要能擁有完整存取權使用者加進來就可以不用 root 身份執行了
sudo usermod -aG libvirt $USER
加入到群組後記得要登出後大概等 5 秒再登入,如果登出登入一樣要輸入密碼,那下次重新開機就不用輸入密碼了。
補充:
libvirt 因為只是控制 VM 平台的 API,所以除了 KVM/QEMU 他也能連線 Hyper-V、ESXi 、 Xen 和 Bhyve 等 Hypervisor。
QEMU 安裝
你以為這就完了嗎?不!這時候按新增虛擬機你會看到前面還有一個坑:

一般來說如果你有開啟虛擬化,那基本上 Linux 都會開啟 KVM,可以用以下指令做檢測 KVM 開啟狀態:
lsmod | grep kvm
然後輸出應該要類似這個樣子,有 KVM 相關 mod 啟用資訊:
# AMD
kvm_amd 253952 0
kvm 1540096 1 kvm_amd
irqbypass 16384 1 kvm
ccp 233472 1 kvm_amd
# Intel
kvm_intel 417792 0
kvm 1396736 1 kvm_intel
irqbypass 12288 1 kvm
如果沒有,記得去 BIOS/UEFI 開啟虛擬化;如果有那這時就是缺 QEMU 了。
回到我們的 Shelly,我們去看 libvirt,可以看到可選依賴有 QEMU,而且有 3 個 QEMU:

好了,這時候該安裝哪個呢?我們來列出 3 種 QEMU 的差異吧:
qemu-base: 僅有最基礎的 CLI 工具,用於無頭環境,包括qemu-system-x86和virtiofsd,也是qemu-desktop和qemu-full的依賴項。qemu-desktop: 多了 USB redirect、GUI 顯示套件和 SPICE 協定等工具,基本上要讓 KVM/QEMU VM 操作起來有接近 VMware 的感覺這個必不可少。qemu-emulators-full: 所有 QEMU 能模擬的架構的模擬器,包括 S390X、SPARC 和各種活得或成為考古的架構,非必要 (而且非 x86 VM 不會走 KVM ,只會走純 QEMU,效率很差)。
如果你是看 Ivon 的文章,你可能會看到他安裝的是 qemu-full,這個就是把你能看到的 qemu-* 都裝進來,各種你用的到的,用不到的都會裝進來,除非你會今天開 Windows VM,明天科技考古跑個 SPARC 的 Solaris,後天會直接在你電腦編譯給 ARM 電腦用的 Container,否則不要安裝這麼一大包東西。
所以我們要安裝的是 qemu-desktop,這邊繼續以 Shelly 為例,安裝時會有一堆可選依賴可以安裝,這裡我只多裝 qemu-tools,這個套件可以提供大量 VM 的管理介面

新建虛擬機在 QEMU 會先碰到的坑
這時候終於可以新增虛擬機了對吧?洋洋灑灑的按下新增,然後到了第二步,你就會發現手動指定了 iso 路徑,結果 iso 內的 OS 無法檢測,也無法被指定

不然就是你要新增儲存池然後提示無法新增

這時候輸入 sudo systemctl enable --now virtstoraged.socket 把錯誤提示上的 Virt-manager 的儲存服務開啟,然後就會把對應的 socket 全部打開,跟 virtqemud.socket 一樣,如果只開一個就手動開啟剩下的。
~
❯ sudo systemctl enable --now virtstoraged.socket
Created symlink '/etc/systemd/system/sockets.target.wants/virtstoraged.socket' → '/usr/lib/systemd/system/virtstoraged.socket'.
Created symlink '/etc/systemd/system/sockets.target.wants/virtstoraged-ro.socket' → '/usr/lib/systemd/system/virtstoraged-ro.socket'.
Created symlink '/etc/systemd/system/sockets.target.wants/virtstoraged-admin.socket' → '/usr/lib/systemd/system/virtstoraged-admin.socket'.
這時候終於可以順利選擇 iso 和識別系統了,然後到了最後一步,沒有預設網路,裝好了 QEMU 怎麼還有這麼多坑😭

這時候就需要開啟 libvirt 的 Network 相關的 Socket,這樣子至少有最基本的 Default Network 可以用
sudo systemctl enable --now virtnetworkd.socket
一樣也是有三個 Socket 會同時開啟,輸出如下,如果沒同時開啟就另外把兩個補上:
~
❯ sudo systemctl enable --now virtnetworkd.socket
Created symlink '/etc/systemd/system/sockets.target.wants/virtnetworkd.socket' → '/usr/lib/systemd/system/virtnetworkd.socket'.
Created symlink '/etc/systemd/system/sockets.target.wants/virtnetworkd-ro.socket' → '/usr/lib/systemd/system/virtnetworkd-ro.socket'.
Created symlink '/etc/systemd/system/sockets.target.wants/virtnetworkd-admin.socket' → '/usr/lib/systemd/system/virtnetworkd-admin.socket'.
其他可能會碰到的坑
到此終於能建立虛擬機了…才怪,還有一堆服務沒開,比如負責實體裝置管理的 virtnodedevd 沒開,處理防火牆規則的 virtnwfilterd 也沒開,網卡也有一個 virtinterfaced 也要開,我踩坑踩到這裡終於看到了 Docs ,讓我們來看一下 libvirt 正確的啟動方式是什麼。
Docs 中啟動 libvirt 的方式
根據 Libvirt Daemons 的部分,他詳細介紹了 libvirt 裡面的各種 Daemons 的用途,這裡我先跟你說看哪裡實作,再來說為什麼要這樣做。
如果你跟我一樣,是剛裝好 Virt-manager 然後半個 daemons 都沒啟動的狀況下,前兩步可以直接跳過,從第三步開始看。
然後到這裡你應該會覺得「奇怪?Service 不是會被自動觸發?為什麼還要 enable service?」
問得好,我們把目光放回前面介紹 driver sockets 的地方,在 Monolithic/Modular Systemd Integration 的 libvirtd.service 和 virt${DRIVER}d.service 部分有說明:
If it is known that autostart is not required, this unit can be left to start on demand.
如果確定虛擬機自動啟動不是必要的,那設定為按需啟動即可。
並且在第四步時也有說明:
Start the sockets for the same set of daemons. There is no need to start the services as they will get started when the first socket connection is established
啟動 Sockets 時會啟動同組的 daemons。無需手動啟動服務,因為服務會在 Sockets 接收到連線後自動啟動
原理麻…我前面踩坑說過了,Systemd 的 Service 和 Sockets 的區別很有意思,所以我日後有時間我會想好好說明和比較。
你只要知道 Service 就是會常駐後臺,Socket 就只是開個 Port,等收到連線才會啟動服務。
那以我的情況來說,我不需要開機自動啟動 VM ,要用 VM 的時候我會打開 Virt-manager (或者使用 virsh) 才會啟動並操控 VM。
我們也知道 --now 是可以 enable 同時 start 服務的參數,所以我們可以把啟動指令縮減成一行,那官方用的是 bash ,CachyOS 預設用 fish ,所以我會把 bash 和 fish 的兩種語法都放上來。
bash:
for drv in qemu interface network nodedev nwfilter secret storage
do
# 如果要 autostart 再解注解 .service 相關指令
# sudo systemctl unmask virt${drv}d.service
sudo systemctl unmask virt${drv}d{,-ro,-admin}.socket
# sudo systemctl enable --now virt${drv}d.service
sudo systemctl enable --now virt${drv}d{,-ro,-admin}.socket
done
fish:
for drv in qemu interface network nodedev nwfilter secret storage
# 如果要 autostart 再解注解 .service 相關指令
# sudo systemctl unmask virt{$drv}d.service
sudo systemctl unmask virt{$drv}d.socket
sudo systemctl unmask virt{$drv}d{-ro,-admin}.socket
# sudo systemctl enable --now virt{$drv}d.service
sudo systemctl enable --now virt{$drv}d.socket
sudo systemctl enable --now virt{$drv}d{-ro,-admin}.socket
end
你應該會看到類似以下輸出:
Created symlink '/etc/systemd/system/sockets.target.wants/virt${drv}d.socket' → '/usr/lib/systemd/system/virt${drv}d.socket'.
Created symlink '/etc/systemd/system/sockets.target.wants/virt${drv}d-ro.socket' → '/usr/lib/systemd/system/virt${drv}d-ro.socket'.
Created symlink '/etc/systemd/system/sockets.target.wants/virt${drv}d-admin.socket' → '/usr/lib/systemd/system/virt${drv}d-admin.socket'.
自行把
${drv}替換成其他服務,你應該會看到 7 * 3 = 21 行輸出
如果你有打算讓遠端主機可以連線控制,那還要多開一個 proxy socket:
bash:
# 按需再開
# sudo systemctl enable virtproxyd.service
sudo systemctl unmask virtproxyd{,-ro,-admin}.socket
sudo systemctl enable --now virtproxyd{,-ro,-admin}.socket
fish:
# 按需再開
# sudo systemctl enable virtproxyd.service
sudo systemctl unmask virtproxyd.socket
sudo systemctl unmask virtproxyd{-ro,-admin}.socket
sudo systemctl enable --now virtproxyd.socket
sudo systemctl enable --now virtproxyd{-ro,-admin}.socket
這樣子能在其他機器使用 libvirt 連線了,如果你有憑證想走 TLS ,也可以多開這條:
sudo systemctl enable --now virtproxyd-tls.socket
如果有問題,或者想要檢查,可以用以下指令檢查,如果是 active 就代表有啟用,若未啟用則會輸出 inactive 並且 return 3 (拿 QEMU 連線為例):
sudo systemctl is-active virtqemud.socket
如果想要完整檢查可以用這個腳本:
bash:
for drv in qemu interface network nodedev nwfilter secret storage
do
# sudo systemctl unmask virt${drv}d.service
sudo systemctl is-active virt${drv}d{,-ro,-admin}.socket
done
fish:
for drv in qemu interface network nodedev nwfilter secret storage
sudo systemctl is-active virt{$drv}d.socket
sudo systemctl is-active virt{$drv}d{-ro,-admin}.socket
end
不算遠端連線的情況下應該要看到 21 個 active ,不會有任何 inactive,如果有就要去開服務或確認 socket status。
如果有開遠端,把 proxy 放上去和獨立檢查 virtproxyd-tls (如果 TLS 也有開)就好。
剩下會踩到的坑
該開的服務開好後你會踩到的坑大概會剩下 QEMU 安裝(可以回到踩坑記錄看一下,這裡不再贅述),以及剩下比較零散的坑。
先說說系統安裝的部分,微軟推出 Windows 11 後要求系統一定要有 TPM (這裡不說在 CMD 可以 bypass 這件事),那在 libvirt + KVM/QEMU 的情況下,我們需要額外安裝一個套件,可以產生模擬的 TPM ,這個套件就是 swtpm。
swtpm 也是 libvirt 的可選依賴之一,它可以模擬 TPM 硬體讓 VM 使用,如果安裝 Virt-manager 沒有跳出這個套件,重新回到 Shelly 或 pacman 安裝即可

你可能還會問「有 TPM,那 OVMF (UEFI) 呢?」
OVMF 的套件是 edk2-ovmf,他本身就是 qemu-base 底下的 qemu-system-x86 的依賴,安裝 qemu-desktop 時作為必要依賴已經安裝了進來,所以不用另外安裝。
其他推薦套件
libvirt 和 qemu-desktop 有些套件如果有需求我也會建議安裝,大概是這些:
- samba: 當 virtiofsd 效率太差時可以考慮走 SMB,讓 host 和 guest 透過網路分享檔案,但我更傾向於在 guest 開 Share folder 或者安裝 Samba
qemu-user和qemu-user-static: 如果你有跨平臺開發的需求,可以考慮安裝這兩個套件到電腦上,讓 host 直接能運行非 x86 的軟體,比如 ARM 的執行檔,前者讓你可以在系統上運行,後者在此之上還具備可以編譯並打包非 x86 架構使用的 Container。
一些使用心得
當從 VMware 重新回到 Virt-manager 時,因為這次本來帶著不少的前置理解回來,所以當我成功讓 Virt-manager 可以建立虛擬機時,建立虛擬機的各項設定從被包裝好的抽象層,變成都是可以獨立調整,用以適配各種狀況的設定,或者是可以很清楚的看到軟體用什麼方式模擬這些硬體。
這屬於把掌握權基本全數交給使用者,但是代價是你認真要搞懂需要學習很多東西,光是 OVMF 就有 3 種設定。
除此之外,Virt-manager 的網路設定也是一個大坑,我本來只打算獨立一篇用來說明 KVM/QEMU + Virt-manager 可以怎麼規劃網路,以及還原 VMnet 甚至是更進階的操作,但還記得 CachyOS 遷移心得 1 我有說過 CachyOS 預設開啟 ufw 嗎?
這件事在安裝 Virt-manager 時成為了大坑,所以又獨立了一篇文出來,我先說結論:
virbr0 這個 NAT 界面是個下限極低,但上限極高的存在,大部分發行版沒開防火牆裝好就好,但一開防火牆整個除錯流程會大幅增加,同時如果沒有 ufw 這類比較高階抽象的存在,理論上可以在 host NAT 公開服務。
大概就是這樣,所以我的待寫清單越來越多了…