簡介:如果可以把運維 API 化,那我們是不是可以把 OS 也作為一個 K8S 可以管理的資源,讓 K8S 像管理容器一樣管理OS?
引言
在 2021 年 10 月的雲棲大會上,
不久前,LifseaOS 核心代碼正式在龍蜥社區開源,用戶可以基於 LifseaOS 開源代碼構建、定制一個屬於自己的容器專屬 OS。
WHY LifseaOS?
說到 LifseaOS,不得不提到其主要面向的場景:容器。
從最早的 UNIX chroot,到 Linux 的 LXC,早期以 cgroup、namespace 為基礎的容器運行時技術一直在持續演進,但並沒有出現階段性的突破。直到 2013 年,docker 的出現直接推進了容器的快速普及,經過短短幾年的發展,容器已經成為了主流的 IT基礎設施技術被廣泛地應用。容器的快速發展 docker 功不可沒,而我們回顧當時 docker 最初的工作,可以發現其並沒有進行顛覆性的技術變革,其核心創新主要包括以下兩個部分:
- 定義了容器分層鏡像標准以及鏡像倉庫:容器鏡像將應用運行環境,包括代碼、依賴庫、工具、資源文件和元信息等,打包成一種操作系統發行版無關的不可變更軟件包
- 定義了覆蓋容器全生命周期 restful API:restful API 的將整個容器的創建、監控、銷毀過程標准化,部署、運維人員可以在一個集群內對大量的容器進行統一化的管理
伴隨着容器一起發展的是以容器為基礎衍生而出的容器編排、容器存儲、容器網絡等領域,這些領域緊密結合形成了“雲原生”生態,並且在 2015 年開始,圍繞着 K8S 逐步形成了一套完整的“雲原生操作系統”。通過 K8S,用戶可以在一個分布式集群內快速、高效地部署容器,無需再去關注復雜的集群資源分配、容器調度等工作。為了完整地支持 K8S,雲廠商也進行了大量的 K8S 的支撐對接,紛紛提供適配自身 I 層基礎設施的 CNI(Container Network Interface)、CSI(Container Storage Interface)以及相對應的 cluster-autoscaler 等組件,讓 K8S 可以完美的管理自己的存儲、網絡、計算資源。
- 體積臃腫:傳統的操作系統為了兼容不同的使用場景,包含了各種各樣的硬件驅動、軟件包、系統庫、系統服務等,操作系統后台服務繁多,體積也顯得龐大。在雲原生容器場景下,必要的服務大都已經被容器化,以容器的方式被部署到節點上,通過容器的方式來實現版本、配置的管理,逐步取代了傳統 OS 上的系統服務;同時,雲上硬件資源通過雲廠商的虛擬化抽象往往更加地簡化,並不需要去支持各種硬件。而容器鏡像本身就有運行時自包含的能力,因此很多傳統 OS 上的能力會顯得厚重而冗余,這些厚重的組件還會使整個 OS 啟動變慢並占用相當的系統資源(CPU、內存等)。
- 版本零散:為了能夠支持不同的訴求,操作系統提供了各種各樣不同的軟件,並以軟件包為粒度進行版本管理,每個軟件包有自己獨立的功能以及代碼、版本號,由用戶根據自身的需求進行軟件包的增、刪。這樣每台宿主機上的 OS 狀態是由大量不同軟件包版本號組成的,而在日常運維時一般是針對某一個軟件包進行管理。在雲原生的場景下,集群計算節點日趨增多,生產過程中由於 bugfix、問題定位等可能在某一節點上針對某個包進行管理(升級、配置修改等),如果沒有一套完整的集群 OS 運維機制,極容易出現集群內 OS 狀態不統一的情況,如果在灰度的過程中出現依賴組件版本不一,可能會導致整個發布流程受阻,給運維人員帶來極大的困難。
- 安全風險:一方面,傳統操作系統包含了大量雲原生場景下不需要的軟件包和系統服務,帶來更大的攻擊面。另一方面,傳統操作系統的運維人員大多通過 ssh 登錄進系統進行黑屏的運維操作,過程難以追溯,誤操作極易帶來災難性的后果。
以上的問題主要還是體現在運維上,這時我們回頭看下,在 docker 出現之前,應用的運維人員也有類似的問題:如何保障應用在不同條件下運行環境的匹配一致、如何便捷快速地管理應用等。而 docker 很好地解決了應用層的問題,那是不是我們可以借鑒 docker 的思路來解決 OS 運維的問題?
其實在業界已經有了一些容器優化版操作系統,即我們常說的 ContainerOS,包括 AWS 的 bottlerocket、Redhat 的 Fodera CoreOS 以及 Rancher 的 RancherOS 等,它們大多具有以下特點:
- 輕量化:操作系統僅僅包含足夠支撐容器運行所需的軟件包與系統服務,大大減少攻擊面,啟動快。
- 原子升級回滾:基於不可變基礎設施的設計原則,提供只讀根文件系統保證系統不被惡意篡改,操作系統的管理以鏡像為粒度,不提供 YUM 等包管理軟件,整個系統以鏡像為粒度進行升級與回滾。Bottlerocket 采用了 A/B 雙分區的方式實現鏡像的原子升級,CoreOS 則通過 rpm-ostree 像管理一個 git 代碼倉一樣管理一個 OS 版本,而 RancherOS 則更加激進地把所有的系統服務全部容器化,實現用容器"管理"操作系統鏡像。
- 默認集成雲原生組件:默認安裝 docker/containerd/kubernetes 等雲原生組件,操作系統開箱即用,不需要用戶進行額外的安裝操作,簡單易用。
- 受控的運維通道:系統去除 sshd 服務,不允許直接登錄系統進行運維,同時提供豐富的 API 接口用於主機的運維,另外還提供專用的運維容器作為最后的“退路”用以登錄系統。
這些特點其實也印證了我們的思考:用鏡像的方式解決版本零散的問題,用 API 解決集群運維的問題,而我們更是發現,如果可以把運維 API 化,那我們是不是可以把 OS 也作為一個 K8S 可以管理的資源,讓 K8S 像管理容器一樣管理OS?
LifseaOS:為雲而生的操作系統
基於以上的思考,我們推出了 LifSeaOS,一款為雲原生而生的 OS。
LifseaOS 使用了 rpm-ostree 的功能,實現鏡像的原子性升級回滾,讓用戶可以在集群維度對 OS 鏡像進行 rolling upgrade,像管理牛群一樣管理一整個集群的操作系統;同時做了大量的裁剪優化,使整體 OS 更輕、更快、更安全。
API 化運維更重要的作用是將 OS 運維往雲原生的方向牽引,我們可以通過一個 K8s 的 controller 對接運維 API,結合上述的 OS 版本化,讓 K8s 像管理一個容器一樣管理一個 HostOS。
當然,LifseaOS 的特征不僅僅是以上描述的鏡像版本化和運維 API 化,它的名字也直接闡述了 LifseaOS 作為一個為雲而生、為容器而生的 OS 所具備的特質:
Lightweight
LifseaOS 默認集成 containerd、kubernetes 組件,僅僅保留 kubernetes pods 運行所需的系統服務與軟件包,整個系統大約只有 200 左右的軟件包,相比傳統操作系統(Alibaba Cloud Linux 2/3、CentOS)500+ 軟件包而言,數量減少 60%,更加的輕量。
繁重的 cloud-init(雲廠商常用的雲主機元數據管理組件)套件被替換為 CoreOS 的 Ignition,且裁剪了大量不需要的功能,僅保留最基礎的磁盤擴容、hostname 配置、chronyd 時區同步服務器配置與執行 user-data 腳本的功能。去除了不必要的內核模塊、 systemd 服務(比如 systemd-logind、systemd-resolved)以及 systemd 附帶的許多實用性極低的小工具。
Fast
LifseaOS 的定位是跑在雲上虛擬機的操作系統,所以不會涉及到太多的硬件驅動,必要的內核驅動模塊修改為 built-in 模式,去除了 initramfs,udev 規則也被大大簡化,這樣,啟動速度得到了大幅提升,以 ecs.g7.large 規格的 ECS 實例為例,LifseaOS 的首次啟動時間保持在 2s 左右:
LifseaOS 根文件系統為只讀權限,只有 /etc 和 /var 目錄可寫以滿足基礎的系統配置需求。這種設計既符合雲原生場景下的基礎設施不可變原則,又能防止逃逸容器篡改主機文件系統。不支持 python 但仍然保留了 shell(因為 ACK 在集群部署階段需要執行一系列的 shell 腳本來進行初始化工作,后續會考慮進一步去除)。
另外,LifseaOS 去除了 sshd 服務,禁止用戶直接登錄到系統中進行一系列可能無法追溯的操作;當然,考慮到特殊運維或者緊急運維的需要,LifseaOS 仍然提供一個專用的運維容器滿足非日常的運維需求,運維容器需要通過 API 按需拉起,默認不開啟。
Atomic
LifseaOS 不支持單個 rpm 包的安裝、升級和卸載,不提供 yum,所以去除了 Fedora CoreOS 里的 rpm-ostree 軟件包而僅保留 ostree 的功能(前者提供了以 rpm 包為粒度的管理功能,而后者僅僅管理文件)。以整個鏡像為粒度的更新和回滾極大程度上保證整個集群內的各個節點的軟件包版本與系統配置的一致性。每個鏡像經過內部嚴格的測試之后才會上線,相較於傳統操作系統基於單個 rpm 包的升級帶來的不確定性,以鏡像為粒度的測試發布更能保證升級后系統的穩定性。
原文鏈接
本文為阿里雲原創內容,未經允許不得轉載。