前幾天看到 KDE Neon 提供了一個(gè) Docker 形式的體驗(yàn)鏡像定嗓,通過掛在數(shù)據(jù)卷
/tmp/.X11-unix
實(shí)現(xiàn)在本地 X 服務(wù)上顯示挥等,這得益于 X 服務(wù)的分布顯示的特點(diǎn)贺拣。
于是突然腦洞一開,如果把整個(gè) Linux 系統(tǒng)的模塊都放進(jìn)容器中運(yùn)行的話阅畴,Linux 就可以變得非常好玩了盯滚。
為了方便大家理解這個(gè)腦洞,先上張圖趟薄,下面的圖片把兩個(gè)不同的桌面環(huán)境同時(shí)無縫運(yùn)行在一個(gè)桌面绽诚,包括軟件和整套桌面:
圖中通過共享宿主機(jī)顯示服務(wù)來達(dá)到同時(shí)運(yùn)行的效果,接下來的腦洞中會(huì)嘗試把所有模塊都放進(jìn)容器中杭煎,包括顯示服務(wù)恩够。
0. 模塊容器化的原因
當(dāng)前 Linux 的軟件“碎片化”可以說是 Linux 普及的一大攔路虎,發(fā)行版之間各自為政羡铲,軟件分發(fā)渠道不一蜂桶。另一方面,Linux 在目錄結(jié)構(gòu)上也沒有嚴(yán)格的規(guī)定也切,安裝一個(gè)軟件往往因?yàn)殚_發(fā)者的習(xí)慣而不同扑媚,裝好的軟件在電腦磁盤中如同垃圾一樣七零八落。盡管有 NixOS 這樣的發(fā)行版在努力雷恃,但聲勢(shì)不大疆股,難成氣候。
所以如果把 Linux 模塊容器化之后倒槐,雖然不能夠從根本上解決上面的問題旬痹,但是因?yàn)楦綦x了文件系統(tǒng),一些依賴以及碎片化的軟件得到了一定遏制讨越。最重要的是两残,如果模塊容器化之后,Linux 在部署把跨、備份上將極為方便人弓。
腦洞不能只是腦洞,我們來看一下如何實(shí)現(xiàn)吧节猿。(本文為一邊寫一邊找資料一邊操作驗(yàn)證票从,至于結(jié)果嘛漫雕,看下去吧。)
1. 內(nèi)核
內(nèi)核肯定不用容器化了峰鄙,Docker 靠的就是 Linux 內(nèi)核支撐浸间,Linux 內(nèi)核更換也方便,無需 Docker 容器包裝吟榴,那么除此之外的其他東西魁蒜,就都交給 Docker 來做的話,需要考慮哪些方面呢吩翻?
2. PID 1
內(nèi)核啟動(dòng)的第一個(gè)進(jìn)程兜看,即 PID 1 是整個(gè)系統(tǒng)的關(guān)鍵部分,我能想到的兩個(gè)系統(tǒng)是 CoreOS 和 RancherOS狭瞎,這兩者都是針對(duì) Docker 而開發(fā)的特別發(fā)行版细移。
之所以使用到它們當(dāng)然是看上了它們對(duì) Docker 的深度整合,CoreOS 使用 systemd 管理容器(似乎)熊锭,而 RancherOS 更加徹底弧轧,直接使用 Docker 管理系統(tǒng),Docker 甚至是 RancherOS 的 PID 1碗殷。
因?yàn)楸疚牡哪X洞是讓 Docker 容器作為一個(gè)桌面運(yùn)行精绎,也就是 run as a Desktop OS,而不是把 GUI 程序運(yùn)行在容器中然后顯示在正常操作系統(tǒng)上锌妻,也就是 run on a Desktop OS代乃。
要了解兩者差別,需要認(rèn)識(shí)到 X 服務(wù)在 Linux 下工作的大致原理仿粹。
在此之前搁吓,你需要對(duì) GUI 這個(gè)名稱有個(gè)認(rèn)識(shí),GUI 全稱是圖形用戶界面(Graphical User Interface)牍陌,我們平時(shí)使用的大部分軟件擎浴,例如瀏覽器员咽、辦公軟件毒涧、聊天軟件等都是有圖形界面的。
而 Docker 運(yùn)行 GUI 軟件的技術(shù)早就已經(jīng)不是什么新鮮事了贝室。大部分都是直接通過共享宿主系統(tǒng)的 X11 服務(wù)實(shí)現(xiàn) GUI 界面的呈現(xiàn)契讲。而我的腦洞中,是從頭到尾對(duì) Linux 系統(tǒng)的包裝滑频,這自然也包括顯示服務(wù)捡偏,這意味著我們不可以使用宿主機(jī)的顯示服務(wù)來顯示 GUI 程序。
2.1 X11 的封裝
以 X11 為例峡迷,在 X11 協(xié)議中银伟,分為 X11 服務(wù)端和 X11 客戶端兩個(gè)部分你虹。X11 服務(wù)端是用于驅(qū)動(dòng)具體顯示硬件將數(shù)據(jù)進(jìn)行展示的模塊,而 X11 客戶端則接收應(yīng)用程序和用戶的操作彤避,并產(chǎn)生刷新屏幕信息的命令發(fā)送給服務(wù)端傅物。服務(wù)端與客戶端可以是在同一個(gè)主機(jī)上,也可以通過網(wǎng)絡(luò)相連琉预。如下圖所示:
接下來董饰,我們遇到一個(gè)問題,因?yàn)闆]有顯示驅(qū)動(dòng)圆米,我們無法顯示界面卒暂,即便依靠 GPU 處理也無法顯示出來,這個(gè)時(shí)候就需要一個(gè)小玩意了娄帖。
2.2 Xvfb
Xvfb的全稱是 “X virtual frame buffer”也祠,是一種 X11 服務(wù)端的特殊實(shí)現(xiàn)。說比較特殊是因?yàn)?Xvfb 不需要實(shí)際的顯示裝置和硬件驅(qū)動(dòng)近速,它將渲染的圖像內(nèi)容保存在內(nèi)存中齿坷,最初的應(yīng)用場(chǎng)景主要是用于自動(dòng)化測(cè)試等不需要看到執(zhí)行界面的地方,作為完整 X 服務(wù)的替代数焊。
在前面已經(jīng)提過永淌,之所以考慮到使用這個(gè)工具,還有一個(gè)很重要的原因:輕量佩耳。Xvfb的所有文件放在一起只有大約 10MB 的大兴熘(加上一些額外依賴的包,實(shí)際增加鏡像的體積大概在幾十 MB)干厚。這樣一種輕量級(jí)的 X11 服務(wù)器用在 Docker 里面使用實(shí)在是在合適不過了李滴,此外,Xvfb也與 CoreOS蛮瞄、RancherOS 不支持圖形顯示所坯、沒有顯示器驅(qū)動(dòng)的情況十分契合。
現(xiàn)在還有個(gè)關(guān)鍵性的問題:怎樣把內(nèi)存里的渲染數(shù)據(jù)表現(xiàn)出來挂捅。為此芹助,我們需要引入另一個(gè) Linux 下的工具軟件X11vnc,它提供了將 X11 服務(wù)端內(nèi)容獲取出來并展現(xiàn)到遠(yuǎn)程的用戶控制端的功能闲先。
這樣我們通過VNC客戶端就可以看到界面了状土。
但是我們饒了一圈,似乎又回來了伺糠,到頭來我還是要通過VNC客戶端顯示內(nèi)容啊蒙谓,這和直接用宿主機(jī)顯示服務(wù)有什么區(qū)別啊训桶?累驮!
等會(huì)酣倾,區(qū)別還是有的,在本文中顯示的界面少了兩次協(xié)議轉(zhuǎn)換谤专,直接通過 x11vnc 轉(zhuǎn)發(fā)出去灶挟,效果十分逼真,延遲感受基本體會(huì)不到毒租。
更多的顯示服務(wù)
依據(jù)這個(gè)思路稚铣,我們準(zhǔn)備在容器里面從零搭建整個(gè) X11 的世界。不過墅垮,要是安裝標(biāo)準(zhǔn)的 X11 服務(wù)惕医,加上它的各種依賴,少說需要幾百 MB 的額外空間算色,其他啥都沒裝就把鏡像變大好幾倍了抬伺,工程著實(shí)浩大。好在開源界已經(jīng)有了許多種輕量級(jí) X11 服務(wù)替代品灾梦,例如Xdummy峡钓、Xvfb和Xpra。這些平時(shí)不太顯眼的寶藏在容器中可以大有作為若河。當(dāng)然不嫌棄的話還是 X 大法好能岩,值得一提的是Wayland 與 X 作為顯示服務(wù)卻有本質(zhì)不同,Wayland直接讓軟件與硬件交流萧福,我們沒有機(jī)會(huì)對(duì) Wayland 封裝拉鹃,所以這么一看 X 老大爺還是挺有趣的。
作為一個(gè)需要對(duì)外提供顯示圖形環(huán)境的容器鲫忍,有一些基本的基礎(chǔ)環(huán)境需要解決膏燕。例如:
- 軟件源
- 語言(中文顯示)
- 系統(tǒng)字體
- 時(shí)區(qū)
- 用戶
- 基本系統(tǒng)軟件
這些內(nèi)容就像一個(gè)基本的操作系統(tǒng)。用戶可以自由選擇顯示服務(wù)悟民,并自由組合桌面環(huán)境坝辫,也就是說同時(shí)運(yùn)行 Gnome 和 Kde完全沒有問題。
關(guān)于 RancherOS 的更大膽腦洞
由于 CoreOS 使用了只讀的系統(tǒng)分區(qū)射亏,想在系統(tǒng)上直接安裝一個(gè) X11 服務(wù)是行不通的近忙。
但是 RancherOS 不同,我們可以在下面鏈接中看到鸦泳,老外已經(jīng)做了個(gè)測(cè)試银锻,使用一個(gè)僅有幾十 MB 的系統(tǒng)跑一個(gè)桌面容器,運(yùn)行良好做鹰。
https://forums.rancher.com/t/rancheros-and-sound-module-missing-dev-snd/1799/5
通過更換系統(tǒng)內(nèi)核,加裝基本配置鼎姐,一個(gè)模塊容器化的 Linux 似乎就在眼前啊钾麸。
以上都是腦洞更振,也許有空時(shí)我會(huì)動(dòng)手驗(yàn)證下,所以記錄一下饭尝,保存下來肯腕,笑。