先問是不是,再問爲什麼。
沒錯,這是真的。Kubernetes現已棄用Docker。
參考鏈接:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#deprecation
目前,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以在該節點上運行容器的創建/刪除。
但Docker爲什麼會被棄用?
如前所述,Kubernetes只能與CRI通信,因此要與Docker通信,就必須使用橋接服務。這就是第一點原因。
要解釋下一個原因,我們必須稍微解釋一下Docker架構。首先參考以下示意圖。
沒錯,Kubernetes實際上需要保持在紅框之內。Docker網絡與存儲卷都被排除在外。
而這些用不到的功能本身就可能帶來安全隱患。事實上,你擁有的功能越少,攻擊面也就越小。
因此,我們需要考慮使用替代方案,即CRI運行時。
CRI運行時
CRI運行時的實現方案主要有兩種。
containerd
如果大家只是想從Docker遷移出來,那麼containerd就是最好的選擇。因爲它實際上就是在Docker之內起效,可以完成所有“運行時”工作,如上圖所示。更重要的是,它提供的CRI其實100%就是由Docker所提供。
containerd還屬於全開源軟件,因此你可以在GitHub上查看說明文檔甚至參與項目貢獻。
https://github.com/containerd/containerd/
CRI-O
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請求。
根據規範創建OCI json配置
OCI運行時
OCI運行時負責使用Linux內核系統調用(例如cgroups與命名空間)生成容器。你可能聽說過runC或者gVisor,這就是了。
CRI會通過Linux系統調用以執行二進制文件,而後runC生成容器。這表明runC依賴於Linux計算機上運行的內核。
這也意味着,如果你發現runC中的漏洞會使你獲得主機root權限,那麼容器化應用程序同樣會造成root權限外泄。很明顯,惡意黑客會抓住機會入侵主機,引發災難性的後果。正因爲如此,大家才需要不斷更新Docker(或者其他容器運行時),而不僅僅是更新容器化應用程序本身。
gVisor是最初由谷歌員工創建的OCI運行時。它實際上運行在承載各類谷歌雲服務(包括Google Cloud Run、Google App Engine以及Google Cloud Functions)的同一套基礎設施之上。
有趣的是,gVisor中包含一個“訪客內核”層,意味着容器化應用程序無法直接接觸到主機內核層。即使是應用程序“認爲”自己接觸到了,實際接觸到的也只是gVisor的訪客內核。
gVisor的安全模式非常有趣,這裏建議大家參閱官方說明文檔[1]。
gVisor與runC的顯著差別如下:
性能更差
Linux內核層並非100%兼容,參見官方文檔中的兼容性部分[2]
不受默認支持
總結
Docker確被棄用,大家應該開始考慮使用CRI運行時,例如containerd與CRI-O。
-
containerd與Docker相兼容,二者共享相同的核心組件。
如果你主要使用Kubernetes的最低功能選項,CRI-O可能更爲適合。
明確理解CRI運行時與OCI運行時之間的功能與作用範圍差異。
根據你的實際工作負載與業務需求,runC可能並不總是最好的選擇,請酌情做出考量!
相關鏈接:
https://gvisor.dev/docs/
https://gvisor.dev/docs/user_guide/compatibility/
原文鏈接:https://dev.to/inductor/wait-docker-is-deprecated-in-kubernetes-now-what-do-i-do-e4m
Kubernetes實戰培訓
Kubernetes實戰培訓將於2020年12月25日在深圳開課,3天時間帶你係統掌握Kubernetes,學習效果不好可以繼續學習。本次培訓包括:雲原生介紹、微服務;Docker基礎、Docker工作原理、鏡像、網絡、存儲、數據卷、安全;Kubernetes架構、核心組件、常用對象、網絡、存儲、認證、服務發現、調度和服務質量保證、日誌、監控、告警、Helm、實踐案例等,點擊下方圖片或者閱讀原文鏈接查看詳情。