最近kubernetes社群發生了一件大事,Kubernetes 1。20 宣佈棄用docker,並且在2021年下半年釋出的1。23版本中,徹底移除 dockershim 程式碼,意味著屆時kubernetes支援的容器執行時不再包括docker。

這件事發生後,很多小夥伴為之擔憂,眾說紛紜。為了讓大家明白,棄用 docker 對我們終端使用者意味著什麼,本文從原理到未來我們該如何選擇這幾個幾個角度闡述。

Kubernetes 架構

Kubernetes叢集由matser和worker兩種角色組成:

一組master節點,它們承載著控制平面元件,它們是系統的大腦,因為它們控制著整個叢集。

一組構成工作負載平面的工作節點,工作負載在此執行。

Kubernetes“棄用”Docker對我們意味著什麼

Kubernetes Master

Master節點是Kubernetes控制面板或控制平面。這裡做出有關叢集的決策,例如排程和檢測/響應叢集事件。以下是master節點關鍵元件的細分:

API Server

叢集資料儲存 (etcd)

Controller Manager

Scheduler

Kubernetes 工作節點

Master節點處理和管理叢集,而工作節點執行容器並提供Kubernetes執行時環境。

主要元件有:

Kubelet

Container runtime

Kube-proxy

容器執行時並不會直接和master元件互動,而是kubelet 接受控制面下發的控制指令,然後根據指令控制容器執行時,當然kubelet 也會獲取執行容器的狀態並上報給master元件。

Kubernetes“棄用”Docker對我們意味著什麼

這樣的好處可想而知,並不會限制大家對於容器執行時的選擇。

為了使Kubernetes具有更好的可擴充套件性,kubernetes實現了一種新的外掛API,用於Kubernetes中的容器執行時,稱為“CRI”。

什麼是CRI?

容器執行時外掛(Container Runtime Interface,簡稱 CRI)是 Kubernetes v1。5 引入的容器執行時介面,它將 Kubelet 與容器執行時解耦,將原來完全面向 Pod 級別的內部介面拆分成面向 Sandbox 和 Container 的 gRPC 介面,並將映象管理和容器管理分離到不同的服務。

Kubernetes“棄用”Docker對我們意味著什麼

在 1。23 之前,kubernetes 支援 docker,containerd, cri-o 三種容器執行時。其中 containerd, cri-o 兩種容器執行時,是透過標準的 CRI 介面與Kubelet 對接。至於docker,kubelet 透過內部整合dockershim ,來實現對接。

為了對比兩種對接方式,我們透過三幅圖來說明。

下圖是kubelet與cri-o整合的示意圖:

Kubernetes“棄用”Docker對我們意味著什麼

下圖是kubelet 與 containerd 整合的示意圖:

Kubernetes“棄用”Docker對我們意味著什麼

下面是kubelet與docker整合的示意圖:

Kubernetes“棄用”Docker對我們意味著什麼

看到此處,你不由會問,為什麼kubelet 不透過 cri 與 docker 整合?

說來話長,技術圈也是一個大江湖。在kubernetes 橫空出世之前,docker 已經如日中天了。kubernets 為了推廣,快速佔領市場,支援 docker 是一個明智的選擇。而 docker 開發出了swarm,與kubernetes 抗衡。奈何 kubernetes 出身優越,背靠著谷歌這顆大樹,把swarm打的無還手之力。於此同時,順手收拾了mesos。結果大家已經看到,容器編排圈的三國之爭,以kubernets成為事實上的標準而結束。

Kubernetes“棄用”Docker對我們意味著什麼

後來 docker 將自己的內部一些元件抽象出來,捐獻給社群,這就是現在的containerd以及oci 規範。也許是想借助社群的力量,繼續抗衡。

Docker 官方 並沒有支援 CRI 介面的打算。這也算最後的倔強吧。

但是從理性的角度看,kubelet 透過整合docker shim 程式碼來實現與docker 的對接並不是一個最佳實踐。簡單總結以下兩點原因:

緊耦合,會導致升級困難。也不符合單一職責原則。

必須充分的測試,才能保證相容。

Docker 是否完全離我們而去?

Docker 雖然被kubernetes 棄用,但是並不意味著docker 完全離我們而去。我們看下docker 的架構:

Kubernetes“棄用”Docker對我們意味著什麼

容器執行時僅僅是docker 生態的一部分。docker 家族,還包括docker deskstop 等有著出色使用者體驗的工具以及 dockerhub 這個寶藏。

開發人員仍然可以使用Docker平臺在Kubernetes上構建,共享和執行容器。Kubernetes棄用docker主要影響Kubernetes的運營商和管理員,而不會影響開發人員的工作流程。 Docker構建的映象符合OCI(開放容器協議),在容器上完全受支援,並將繼續在Kubernetes上很好地執行。

所以我們需要知道以下兩點:

OCI 規範包括 OCI image 規範 和 OCI runtime 規範,所以映象是通用的,從而我們依舊可以在kubernetes 中使用 dockerhub上的映象 。

我們依舊可以使用 docker 對映象進行構建。

借用老羅的一句話,docker 想對大家說:“放心,我還在”。

過去的已經過去了,作為一個終端使用者,接下來我們需要考慮的是選擇Containerd 或是CRI-O。

Containerd or CRI-O?

下面我們簡單對比一下兩種執行時。

Containerd

containerd是行業標準的容器執行時,具備簡單性,健壯性和可移植性等特點。它可以作為Linux和Windows的守護程式使用,可以管理其主機系統的完整容器生命週期:映象傳輸和儲存,容器執行和監控,低階儲存和網路附件等。

containerd旨在嵌入到更大的系統中,而不是由開發人員或終端使用者直接使用。

Kubernetes“棄用”Docker對我們意味著什麼

Docker於2016年與Google和IBM一起建立了Containerd。其已於2017年捐贈給CNCF,並於2020年畢業。Containerd擁有活躍的社群,貢獻人員自亞馬遜,谷歌,微軟和IBM等大廠。

CRI-O

CRI-O是Kubernetes CRI(容器執行時介面)的實現,以啟用使用OCI(開放容器協議)相容的執行時。它是使用Docker作為kubernetes的執行時的輕量級替代方案。它允許Kubernetes使用任何符合OCI的執行時作為執行Pod的容器執行時。今天,它支援runc和Kata Containers作為容器執行時,但是原則上可以插入任何符合OCI的執行時。

CRI-O支援OCI容器映象,並且可以從任何容器登錄檔中拉取。它是將Docker,Moby或rkt用作Kubernetes的執行時的輕量級替代方案。

Kubernetes“棄用”Docker對我們意味著什麼

對比

對比兩種執行時,均可以使用符合oci規範的映象,並都直接支援CRI介面,從而可以與kubernetes 整合。

但是containerd 社群更加活躍,發展勢頭更好。 從生產環境使用上看,containerd也較cri-o多。比如aws 開源的Firecracker(輕量級runv),就透過 firecracker-containerd

專案實現

containerd 對於Firecracker的管理。

當然黑貓白貓,抓住耗子就是好貓。至於最終選擇哪種執行時,也取決於公司的實際場景和對兩種執行時的掌握程度。