快轉到主要內容

KVM虛擬機當主力機使用,Linux + Windows的虛擬機多開實踐

分類   Linux系統 Self-hosting自架
標籤   Virtual Desktop Infrastructure Linux Libvirt Moonlight Game Streaming
🗓️ 民國113年 甲辰年
✍ 切換正體/簡體字
目錄

Use virtual machines as daily drivers. Virtualize a home PC and replace it with a thin client that connects to the VMs via remote desktop.

我終於成為「Yes I am Linux user」!How do you know that I am a Linux user?

實際使用場景就像下圖,差別在於我不是用Arch Linux,而是Ubuntu。

嘗試將現有的Linux電腦,轉換為一個兼具「工作 + 遊戲 + AIGC計算 + macOS XCode編譯 + 玩Android遊戲 + BT下載 + NAS」的多功能虛擬機主機,底層的系統得是跑在Linux上的。

並且,將虛擬機系統作為一種類似VDI(桌面虛擬化設施),隨時隨地的使用Thin Client遠端存取桌面。

在GNOME工作區,遠端監看Linux宿主機的資源使用狀況
切換到第二個GNOME工作區,遠端連線到Linux虛擬機桌面

1. 動機
#

以前是一邊操作Linux宿主機,一邊使用虛擬機跑Windows。

因為我想跑的東西實在太雜,所以乾脆結合 過去幾年學到的虛擬機技術,將一切虛擬化,讓我能夠任意分配硬體資源給系統使用。

我知道的東西不是很多,所以這篇文章的內容可能會隨時修正。

這個想法在前幾個月的兩篇文章已然成形:

這次我重新把它polish了一遍,以求未來能以此繼續延展。我還是沒有用Proxmox,而是用Ubuntu搭配Libvirt KVM自行拼出一個虛擬機導向的作業系統。

下面會講選擇Ubuntu當底層作業系統的理由,這裡我要再講些動機方面的東西。第一個,那就是幾年前讀了「編程隨想的博客」補充了我許多虛擬機隔離的想法。第二個,透過Edward Snowden的書了解到Tails OS和Qubes OS的存在,讓我更想嘗試將一切都虛擬化,加強安全性的作法。

這兩個動機聽起來很詭異是吧,既沒有中共國安要抓我,也沒有CIA監控人民的風險,但是,台灣有可能在不遠的未來被那些"glowies glow in the dark"持續蠶食鯨吞人民的權利,所以防患於未然是重要的。

2. 伺服器硬體架構規劃
#

開啟Joplin,用Apple Pencil畫了一上午得出來的構想。

設想

針對這幅靈魂繪圖的解釋。

首先是宿主機硬體規格。

  • CPU:Intel i5-7400,含UHD 630 iGPU內顯
  • RAM:16GB DDR4
  • GPU:4GB VRAM的Nvidia GTX1050Ti
  • 硬碟:總計6TB的空間,但不會全部使用。

將現有的兩個SSD硬碟組成一個LVM Group,取得最大的root空間,不用再額外掛載硬碟到其他路徑導致資料要搬來搬去的。也方便日後擴充硬碟。

宿主機的作業系統安裝標準的Ubuntu Desktop,並啟用LVM。為什麼不選Proxmox或者純伺服器的Linux發行版?因為我還想當普通人,要保有人性(humanity,即Ubuntu這個字的本義),我想當吸血鬼(戴上石鬼面,成為hacker admin)的時候就會拋棄它了。

…其實比較現實的理由是,Libvirt沒有好用的網頁界面,Cockpit還不成熟,所以在起初建置虛擬機胡敬的時候還是有圖形界面跑Virt Manager較好。等一切就緒後圖形界面就能關掉了。

宿主機應當儘量保持精簡,只要做好Hypervisor的調度工作就行了,除了SSH和Libvrit虛擬機等必要軟體以外一律不安裝,UFW防火牆全部封鎖。因為我不會用LXC(吐舌),就連Docker和Podman都是在虛擬機裡面跑的。

然後,手邊有幾個HDD,他們有各自的用途,所以不會成為LVM Group的一部分。

3. 虛擬機規劃
#

計畫安裝三個虛擬機:

  1. 第一個是使用我慣用的KDE桌面的Linux虛擬機,做主力,直通Intel GPU,負擔基本3D加速。
  2. 專門跑self-hosted服務的headless Linux虛擬機,主要跑Docker和Podman,直通Nvidia GPU跑AI運算。
  3. Windows虛擬機,直通Nvidia GPU玩遊戲。

以上是最常用的三個,剩下的就按照需求臨時加開虛擬機。如果有必要,虛擬機應該啟用Secure Boot和FDE全硬碟加密。

既然虛擬機都是跑在區域網路,我有想過,或許虛擬機可以用PXE從網路硬碟開機的?但為了效能考量還是採用比較常見的作法,即一個系統一個qcow2硬碟。

因為Libvirt有超賣(overcommiting)機制,所以CPU和RAM可以有效利用。多個虛擬機同時執行的是可能的,閒置的虛擬機資源會被其他虛擬機拿去用。不過就實務來看上,同時跑Linux和Windows虛擬機就差不多吃乾i5-7400的所有資源了(該死的Windows Update)。倒是跑兩個Linux虛擬機比較滋潤,所以我不會讓Windows虛擬機一直在線上,會一直在線上的是Linux的虛擬機。

就算虛擬機全部下線,宿主機也不會關機。我已經做好長期不關機的準備,要買UPS了。

4. 遠端存取虛擬機的手段
#

當你啟用VFIO隔離了電腦上所有的GPU,等同封鎖了它輸出螢幕的能力,故開機後會完全沒畫面,得用SSH登入。

將宿主機連上Tailscale網路,組成私人VPN通訊網,這樣就能用手機或者其他電腦遠端登入操作。另外雖然Cockpit界面很爛,我還是啟用了,聊勝於無。

要連線到虛擬機,一般的遠端桌面是滿足不了我的,所以不使用虛擬顯示卡,不用SPICE或VNC,而是將GPU直通給虛擬機,再於區域網路做高品質桌面串流。目前試下來最順的就是Moonlight + Sunshine的搭配了。Looking Glass不能在非本機以外的網路傳輸,所以淘汰。

除了Moonlight外我還準備了備用的遠端桌面連線手段,因為它們都是Libvirt建立的虛擬機,因此GPU串流出問題的話還可以在Virt Manager插SPICE,再用VNC或RDP遠端進入桌面除錯。最不濟還有SSH能登入。

而如果是那種不能裝遠端桌面,又需要圖形效能的特殊虛擬機系統(例如BlissOS)我還有一招,那就是使用USB擷取卡獲得螢幕畫面,於其他虛擬機裡面檢視那個虛擬機的畫面。

5. 硬體直通做法
#

Libvirt可以將宿主機的任意USB裝置或PCI裝置直通給虛擬機使用。

首先是GPU,透過VFIO,將Nvidia GPU完全隔離,它就是一個讓各個虛擬機允取允求的資源,一次只能由一個虛擬機使用。不搞一對多的vGPU,因為太麻煩,且4GB VRAM也沒什麼好拆分的。

至於Intel iGPU,也是透過VFIO直通,而非選擇壓搾Intel iGPU到極限,用GVT-g功能分給兩個虛擬機使用。因為經過測過,iGPU直通原本是能負擔1080p60串流的,但啟用GVT-g後VRAM砍半就撐不了,位元率必須降得很低才行,而且虛擬機的解析度還會被限制住,這樣我不喜歡。

替代方案:用不怎麼吃GPU效能的RustDesk來存取桌面,即使iGPU VRam砍半也能負荷。但是,RustDesk延遲太高了。

以上兩個要直通的GPU都有插著一塊顯示器或者HDMi欺騙器,以確保能發揮顯示卡最大效能。

接著是其他硬體裝置。虛擬機的網路上網都是透過Libvirt的NAT虛擬網路,不過我特別做了橋接網路讓虛擬機能從外網存取。僅是為了區網傳輸方便,防火牆還是有開,且為了通訊安全大部分時候都是用SSH或VPN之類的加密通訊。

若是為了降低虛擬機輸入與輸出延遲,購買USB Hub,將滑鼠與鍵盤與喇叭插在Hub上,再將該Hub直通給單一虛擬機使用,就可達致最低延遲。

6. 將單個硬碟共享給多個虛擬機
#

有個HDD資料碟得在多個虛擬機間共享,例如跑Podman服務的虛擬機需要存取照片,我又想在主力桌面環境虛擬機直接開照片。

所以我不直通硬碟給單一虛擬機,而是透過網路檔案系統傳輸。

為了安全性和維護容易,選擇SSHFS,備用方案NFS + Kerberos。所有的虛擬機皆得透過遠端連線到宿主機,間接讀取資料碟上的檔案。


然後還有虛擬機玩遊戲問題。利用Steam硬碟資料庫共享原理,將一個專門裝遊戲的實體硬碟給Linux和Windows虛擬機使用。

為了速度考量,不採用SSHFS,而是直通。在Linux和Windows虛擬機間共享遊戲,這樣能測試Proton的執行效果,也能夠順利的於Linux虛擬機玩遊戲。此外利用VFIO原理,Nvidia GPU可以在虛擬機關機之下任意分配給虛擬機,Sunshine會在開機後自動啟動,不問Nvidia還是iGPU都能開始串流。

7. 準備Thin Client遠端存取
#

Thin Client是使用硬體較弱的裝置存取虛擬機桌面的電腦。

這就叫"Thin client",識得唔識得呀?

對VDI而言,這又稱之為VDI Client

沒有多餘的電腦,所以就地利用,將樹莓派拿出來,從伺服器轉做桌面用途。

雖然Android、iPad接上螢幕也可以當電腦用,但是這是次佳的選擇。樹莓派配上GNOME桌面才有真正多工,方便管理多視窗的虛擬機。

Thin Client的東西要盡量精簡,只裝遠端桌面軟體,負責透過區域網路連線到Ubuntu和管理虛擬機,除此之外Thin Client不可以登入任何帳號,所有正式的工作都應該在虛擬機內部完成。

8. 架設過程
#

  1. 把重要資料備份到最大的HDD
  2. 抹除系統,重裝Ubuntu Desktop,啟用LVM
  3. 設定SSH與 Taiscale服務
  4. 安裝 Libvirt KVM,安裝Linux和Windows虛擬機
  5. 設定 橋接器網路
  6. 安裝 Cockpit網頁服務
  7. 確認虛擬機就緒後,切換到Thin Client,遠端登入操作
  8. 直通Nvidia GPU 直通Intel GPU,測試VFIO功能是否正常。
  9. 設定遠端桌面功能,包括SSH、 RustDesk Moonlight + Sunshine等等。
  10. 正式拔除圖形環境,使用指令sudo systemctl set-default multi-user.target設定Ubuntu開機進入純文字模式。

9. 實際使用體驗&未解決的問題
#

利用Moonlight遠端到Linux虛擬機日常上網、玩遊戲,因為是區域網路沒什麼問題,只是偶爾會延遲。因為每個虛擬機的資源分配不均,加上4核心的CPU根本吃不消,容易一個虛擬機開始做大量操作就影響到主力虛擬機的正常使用。例如,Linux主力機的喇叭爆音就知道整個系統的CPU過載了;在區域網路搬移許多檔案的時候會導致遠端桌面連線跟著塞車。使用下來體驗不佳,甚至比我以前一邊操作宿主機,一邊使用虛擬機的體驗還差勁。

正如我上面說的,硬體效能限制了我的想像。目前的硬體實在不能同時跑兩個以上的虛擬機,會引發宿主機的OOM Killer,亦不適合一邊正常使用一邊當伺服器。因此未來全面升級硬體是必須的,最好升級到10核心以上CPU、16GB VRAM的GPU,還有32GB以上的RAM。主機板最好可以插兩個GPU,一個AMD一個Nvidia(或者至少CPU要有強力內顯),供給多個虛擬機使用。

此外我沒有把備份納入考量,所以硬體方面未來要再搞個RAID。

因此在短暫試驗幾天之後,我又回到了以前的模式:宿主機恢復圖形界面,改GPU直通搭配Moonlight存取虛擬機。服務直接在宿主機用Docker跑就好。

相關討論
#

相關文章

Moonlight自動調整Linux遠端桌面解析度,解決黑邊問題
分類   Linux系統 Self-hosting自架
標籤   Moonlight Game Streaming Linux
Cockpit教學:用網頁瀏覽器管理QEMU/KVM虛擬機,替代Virt Manager
分類   Linux系統 Self-hosting自架
標籤   Libvirt PCI Passthrough GPU Passthrough QEMU-KVM Podman Docker Linux
Sunshine:Linux版Moonlight教學,自架免費雲端串流遊戲服務+遠端桌面
分類   Linux系統 Self-hosting自架 Linux玩遊戲
標籤   Moonlight Game Streaming Cloud Gaming Remote Desktop Steam Linux

留言板

此處提供二種留言板。點選按鈕,選擇您覺得方便的留言板。要討論程式碼請用Giscus,匿名討論請用Disqus。

這是Giscus留言板,需要Github帳號才能留言。支援markdown語法,若要上傳圖片請貼Imgur或Postimages。您的留言會在Github Discussions向所有人公開。

這是Disqus留言板,您可能會看到Disqus強制投放的廣告。為防止垃圾內容,有時留言可能會被系統判定需審核,導致延遲顯示,請見諒。若要上傳圖片請善用圖床網站。