簡年6:一個關于 Linux 容器化的腦洞

前幾天看到 KDE Neon 提供了一個 Docker 形式的體驗鏡像,通過掛在數據卷 /tmp/.X11-unix 實現在本地 X 服務上顯示,這得益于 X 服務的分布顯示的特點。

于是突然腦洞一開,如果把整個 Linux 系統的模塊都放進容器中運行的話,Linux 就可以變得非常好玩了。

為了方便大家理解這個腦洞,先上張圖,下面的圖片把兩個不同的桌面環境同時無縫運行在一個桌面,包括軟件和整套桌面:

KDE 和 Pantheon 同時無縫運行

圖中通過共享宿主機顯示服務來達到同時運行的效果,接下來的腦洞中會嘗試把所有模塊都放進容器中,包括顯示服務。

0. 模塊容器化的原因

當前 Linux 的軟件“碎片化”可以說是 Linux 普及的一大攔路虎,發行版之間各自為政,軟件分發渠道不一。另一方面,Linux 在目錄結構上也沒有嚴格的規定,安裝一個軟件往往因為開發者的習慣而不同,裝好的軟件在電腦磁盤中如同垃圾一樣七零八落。盡管有 NixOS 這樣的發行版在努力,但聲勢不大,難成氣候。

所以如果把 Linux 模塊容器化之后,雖然不能夠從根本上解決上面的問題,但是因為隔離了文件系統,一些依賴以及碎片化的軟件得到了一定遏制。最重要的是,如果模塊容器化之后,Linux 在部署、備份上將極為方便。

腦洞不能只是腦洞,我們來看一下如何實現吧。(本文為一邊寫一邊找資料一邊操作驗證,至于結果嘛,看下去吧。)

1. 內核

內核肯定不用容器化了,Docker 靠的就是 Linux 內核支撐,Linux 內核更換也方便,無需 Docker 容器包裝,那么除此之外的其他東西,就都交給 Docker 來做的話,需要考慮哪些方面呢?

2. PID 1

內核啟動的第一個進程,即 PID 1 是整個系統的關鍵部分,我能想到的兩個系統是 CoreOS 和 RancherOS,這兩者都是針對 Docker 而開發的特別發行版。

之所以使用到它們當然是看上了它們對 Docker 的深度整合,CoreOS 使用 systemd 管理容器(似乎),而 RancherOS 更加徹底,直接使用 Docker 管理系統,Docker 甚至是 RancherOS 的 PID 1。

因為本文的腦洞是讓 Docker 容器作為一個桌面運行,也就是 run as a Desktop OS,而不是把 GUI 程序運行在容器中然后顯示在正常操作系統上,也就是 run on a Desktop OS。

要了解兩者差別,需要認識到 X 服務在 Linux 下工作的大致原理。
在此之前,你需要對 GUI 這個名稱有個認識,GUI 全稱是圖形用戶界面(Graphical User Interface),我們平時使用的大部分軟件,例如瀏覽器、辦公軟件、聊天軟件等都是有圖形界面的。

而 Docker 運行 GUI 軟件的技術早就已經不是什么新鮮事了。大部分都是直接通過共享宿主系統的 X11 服務實現 GUI 界面的呈現。而我的腦洞中,是從頭到尾對 Linux 系統的包裝,這自然也包括顯示服務,這意味著我們不可以使用宿主機的顯示服務來顯示 GUI 程序。

2.1 X11 的封裝

以 X11 為例,在 X11 協議中,分為 X11 服務端和 X11 客戶端兩個部分。X11 服務端是用于驅動具體顯示硬件將數據進行展示的模塊,而 X11 客戶端則接收應用程序和用戶的操作,并產生刷新屏幕信息的命令發送給服務端。服務端與客戶端可以是在同一個主機上,也可以通過網絡相連。如下圖所示:

X11 服務示意

接下來,我們遇到一個問題,因為沒有顯示驅動,我們無法顯示界面,即便依靠 GPU 處理也無法顯示出來,這個時候就需要一個小玩意了。

2.2 Xvfb

Xvfb的全稱是 “X virtual frame buffer”,是一種 X11 服務端的特殊實現。說比較特殊是因為 Xvfb 不需要實際的顯示裝置和硬件驅動,它將渲染的圖像內容保存在內存中,最初的應用場景主要是用于自動化測試等不需要看到執行界面的地方,作為完整 X 服務的替代。

在前面已經提過,之所以考慮到使用這個工具,還有一個很重要的原因:輕量。Xvfb的所有文件放在一起只有大約 10MB 的大小(加上一些額外依賴的包,實際增加鏡像的體積大概在幾十 MB)。這樣一種輕量級的 X11 服務器用在 Docker 里面使用實在是在合適不過了,此外,Xvfb也與 CoreOS、RancherOS 不支持圖形顯示、沒有顯示器驅動的情況十分契合。

現在還有個關鍵性的問題:怎樣把內存里的渲染數據表現出來。為此,我們需要引入另一個 Linux 下的工具軟件X11vnc,它提供了將 X11 服務端內容獲取出來并展現到遠程的用戶控制端的功能。

X11 VNC

這樣我們通過VNC客戶端就可以看到界面了。

但是我們饒了一圈,似乎又回來了,到頭來我還是要通過VNC客戶端顯示內容啊,這和直接用宿主機顯示服務有什么區別啊?!

等會,區別還是有的,在本文中顯示的界面少了兩次協議轉換,直接通過 x11vnc 轉發出去,效果十分逼真,延遲感受基本體會不到。

更多的顯示服務

依據這個思路,我們準備在容器里面從零搭建整個 X11 的世界。不過,要是安裝標準的 X11 服務,加上它的各種依賴,少說需要幾百 MB 的額外空間,其他啥都沒裝就把鏡像變大好幾倍了,工程著實浩大。好在開源界已經有了許多種輕量級 X11 服務替代品,例如Xdummy、Xvfb和Xpra。這些平時不太顯眼的寶藏在容器中可以大有作為。當然不嫌棄的話還是 X 大法好,值得一提的是Wayland 與 X 作為顯示服務卻有本質不同,Wayland直接讓軟件與硬件交流,我們沒有機會對 Wayland 封裝,所以這么一看 X 老大爺還是挺有趣的。

作為一個需要對外提供顯示圖形環境的容器,有一些基本的基礎環境需要解決。例如:

  • 軟件源
  • 語言(中文顯示)
  • 系統字體
  • 時區
  • 用戶
  • 基本系統軟件

這些內容就像一個基本的操作系統。用戶可以自由選擇顯示服務,并自由組合桌面環境,也就是說同時運行 Gnome 和 Kde完全沒有問題。

關于 RancherOS 的更大膽腦洞

由于 CoreOS 使用了只讀的系統分區,想在系統上直接安裝一個 X11 服務是行不通的。

但是 RancherOS 不同,我們可以在下面鏈接中看到,老外已經做了個測試,使用一個僅有幾十 MB 的系統跑一個桌面容器,運行良好。
https://forums.rancher.com/t/rancheros-and-sound-module-missing-dev-snd/1799/5

通過更換系統內核,加裝基本配置,一個模塊容器化的 Linux 似乎就在眼前啊。

以上都是腦洞,也許有空時我會動手驗證下,所以記錄一下,保存下來,笑。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容