什麼?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 節點都與控制平面彼此通信。各個節點上的 kubelet 擷取中繼資料,并執行 CRI 以在該節點上建立 / 删除容器。
如前所述,Kubernetes 隻能與 CRI 通信,是以要與 Docker 通信,就必須使用橋接服務。這就是棄用 Docker 的第一點原因。
要解釋下一個原因,我們必須稍微聊聊 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 容器運作時以運作容器。稍微有點複雜,接下來我們會用圖表來解釋。
是以,CRI 運作時将執行以下操作:
從 kubelet 擷取 gRPC 請求。
根據規範建立 OCIjson 配置。
OCI 運作時
OCI 運作時負責使用 Linux 核心系統調用(例如 cgroups 與命名空間)生成容器。您可能聽說過 runc 或者 gVisor,這就是了。
附錄 1:runC 的工作原理
CRI 會通過 Linux 系統調用以執行二進制檔案,而後 runC 生成容器。這表明 runC 依賴于 Linux 計算機上運作的核心。
這也意味着,如果您發現 runC 中的漏洞會使您獲得主機 root 權限,那麼容器化應用程式同樣會造成 root 權限外洩。很明顯,惡意黑客會抓住機會入侵主機,引發災難性的後果。正因為如此,大家才需要不斷更新 Docker(或者其他容器運作時),而不僅僅是更新容器化應用程式本身。
附錄 2:gVisor 工作原理
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