本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

rktnetes 將 rkt 容器引擎帶入 Kubernetes

編者註: 這篇文章是關於 Kubernetes 1.3 新功能的系列深入文章的一部分

作為 Kubernetes 1.3 的一部分,我們很高興地宣布,我們為 Kubernetes 帶來可互換容器引擎的工作已初見成果。我們親切地稱之為「rktnetes」的功能已包含在 Kubernetes 1.3 版本中,並已準備好供開發使用。rktnetes 將 CoreOS rkt 的支援整合到 Kubernetes 中,作為叢集節點上的容器執行期,現在已成為 Kubernetes 主線原始碼的一部分。如今,對於那些考慮容器可攜性的開發人員和運維專業人員來說,嘗試使用不同的容器引擎運行 Kubernetes 比以往任何時候都更加容易。

PayPal 服務 Xoom 的資深 MTS 和架構師 Mark Petrovic 表示:「我們發現 CoreOS 的 rkt 在 Kubernetes 中是一個引人注目的容器引擎,因為 rkt 是如何與底層 systemd 組合的。rkt 執行期僅承擔其需要的責任,然後在適當情況下委派給其他系統服務。這種關注點分離對我們來說非常重要。」

什麼是 rktnetes?

rktnetes 是賦予 Kubernetes 節點能夠使用 rkt 容器引擎(而不是 Docker)執行應用程式容器的程式碼的暱稱。此變更為 Kubernetes 新增了新功能,例如在彈性的隔離層級下運行容器。rkt 探索了一種容器執行期架構的替代方法,旨在反映 Unix 哲學的清晰分離、模組化工具。為支援 rktnetes 所做的工作也為 Kubernetes 開啟了未來的可能性,例如多個容器映像檔格式支援,以及整合針對特定使用案例或平台量身定制的其他容器執行期。

為何 Kubernetes 需要 rktnetes?

rktnetes 不僅僅關於 rkt。它還關於改進和實踐 Kubernetes 介面,並為未來其他模組化執行期鋪路。雖然 Docker 容器引擎廣為人知,並且目前是預設的 Kubernetes 容器執行期,但可插拔的容器環境帶來了許多好處。例如,某些叢集可能需要非常特定的容器引擎實作,而確保 Kubernetes 設計具有足夠的彈性來支援替代執行期(從 rkt 開始)有助於保持組件之間介面的清晰和簡潔。

關注點分離:分解單體式容器守護程序

Kubernetes 目前使用的容器執行期施加了許多設計決策。在如此快速發展的領域中,實驗其他容器執行架構是值得的。如今,當 Kubernetes 向節點發送啟動 Pod 運行的請求時,它會透過每個節點上的 kubelet 與預設容器執行期的中央守護程序通信,該守護程序負責管理節點的所有容器。

rkt 沒有實作單體式容器管理守護程序。(值得注意的是,預設容器執行期正在重構其原始的單體式架構。)rkt 設計從一開始就嘗試充分應用模組化原則,包括重複使用經過充分測試的系統組件,而不是重新實作它們。

建置容器映像檔的任務在 rkt 中從容器執行期核心中抽象化出來,並由獨立的工具實作。對持續的容器生命週期管理也採取相同的方法。單一二進制檔案 rkt 配置環境並準備容器映像檔以供執行,然後設定容器應用程式及其隔離環境運行。此時,rkt 程式已完成其「一項工作」,容器隔離器接管。

Kubernetes 用於追蹤每個節點上叢集工作的查詢容器引擎和 Pod 狀態的 API,在獨立的服務中實作,將協調和編排功能與核心容器執行期隔離。雖然 API 服務尚未完全實作目前預設容器引擎的所有 API 功能,但它已協助將容器與核心執行期中的故障和升級隔離,並為查詢容器元數據提供預期 API 的唯讀部分。

模組化容器隔離層級

透過 rkt 管理容器執行,Kubernetes 可以利用 CoreOS 容器引擎的模組化 stage1 隔離機制。典型的容器在 rkt 下在由 Linux 核心命名空間、cgroups 和其他機制建構的軟體隔離環境中運行。以這種常見方式隔離的容器仍然與系統上的所有其他容器共用單一核心,從而實現正在運行的應用程式的輕量級隔離。

然而,rkt 具有可插拔的隔離環境,稱為 stage1,用於變更容器的執行和隔離方式。例如,rkt fly stage1 在主機命名空間(PID、掛載、網路等)中運行容器,授予容器在主機系統上更大的權限。Fly 用於容器化較低層級的系統和網路軟體,例如 kubelet 本身。在隔離範圍的另一端,KVM stage1 將標準應用程式容器作為個別虛擬機器運行,每個虛擬機器都在自己的 Linux 核心之上,由 KVM hypervisor 管理。此隔離層級對於高安全性和多租戶叢集工作負載非常有用。

目前,rktnetes 可以使用 KVM stage1,透過設定 kubelet 的 --rkt-stage1-image 選項,以 VM 隔離執行節點上的所有容器。存在實驗性工作,可以透過 Kubernetes 註解宣告 Pod 適當的 stage1,以在每個 Pod 的基礎上選擇 stage1 隔離機制。KVM 容器和標準 Linux 容器可以在同一個叢集中混合使用。

rkt 如何與 Kubernetes 協同運作

如今,Kubernetes 透過 Docker 守護程序提供的 API 與預設容器引擎通信。rktnetes 與 rkt 的溝通方式略有不同。首先,Kubernetes 如何變更節點容器的狀態(即它如何啟動和停止 Pod,或為了故障轉移或擴展而重新排程它們)與編排器如何查詢 Pod 元數據以進行常規、唯讀的帳務處理之間存在區別。兩種不同的機制實現這兩種不同的情況。

管理微服務生命週期

每個叢集節點上的 kubelet 與 rkt 通信,以準備容器及其環境到 Pod 中,並與 Linux 服務管理框架 systemd 通信,以調用和管理 Pod 流程。然後將 Pod 作為 systemd 服務進行管理,並且 kubelet 透過 dbus 發送 systemd 命令來操作它們。生命週期管理(例如重新啟動失敗的 Pod 和終止已完成的流程)由 systemd 處理,應 kubelet 的要求。

用於讀取 Pod 數據的 API 服務

獨立的 rkt api-service 實作 Kubernetes 預期的 Pod 內省機制。雖然每個節點的 kubelet 使用 systemd 來啟動、停止和重新啟動 Pod 作為服務,但它會聯絡 API 服務以讀取容器執行期元數據。這包括基本的編排資訊,例如節點上運行的 Pod 數量、這些 Pod 的名稱和網路,以及 Pod 配置、資源限制和儲存卷的詳細資訊(想想 kubectl describe 子命令顯示的資訊)。

Pod 日誌在寫入日誌檔案後,也由 API 服務提供給 kubectl logs 和其他鑑識子命令,API 服務從日誌檔案讀取,以向 kubelet 提供 Pod 日誌數據,以回應控制平面請求。

到容器環境的這種雙重介面是一個非常活躍的開發領域,並且計劃擴展 API 服務,以提供 Pod 操作命令的方法。底層機制將繼續牢記關注點分離,但會從 kubelet 隱藏更多這些。隨著時間的推移,kubelet 用於控制 rktnetes 容器引擎的方法將與預設容器執行期介面之間的差異越來越小。

試用 rktnetes

那麼,您今天可以使用 rktnetes 做什麼呢?目前,rktnetes 通過了所有適用的 Kubernetes「端到端」(又名「e2e」)測試,向 cAdvisor 提供標準指標,使用 CNI 管理網路,處理每個容器/Pod 的日誌,並自動垃圾回收舊容器和映像檔。在 rkt 上運行的 Kubernetes 已經為 Kubernetes 叢集提供了超出模組化、彈性容器執行期基本功能的更多功能,並且它已經成為我們 CoreOS 開發環境的功能部分。

開發人員和早期採用者可以關注 rktnetes 筆記中的已知問題,以了解測試驅動程式預期會遇到的問題和障礙。此清單將使 rktnetes 達到與現有容器執行期和 API 功能對等所需的高層級部分分組。我們希望您也能在您的 Kubernetes 叢集中試用 rktnetes。

今天開始將 rkt 與 Kubernetes 搭配使用

入門指南 在 rkt 上運行 Kubernetes 逐步說明啟動 rktnetes 叢集的步驟,從 kubelet --container-runtime=rkt 到網路和啟動 Pod。此入門指南還概述了您需要使用 Kubernetes kube-up.sh 腳本在 GCE 上啟動叢集的配置。

最近的工作旨在使 rktnetes 叢集創建更加容易。雖然尚未合併,但一個進行中的提取請求建立了一個單一 rktnetes 配置切換,以在使用 coreos-kubernetes 配置工具部署 Kubernetes 叢集時選擇 rkt 作為容器引擎。您也可以查看 rktnetes 工作坊專案,該專案透過一個 vagrant up 命令在幾乎任何開發人員工作站上啟動單節點 rktnetes 叢集。

我們很高興看到更廣泛的 Kubernetes 和 CoreOS 社群設計的實驗來測試 rktnetes,我們歡迎您的意見 – 和提取請求!