Kubernetes 棄用 Docker,到底會影響到誰?
Kubernetes 在其最新的 Changelog 中宣布,自 Kubernetes 1.20 之后將棄用 Docker 作為容器運行時。那么這到底是怎么回事?開發者和企業會受到什么樣到影響?
近幾年,Kubernetes 已經成為自有機房、雲上廣泛使用的容器編排方案,最廣泛的使用方式是 Kubernetes+Docker。從 DevOps 人員的角度,一面用 kubctl 命令、k8s API 來操作集群,一面在單機用 Docker 命令來管理鏡像、運行鏡像。
單獨用 Docker 的情況,在一些公司的場景里面也是有的。一種場景是“只分不合”,把一台機器用 Docker 做資源隔離,但是不需要將多容器“編排”。單獨用 Kubernetes,下層不是 Docker 的情況,並不算很多。
Kubernetes 和 Docker 的關系,簡單來說,有互補,也有競爭。在一般的認知中,Kubernetes 和 Docker 是互補關系:
Dockers 屬於下層——容器引擎;
Kubernetes 屬於上層——編排調度層。
Docker 源於 Linux Container,可以將一台機器的資源分成 N 份容器,做到資源的隔離,並將可運行的程序定義為標准的 docker image;Kubernetes 則可以把不同機器的每份容器進行編排、調度,組成分布式系統。
Kubernetes 和 Docker 並不完全是“涇渭分明”的互補關系,它之間有重疊部分,也可以說成是競爭,主要在於幾個點:
系統三大移植資源是計算、存儲、網絡,從 Kubernetes 角度 Docker 屬於“Runtime(運行時)”,也就是計算資源;但是 Docker 技術體系里面,本身也包括存儲層、網絡層。上下層職責的重疊,也可以看作競爭。
Docker 原本有個原生的調度引擎——Swarm,幾年前在調度編排領域,還是 Kubernetes、Mesos、Swarm 三者並存,Kubernetes 最終勝出,但 Docker 仍有“繼續向上做一層的意願”。
Kubernetes 在如何使用 Docker 方面,存在爭議和變數。kubernetes 1.20 ChangeLog 中所謂要廢棄 Docker 的傳言,也是無風不起浪。換句話說,即便 Kubernetes 一直用 Docker,也不是用 Docker 的全部,多少是不一樣的。
而且,“棄用 Docker”這個詞本身有多重的含義,Docker 並非一個單層軟件,Kubernetes 1.20 啟用 dockershim 並不代表棄用了 Docker 的全部,仍有 containerd 可以對接 docker。
1.Kubernetes 有 CRI、OCI 兩個容器標准
在目前廣泛使用 kubernetes 與 Runtime 的橋接方案,CRI(Container Runtime Interface)與 OCI(Open Container Initiative)是“套娃“關系。Kubernetes 的 kubelet 調用 CRI,OCI 的實現者然后再調用 OCI。
下圖也說明了 CRI 與 OCI 的關系:
從 Kubernetes 的角度,CRI 是與 CNI(網絡)、CSI(存儲)相同層級的接口。
OCI 是個自下而上的標准,也就是從實現抽象出接口,它是 Linux Foundation 主導的。Docker 實現的核心 RunC,也就是 OCI 的典型實現、標准實現。
CRI 是個自上而下的標准,源於 Kubernetes 對移植層(運行時)的要求。
容器引擎層自下而上定義 OCI,容器編排層自上而下定義 CRI,這也讓它們出現了“套娃“運行情況。
在 Kubernetes 的 dockershim、cri-containerd、cri-o 三種實現中,RedHat 推崇的 cri-o 已經比較主流,它雖然仍是“套娃“,但已經比較精簡。
下面是從 kubernetes 集群運行的全景圖看 cri-o 的位置:
2.Docker 本源於 Linux Container
Docker 作為容器引擎,其實現的基礎是 Linux Container——從內核到用戶空間的機制。
Linux Container 可以分成兩個部分,內核里面的 cgroup,用戶空間的 lxc。Docker 最初實現的時候,也是完全基於 Linux Container 的,基於 lxc 做更上層的東西。
這張很多人認為“與事實不符“的圖,其實代表了過去:
在 Docker 的發展過程中,最終啟用了 C 語言寫成 lxc,換成了 go 語言寫成的 libcontainer。
下面的圖也不是很新,但它更能表示 Docker 后續典型的架構,這里面已經沒有了 lxc。
然而,萬變不離其宗,Docker 實現的本源,還是 Linux Container。即便不用 lxc,當仍要用內核的 cgroup,並且模式也是類似的。
3.Kubernetes 最終如何橋接容器
從純技術的角度,與其討 Kubernetes 與 Docker 關系,不如討論 Kubernetes 與最終容器實現層的關系。因為 Docker 這個名詞,在不同的時候,有着不同的內涵、外延。
下面是 Docker 的簡圖:
從軟件模塊的角度,圖中的 docker Engine、cri-containd、containd-shim、runC 都屬於 Docker 體系的軟件。
下圖中的紫、橙、紅三種顏色,代表了 dockershim、cri-containerd、cri-o 三種 CRI 的典型方式——流程在逐漸縮短,這也是 CRI 實現的一個演進過程。
如果是 kubelet 的 dockershim 模式(紫色),流程是這樣的:
kubelet 從 CRI 的 gRPC 調用 dockershim,二者在同一個進程
dockershim 調用 docker 守護進程
docker 守護進程調用 containerd;containerd 調用 containerd-shim(有時名為docker-containerd-shim 守護進程)完成創建容器等操作
containerd-shim 訪問 OCI 的實現 runC(命令行可執行程序)
如果是 kubelet 的 cri-containerd 模式(橙色),流程是這樣的:
kubelet 從 CRI 的 gRPC 調用 cri-containerd;
cri-containerd 調用 containerd;containerd 調用 containerd-shim(同上)
containerd-shim 調用 RucnC (同上);
在很多人的印象中,如果不用 docker 守護進程,就相當於“棄用 docker“,這其實也就是從 dockershim 到 containerd 的變化。從另一個角度來說,containerd 這個守護進程,也是 docker 組織做的。
如果是 kubelet 的 cri-o 模式(紅色),則更加簡練:
kubelet 從 CRI 的 gRPC 調用 cri-o;
cri-o 調用 OCI 的實現 runC
如果以 kubelet 調用 CRI 為起點,OCI 的 runC 調用為終點,三種模式經歷的可執行程序分別是:
dockershim 模式:dockershim(*)->dockd->containerd->containerd-shim
dockershim 模式有 3 個可執行程序,dockershim 一般與 kubelet 同進程;
cri-containerd 模式:cri-containerd(*)-> containerd->containerd-shim
cri-containerd 模式有 2-3 個可執行程序,cri-containerd 可與 containerd 同進程;
cri-o 模式:cri-o
cri-o 模式只有 1 個可執行程序。
顯然在這種 Red Hat 推崇的 cri-o 模式下,Docker 體系的 containerd 也用不着了,只剩 runC 這個命令行的程序。runC 也是用 go 寫成的,里面有調用 libcontainer。
當 Docker 萎縮到這個地步,其實也只剩 Linux 內核里面 cgroup、namespace 功能的封裝了。
總結來說,由於老技術實現的慣性,在生產環境大量使用的經典 Kubernetes+ Docker 方案依然運行,且運維已經成熟,不會很快升級。對於開發人員、企業,對於 K8S API 的使用頻率、變數,遠遠大於 Docker API,至於 Kubernetes 和 Docker 的橋接,更不用關心。因此,即便“徹底棄用 Docker”,對開發者與企業的影響也非常有限。
抄自於:https://mp.weixin.qq.com/s?__biz=MzIzNjUxMzk2NQ==&mid=2247503788&idx=1&sn=e6940f629dd56d4e9f3ea8daf1626b2a&chksm=e8d4306edfa3b97814ecc27710ebfb31d08314e7e49f1bf894bfe385483421e5ce2480b5a76e&scene=126&sessionid=1608013820&key=7699cc7e7be7dcfc92288968a4031874596f503924f2a0fe4d86de798482a3d37f32b0dbf5b57fe1ae4999cf67a5efd157734008974dd4e1edaea9d8193db51ff31bcf5dbb9e1e19ca991d24cdf68c1b68244e80fac45dc1b0229754ce42d1980de2f7239ffb6868d2f473e281933284882275b91ecc80da0d28dc0dc5906360&ascene=1&uin=MjM3MjczMTM2MQ%3D%3D&devicetype=Windows+10+x64&version=6300002f&lang=zh_CN&exportkey=AfTZWMfy9ESXczcNuavvncA%3D&pass_ticket=0iAf7dngOlPnLj2404zpBLNzUWXrDCI0d070YhiabyHBfevMErYaEHBAVEli8pVB&wx_header=0
作者介紹
楊明越,現從事分布式系統、雲架構方面工作,具有全方位的技術,曾任新興互聯網公司(BAT)的主任架構師,世界頂級芯片公司的 OS 技術專家,前 Top2 通訊公司高級工程師。