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

Containerd 為 Kubernetes 帶來更多容器執行時選項

更新:Kubernetes 透過 `dockershim` 對 Docker 的支援現已棄用。欲瞭解更多資訊,請閱讀棄用通知。您也可以透過專門的 GitHub issue 討論棄用問題。

容器執行時是執行容器並在節點上管理容器映像的軟體。如今,最廣為人知的容器執行時是 Docker,但生態系統中還有其他容器執行時,例如 rktcontainerdlxd。Docker 是生產 Kubernetes 環境中使用最常見的容器執行時,但 Docker 的小弟 containerd 可能被證明是一個更好的選擇。本文描述瞭如何將 containerd 與 Kubernetes 結合使用。

Kubernetes 1.5 引入了一個名為 容器執行時介面 (CRI) 的內部外掛 API,以便輕鬆訪問不同的容器執行時。CRI 使 Kubernetes 能夠使用各種容器執行時,而無需重新編譯。理論上,Kubernetes 可以使用任何實現 CRI 的容器執行時來管理 Pod、容器和容器映象。

在過去的6個月中,來自Google、Docker、IBM、中興和浙江大學的工程師們致力於為containerd實現CRI。該專案名為cri-containerd,並於2017年9月25日釋出了功能完備的v1.0.0-alpha.0版本。藉助cri-containerd,使用者可以在不安裝Docker的情況下,使用containerd作為底層執行時來執行Kubernetes叢集。

containerd

Containerd 是一個相容 OCI 的核心容器執行時,旨在嵌入到更大的系統中。它提供了在節點上執行容器和管理映象所需的最少功能集。它由 Docker Inc. 發起,並於2017年3月捐贈給 CNCF。Docker 引擎本身是建立在 containerd 的早期版本之上,並將很快更新到最新版本。Containerd 即將釋出功能完備的穩定版本,目前 1.0.0-beta.1 已可用。

Containerd 的範圍比 Docker 小得多,提供了一個 Golang 客戶端 API,並且更注重可嵌入性。較小的範圍帶來了更小的程式碼庫,隨著時間的推移更容易維護和支援,這與 Kubernetes 的要求相符,如下表所示:

Containerd 範圍 (包含/不包含)Kubernetes 要求
容器生命週期管理包含容器建立/啟動/停止/刪除/列出/檢查 (✔️)
映象管理包含拉取/列出/檢查 (✔️)
網路不包含,無具體網路解決方案。使用者可以設定網路名稱空間並將容器放入其中。Kubernetes 網路處理的是 Pod,而不是容器,因此容器執行時不應提供不滿足要求的複雜網路解決方案。(✔️)
不包含,無卷管理。使用者可以設定主機路徑並將其掛載到容器中。Kubernetes 管理卷。容器執行時不應提供可能與 Kubernetes 衝突的內部卷管理。(✔️)
持久化容器日誌不包含,無持久化容器日誌。容器標準輸入輸出作為 FIFO 提供,可以根據需要進行重定向/修飾。Kubernetes 對持久化容器日誌有特定要求,例如格式和路徑等。容器執行時不應持久化不可管理的容器日誌。(✔️)
指標包含。Containerd 提供容器和快照指標作為 API 的一部分。Kubernetes 期望容器執行時提供容器指標(CPU、記憶體、可寫層大小等)和映象檔案系統使用情況(磁碟、inode 使用情況等)。(✔️)
總的來說,從技術角度看,containerd 是 Kubernetes 一個非常好的替代容器執行時。

cri-containerd

Cri-containerd 就是這樣一個專案:它是 containerd 的 CRI 實現。它與 Kubelet 和 containerd 在同一節點上執行。cri-containerd 位於 Kubernetes 和 containerd 之間,處理來自 Kubelet 的所有 CRI 服務請求,並使用 containerd 來管理容器和容器映象。cri-containerd 透過形成 containerd 服務請求,並新增足夠的額外功能來支援 CRI 要求,從而部分地管理這些服務請求。

與當前的 Docker CRI 實現(dockershim)相比,cri-containerd 消除了堆疊中的額外一層,使堆疊更穩定、更高效。

架構

Cri-containerd 使用 containerd 來管理完整的容器生命週期和所有容器映象。如下所示,cri-containerd 還透過 CNI(另一個 CNCF 專案)管理 Pod 網路。

我們用一個例子來演示當 Kubelet 建立一個單容器 Pod 時 cri-containerd 是如何工作的:

  1. Kubelet 透過 CRI 執行時服務 API 呼叫 cri-containerd 建立一個 Pod;
  2. cri-containerd 使用 containerd 建立並啟動一個特殊的 暫停容器沙箱容器),並將該容器放入 Pod 的 cgroups 和名稱空間中(為簡潔起見,省略了步驟);
  3. cri-containerd 使用 CNI 配置 Pod 的網路名稱空間;
  4. Kubelet 隨後透過 CRI 映象服務 API 呼叫 cri-containerd 拉取應用程式容器映象;
  5. 如果映象在節點上不存在,cri-containerd 會進一步使用 containerd 拉取映象;
  6. 然後 Kubelet 透過 CRI 執行時服務 API 呼叫 cri-containerd,使用拉取的容器映象在 Pod 內建立並啟動應用程式容器;
  7. cri-containerd 最後呼叫 containerd 建立應用程式容器,將其放入 Pod 的 cgroups 和名稱空間中,然後啟動 Pod 的新應用程式容器。完成這些步驟後,一個 Pod 及其相應的應用程式容器就被建立並運行了。

狀態

Cri-containerd v1.0.0-alpha.0 於2017年9月25日釋出。

它功能齊全。支援所有 Kubernetes 功能。

所有 CRI 驗證測試 已透過。(CRI 驗證是一個測試框架,用於驗證 CRI 實現是否滿足 Kubernetes 的所有要求。)

所有常規的 節點端到端測試 已透過。(Kubernetes 測試框架,用於測試 Kubernetes 節點級別功能,例如管理 Pod、掛載卷等。)

要了解有關 v1.0.0-alpha.0 版本的更多資訊,請參閱專案倉庫

試用一下

有關使用 Ansible 和 Kubeadm 進行多節點叢集安裝和啟動的步驟,請參閱此倉庫連結

如需在 Google Cloud 上從頭開始建立叢集,請參閱 Kubernetes the Hard Way

有關從釋出壓縮包進行自定義安裝,請參閱此倉庫連結

要在本地虛擬機器上使用 LinuxKit 進行安裝,請參閱此倉庫連結

後續步驟

我們將穩定性與可用性改進作為下一步重點。

  • 穩定性

    • 在 Ubuntu、COS (Container-Optimized OS) 等各種作業系統發行版上,在 Kubernetes 測試基礎設施中設定一套完整的 Kubernetes 整合測試。
    • 積極修復使用者報告的任何測試失敗和其他問題。
  • 可用性

    • 改善 crictl 的使用者體驗。Crictl 是一個適用於所有 CRI 容器執行時的可移植命令列工具。目標是使其易於用於除錯和開發場景。
    • 將 cri-containerd 與 kube-up.sh 整合,幫助使用者使用 cri-containerd 和 containerd 啟動生產質量的 Kubernetes 叢集。
    • 改進我們為使用者和管理員提供的文件。

我們計劃在 2017 年底釋出 v1.0.0-beta.0。

貢獻

Cri-containerd 是一個 Kubernetes 孵化專案,位於 https://github.com/kubernetes-incubator/cri-containerd。歡迎提供任何形式的貢獻,包括想法、問題和/或修復。對於貢獻者而言,開發者入門指南 是一個很好的起點。

社群

Cri-containerd 由 Kubernetes SIG-Node 社群開發和維護。我們很樂意聽取您的反饋。加入社群: