天天看點

什麼!Kubernetes 決定棄用 Docker?那有什麼替代品?

什麼?Kubernetes 決定棄用 Docker?

這是真的。Kubernetes 現已棄用 Docker。

“ https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md ”

目前,kubelet 中的 Docker 支援功能現已棄用,并将在之後的版本中被删除。Kubelet 之前使用的是一個名為 dockershim 的子產品,用以實作對 Docker 的 CRI 支援。但 Kubernetes 社群發現了與之相關的維護問題,是以建議大家考慮使用包含 CRI 完整實作(相容 v1alpha1 或 v1)的可用容器運作時。

簡而言之,Docker 并不支援 CRI(容器運作時接口)這一 Kubernetes 運作時 API,而 Kubernetes 使用者一直以來所使用的其實是名為“dockershim”的橋接服務。Dockershim 能夠轉換 Docker API 與 CRI,但在後續版本當中,Kubernetes 将不再提供這項橋接服務。

當然,Docker 本身也是一款非常強大的工具,可用于建立開發環境。但為了了解造成目前狀況的原因,我們需要全面分析 Docker 在現有 Kubernetes 架構中的作用。

Kubernetes 是一款基礎設施工具,可對多種不同計算資源(例如虛拟 / 實體機)進行分組,使其呈現為統一的巨量計算資源,進而供應用程式使用或與其他人共享。在這樣的架構中,Docker(或者容器運作時)僅用于通過 Kubernetes 控制平面進行排程,進而在實際主機内運作應用程式。

什麼!Kubernetes 決定棄用 Docker?那有什麼替代品?

通過以上架構圖,可以看到每個 Kubernetes 節點都與控制平面彼此通信。各個節點上的 kubelet 擷取中繼資料,并執行 CRI 以在該節點上建立 / 删除容器。

如前所述,Kubernetes 隻能與 CRI 通信,是以要與 Docker 通信,就必須使用橋接服務。這就是棄用 Docker 的第一點原因。

要解釋下一個原因,我們必須稍微聊聊 Docker 架構。首先參考以下示意圖。

什麼!Kubernetes 決定棄用 Docker?那有什麼替代品?

沒錯,Kubernetes 實際上需要保持在紅框之内。Docker 網絡與存儲卷都被排除在外。

而這些用不到的功能本身就可能帶來安全隐患。事實上,您擁有的功能越少,攻擊面也就越小。

是以,我們需要考慮使用替代方案,即 CRI 運作時。

CRI 運作時的實作方案主要有兩種。

如果大家隻是想從 Docker 遷移出來,那麼 containerd 就是最好的選擇。因為它實際上就是在 Docker 之内起效,可以完成所有“運作時”工作,如上圖所示。更重要的是,它提供的 CRI 其實 100% 就是由 Docker 所提供。

containerd 還屬于全開源軟體,是以您可以在 GitHub 上檢視說明文檔甚至參與項目貢獻。

https://github.com/containerd/containerd/

CRI-O 是主要由 Red Hat 員工開發的 CRI 運作時。它的最大差別在于并不依賴于 Docker,而且目前已經在 Red Hat OpenShift 中得到使用。

有趣的是,RHEL 7 同樣不官方支援 Docker。相反,其隻為容器環境提供 Podman、Buildah 以及 CRI-O。

https://github.com/cri-o/cri-o

CRI-O 的優勢在于其采用極簡風格,或者說它的設計本身就是作為“純 CRI”運作時存在。不同于作為 Docker 組成部分的 containerd,CRI-O 在本質上屬于純 CRI 運作時、是以不包含除 CRI 之外的任何其他内容。

從 Docker 遷移至 CRI-O 往往更為困難,但無論如何,CRI-O 至少可以支援 Docker 容器在 Kubernetes 上的正常運作。

當我們談論容器運作時時,請注意我們到底是在談論哪種類型的運作時。運作時分為兩種:CRI 運作時與 OCI 運作時。

CRI 運作時

正如之前所提到,CRI 是 Kubernetes 提供的 API,用于同容器運作時進行通信以建立 / 删除容器化應用程式。

各容器化應用程式作為 kubelet 通過 IPC 在 gRPC 内通信,而且運作時也運作在同一主機之上;CRI 運作時負責從 kubelet 擷取請求并執行 OCI 容器運作時以運作容器。稍微有點複雜,接下來我們會用圖表來解釋。

什麼!Kubernetes 決定棄用 Docker?那有什麼替代品?

是以,CRI 運作時将執行以下操作:

從 kubelet 擷取 gRPC 請求。

根據規範建立 OCIjson 配置。

OCI 運作時

OCI 運作時負責使用 Linux 核心系統調用(例如 cgroups 與命名空間)生成容器。您可能聽說過 runc 或者 gVisor,這就是了。

附錄 1:runC 的工作原理

什麼!Kubernetes 決定棄用 Docker?那有什麼替代品?

CRI 會通過 Linux 系統調用以執行二進制檔案,而後 runC 生成容器。這表明 runC 依賴于 Linux 計算機上運作的核心。

這也意味着,如果您發現 runC 中的漏洞會使您獲得主機 root 權限,那麼容器化應用程式同樣會造成 root 權限外洩。很明顯,惡意黑客會抓住機會入侵主機,引發災難性的後果。正因為如此,大家才需要不斷更新 Docker(或者其他容器運作時),而不僅僅是更新容器化應用程式本身。

附錄 2:gVisor 工作原理

什麼!Kubernetes 決定棄用 Docker?那有什麼替代品?

gVisor 是最初由谷歌員工建立的 OCI 運作時。它實際上運作在承載各類谷歌雲服務(包括 Google Cloud Run、Google App Engine 以及 Google Cloud Functions)的同一套基礎設施之上。

有趣的是,gVisor 中包含一個“訪客核心”層,意味着容器化應用程式無法直接接觸到主機核心層。即使是應用程式“認為”自己接觸到了,實際接觸到的也隻是 gVisor 的訪客核心。

gVisor 的安全模式非常有趣,這裡建議大家參閱官方說明文檔。

https://gvisor.dev/docs/

gVisor 與 runC 的顯著差别如下:

性能更差

Linux 核心層并非 100% 相容:參見官方文檔中的相容性部分

不受預設支援

https://gvisor.dev/docs/user_guide/compatibility/

1.Docker 确被棄用,大家應該開始考慮使用 CRI 運作時,例如 containerd 與 CRI-O。

a.containerd 與 Docker 相相容,二者共享相同的核心元件。

b. 如果您主要使用 Kubernetes 的最低功能選項,CRI-O 可能更為适合。

2.明确了解 CRI 運作時與 OCI 運作時之間的功能與作用範圍差異。

根據您的實際工作負載與業務需求,runC 可能并不總是最好的選擇,請酌情做出考量!

來源 | https://dev.to/inductor/wait-docker-is-deprecated-in-kubernetes-now-what-d