如果你持續關注DevOps周刊,DevOps主題的會議或是對技術真正感興趣,你也許已經聽說Unikernel很多次了。在過去的幾個月,它似乎越來越受關注。
然而,究竟什麼是Unikernel? 它是我想要的東西嗎?
我糾結這個問題許久。不知如何定義Unikernel以及它存在的意義?
真相的來源僅僅是Wikipedia上的一段晦澀的解釋,我們先看看:
Unikernel是通過使用專門的庫操作系統來構建的單地址空間機器鏡像。開發者通過選擇棧模塊和一系列最小依賴庫來運行應用,而這些棧和庫對應於操作系統中運行應用所必需的依賴。
這些庫負責應用和配置代碼編譯,構建成封閉的、固定用途的鏡像(即 Unikernel)可以直接在虛擬機管理程序(hypervisor)或硬件上運行,不需要類似Linux或Windows的操作系統介於其中。
---- 維基百科:Unikernel
都清楚了,對嗎?
好吧,如果是我,或許以上並沒有說太多。接下來是我對Unikernel的解釋。
首先讓我們跟著這裡例子回顧一下。假設你是一個開發者在寫PHP應用。當你運行你的PHP(其他Ruby、Node、Perl均類似)應用,你本質上是在運行:
說老實話,如果你在抽象一個應用程序構建所需的所有層次,這會是一個奇跡般的工作。
但是他們做到了。並且做得非常好,有較好的性能。但是你必須認識到,在提供應用運行環境的硬件到應用程序本身存在許多層。
那就是Unikernel試圖解決的:刪除應用與硬件中間臃腫的部分。讓最“精簡”的操作系統運行你的代碼。
這裡有一篇論文總結得非常好:
Unikernel的願景:當你看到雲客戶端時就像看到單應用硬件一樣。
- The Rise and Fall of the Operating System
Unikernel試圖抹去現代操作系統帶來的一些復雜性。因為“通用”的操作系統(就像任何Linux和Windows的發行版),通常會伴隨著帶來一些對你的應用來說並不需要的驅動、依賴包、服務、等等,但這些對每一個操作系統來說某種程度上又是必需的。
甚至是在Linux內核的核心模塊都並不是需要每一次都完全加載。像USB驅動這類東西在虛擬化的“雲”環境被認為是無用的,但仍然會被包含在內核中。
相比容器和虛擬化,Unikernel所呈現的演進如下圖:
(來源:road_to_unikernels)
unikernels.png
Unikernel對比通用的操作系統例如Linux有許多優勢:
這樣我們非常自然的把Unikernel當作是微服務的備選方案。
如果你運行應用之後想要它的開銷是最小的,那你就可能要考慮制作一個Unikernel。
為此,要使用庫操作系統(LibOS)。一個庫操作系統會給你提供構建自己的Unikernel的方式。最值得關注的是MirageOS(術語“unikernel”的創造者)和Rump Kernels。兩者本質上都是一系列標准化的驅動和庫,這樣你就不需要重復發明像TCP棧、持久存儲層等這類東西。
Unikernel是用高級語言定制的操作系統內核,並且作為獨立的軟件構件。完整的應用(或應用系統)作為一個分布式系統運行在一套unikernels上。
MirageOS基於OCaml語言並且讓unikernels運行在Xen hypervisor上。
-- queue.acm.org: Unikernels: Rise of the Virtual Library Operating System
目前最流行的用來寫unikernel的語言是:
這些並不都是新的編程語言。除了Go和Rust,其他均有超過15年的歷史。
為了使操作系統和應用運行得更加流暢,這些unikernel庫需要使用內核部分盡可能小。
現在,由於虛擬化技術,像Xen或VMware這類虛機管理系統(注*:原Operating System)把異構的硬件設備抽象成一堆標准的虛擬化設備,unikernel也能為定制的虛擬設備而優化。
Unikernel利用虛擬化的優勢創造出一種專屬的經過優化的操作系統。
想要編譯應用程序的“unikernel”,需要依賴MirageOS的庫和OCaml語言,結果像這樣:
編譯器輸出一個完全獨立的內核取代Unix可執行文件。這些unikernels是只為滿足特定的應用程序和配置文件而實現的庫操作系統VM,並且會依賴hypervisor提供的資源復用和隔離。
--- queue.acm.org: Unikernels: Rise of the Virtual Library Operating System
最終你通過運行一個Unikernel,精簡專屬的操作系統,來運行你應用程序的一部分。如果你的應用和配置需要更新,你需要重新編譯你的源碼來生成新的Unikernel並部署新版本。如果是新的安全升級?也同樣需要重新編譯和部署。
這將使部署的協調和編排更加困難,但好處是運行應用程序更加高效。
構建不可變的基礎設施架構的關鍵在於:應用程序不再保存狀態,並且能方便地丟棄和重新構建。
一方面,我們可以讓Unikernel運行在Docker容器中,但是是否應該盡量避免增加其他復雜的中間層?另一方面,Docker在使用和部署上的優勢確實可以彌補這點中間層的開銷。
實話實說,這個問題的答案對我來說還並不明確。我認為說如果你現在是要在WordPress上部署web應用,使用Unikernel也許還有一定的鴻溝。
另一方面,Unikernel的好處是明顯的,但需要一個完全不同的模式來管理你的基礎設施,一組不同的技能來構建這類的應用和內核並且需要深谙目前對我們來說還完全陌生的一個概念:不可變的基礎設施架構。
也許在今後的5至10年,我們會以新的規范一樣來部署Unikernel。目前,我認為它針對一小部分想要相當專業和安全應用的用戶。對於大多數普通用戶,虛機(或是,如果你走在技術前沿一定會明白:Docker容器)或許才是你應該專注的。
如果您對這個主題感興趣,推薦您一些相關鏈接: