新聞中心
K8S宣布棄用docker,千萬(wàn)別慌!
作者:佚名 2020-12-07 07:48:35
云計(jì)算
開(kāi)發(fā)工具 近日,Kubernetes 官方發(fā)布公告,宣布自 v1.20 起放棄對(duì) Docker 的支持,屆時(shí)用戶(hù)將收到 Docker 棄用警告,并需要改用其他容器運(yùn)行時(shí)。

近日,Kubernetes 官方發(fā)布公告,宣布自 v1.20 起放棄對(duì) Docker 的支持,屆時(shí)用戶(hù)將收到 Docker 棄用警告,并需要改用其他容器運(yùn)行時(shí)。
[[355838]]
圖片來(lái)自 Pexels
但 Docker 作為容器鏡像構(gòu)建工具的作用將不受影響,用其構(gòu)建的容器鏡像將一如既往地在集群中與所有容器運(yùn)行時(shí)正常運(yùn)轉(zhuǎn)。
Kubernetes 將棄用 Docker
沒(méi)錯(cuò),這是真的,Kubernetes 現(xiàn)已棄用 Docker!
參考鏈接:
- https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#deprecation
目前,Kubelet 中的 Docker 支持功能現(xiàn)已棄用,并將在之后的版本中被刪除。
Kubelet 之前使用的是一個(gè)名為 dockershim 的模塊,用以實(shí)現(xiàn)對(duì) Docker 的 CRI 支持。
但 Kubernetes 社區(qū)發(fā)現(xiàn)了與之相關(guān)的維護(hù)問(wèn)題,因此建議大家考慮使用包含 CRI 完整實(shí)現(xiàn)(兼容 v1alpha1 或 v1)的可用容器運(yùn)行時(shí)。
[[355839]]
簡(jiǎn)而言之,Docker 并不支持 CRI(容器運(yùn)行時(shí)接口)這一 Kubernetes 運(yùn)行時(shí) API,而 Kubernetes 用戶(hù)一直以來(lái)所使用的其實(shí)是名為“dockershim”的橋接服務(wù)。
Dockershim 能夠轉(zhuǎn)換 Docker API 與 CRI,但在后續(xù)版本當(dāng)中,Kubernetes 將不再提供這項(xiàng)橋接服務(wù)。
當(dāng)然,Docker 本身也是一款非常強(qiáng)大的工具,可用于創(chuàng)建開(kāi)發(fā)環(huán)境。但為了了解造成當(dāng)前狀況的原因,我們需要全面分析 Docker 在現(xiàn)有 Kubernetes 架構(gòu)中的作用。
Kubernetes 是一款基礎(chǔ)設(shè)施工具,可對(duì)多種不同計(jì)算資源(例如虛擬/物理機(jī))進(jìn)行分組,使其呈現(xiàn)為統(tǒng)一的巨量計(jì)算資源,從而供應(yīng)用程序使用或與其他人共享。
在這樣的架構(gòu)中,Docker(或者容器運(yùn)行時(shí))僅用于通過(guò) Kubernetes 控制平面進(jìn)行調(diào)度,從而在實(shí)際主機(jī)內(nèi)運(yùn)行應(yīng)用程序。
通過(guò)以上架構(gòu)圖,可以看到每個(gè) Kubernetes 節(jié)點(diǎn)都與控制平面彼此通信。各個(gè)節(jié)點(diǎn)上的 kubelet 獲取元數(shù)據(jù),并執(zhí)行 CRI 以在該節(jié)點(diǎn)上運(yùn)行容器的創(chuàng)建/刪除。
Docker 為什么會(huì)被棄用?
如前所述,Kubernetes 只能與 CRI 通信,因此要與 Docker 通信,就必須使用橋接服務(wù)。這就是第一點(diǎn)原因。
要解釋下一個(gè)原因,我們必須稍微解釋一下 Docker 架構(gòu)。首先參考以下示意圖:
沒(méi)錯(cuò),Kubernetes 實(shí)際上需要保持在紅框之內(nèi)。Docker 網(wǎng)絡(luò)與存儲(chǔ)卷都被排除在外。
而這些用不到的功能本身就可能帶來(lái)安全隱患。事實(shí)上,你擁有的功能越少,攻擊面也就越小。因此,我們需要考慮使用替代方案,即 CRI 運(yùn)行時(shí)。
CRI 運(yùn)行時(shí)的實(shí)現(xiàn)方案主要有兩種:
①containerd
如果大家只是想從 Docker 遷移出來(lái),那么 containerd 就是最好的選擇。因?yàn)樗鼘?shí)際上就是在 Docker 之內(nèi)起效,可以完成所有“運(yùn)行時(shí)”工作,如上圖所示。更重要的是,它提供的 CRI 其實(shí) 100% 就是由 Docker 所提供。
containerd 還屬于全開(kāi)源軟件,因此你可以在 GitHub 上查看說(shuō)明文檔甚至參與項(xiàng)目貢獻(xiàn):
- https://github.com/containerd/containerd/
②CRI-O
CRI-O 是主要由 Red Hat 員工開(kāi)發(fā)的 CRI 運(yùn)行時(shí)。它的最大區(qū)別在于并不依賴(lài)于 Docker,而且目前已經(jīng)在 Red Hat OpenShift 中得到使用。
有趣的是,RHEL 7 同樣不官方支持 Docker。相反,其只為容器環(huán)境提供 Podman、Buildah 以及 CRI-O:
- https://github.com/cri-o/cri-o
CRI-O 的優(yōu)勢(shì)在于其采用極簡(jiǎn)風(fēng)格,或者說(shuō)它的設(shè)計(jì)本身就是作為“CRI”運(yùn)行時(shí)存在。
不同于作為 Docker 組成部分的 containerd,CRI-O 在本質(zhì)上屬于純 CRI 運(yùn)行時(shí)、因此不包含除 CRI 之外的任何其他內(nèi)容。
從 Docker 遷移至 CRI-O 往往更為困難,但無(wú)論如何,CRI-O 至少可以支持 Docker 容器在 Kubernetes 上的正常運(yùn)行。
還有一點(diǎn),當(dāng)我們談?wù)撊萜鬟\(yùn)行時(shí)時(shí),請(qǐng)注意我們到底是在談?wù)撃姆N類(lèi)型的運(yùn)行時(shí)。
運(yùn)行時(shí)分為兩種:
- CRI 運(yùn)行時(shí)
- OCI 運(yùn)行時(shí)
CRI 運(yùn)行時(shí)
正如之前所提到,CRI 是 Kubernetes 提供的 API,用于同容器運(yùn)行時(shí)進(jìn)行通信以創(chuàng)建/刪除容器化應(yīng)用程序。
各容器化應(yīng)用程序作為 kubelet 通過(guò) IPC 在 gRPC 內(nèi)通信,而且運(yùn)行時(shí)也運(yùn)行在同一主機(jī)之上;CRI 運(yùn)行時(shí)負(fù)責(zé)從 kubelet 獲取請(qǐng)求并執(zhí)行 OCI 容器運(yùn)行時(shí)以運(yùn)行容器。
稍微有點(diǎn)復(fù)雜,接下來(lái)我們會(huì)用圖表來(lái)解釋?zhuān)?nbsp;
因此,CRI 運(yùn)行時(shí)將執(zhí)行以下操作:
- 從 kubelet 獲取 gRPC 請(qǐng)求。
- 根據(jù)規(guī)范創(chuàng)建 OCI json 配置。
OCI 運(yùn)行時(shí)
OCI 運(yùn)行時(shí)負(fù)責(zé)使用 Linux 內(nèi)核系統(tǒng)調(diào)用(例如 cgroups 與命名空間)生成容器。你可能聽(tīng)說(shuō)過(guò) runC 或者 gVisor,這就是了。
CRI 會(huì)通過(guò) Linux 系統(tǒng)調(diào)用以執(zhí)行二進(jìn)制文件,而后 runC 生成容器。這表明 runC 依賴(lài)于 Linux 計(jì)算機(jī)上運(yùn)行的內(nèi)核。
這也意味著,如果你發(fā)現(xiàn) runC 中的漏洞會(huì)使你獲得主機(jī) root 權(quán)限,那么容器化應(yīng)用程序同樣會(huì)造成 root 權(quán)限外泄。
很明顯,惡意黑客會(huì)抓住機(jī)會(huì)入侵主機(jī),引發(fā)災(zāi)難性的后果。正因?yàn)槿绱?,大家才需要不斷更?Docker(或者其他容器運(yùn)行時(shí)),而不僅僅是更新容器化應(yīng)用程序本身。
gVisor 是最初由谷歌員工創(chuàng)建的 OCI 運(yùn)行時(shí)。它實(shí)際上運(yùn)行在承載各類(lèi)谷歌云服務(wù)(包括 Google Cloud Run、Google App Engine 以及 Google Cloud Functions)的同一套基礎(chǔ)設(shè)施之上。
有趣的是,gVisor 中包含一個(gè)“訪(fǎng)客內(nèi)核”層,意味著容器化應(yīng)用程序無(wú)法直接接觸到主機(jī)內(nèi)核層。
即使是應(yīng)用程序“認(rèn)為”自己接觸到了,實(shí)際接觸到的也只是 gVisor 的訪(fǎng)客內(nèi)核。
gVisor的安全模式非常有趣,這里建議大家參閱官方說(shuō)明文檔:
- https://gvisor.dev/docs/
gVisor 與 runC 的顯著差別如下:
- 性能更差
- Linux內(nèi)核層并非 100% 兼容,參見(jiàn)官方文檔中的兼容性部分:
- https://gvisor.dev/docs/user_guide/compatibility/
- 不受默認(rèn)支持
總結(jié):
- Docker 確被棄用,大家應(yīng)該開(kāi)始考慮使用 CRI 運(yùn)行時(shí),例如 containerd 與 CRI-O。containerd 與 Docker 相兼容,二者共享相同的核心組件。如果你主要使用 Kubernetes 的最低功能選項(xiàng),CRI-O 可能更為適合。
- 明確理解 CRI 運(yùn)行時(shí)與 OCI 運(yùn)行時(shí)之間的功能與作用范圍差異。
根據(jù)你的實(shí)際工作負(fù)載與業(yè)務(wù)需求,runC可能并不總是最好的選擇,請(qǐng)酌情做出考量!
廢棄 Docker,但別慌!
[[355840]]
在 1.20 版本之后,Kubernetes 將不再支持把 Docker 作為容器運(yùn)行時(shí)使用。
不必驚慌,實(shí)際上沒(méi)多大影響。
PS:這里只是不建議將 Docker 作為底層運(yùn)行時(shí),你仍然可以使用專(zhuān)為Kubernetes創(chuàng)建的容器運(yùn)行時(shí)接口(CRI)一如既往地在集群中運(yùn)行 Docker 鏡像。
對(duì)于 Kubernetes 最終用戶(hù),此次調(diào)整同樣不會(huì)有太大影響。Docker 不會(huì)就此消亡,你也仍然可以繼續(xù)將 Docker 作為開(kāi)發(fā)工具使用。
Docker 會(huì)繼續(xù)構(gòu)建起不計(jì)其數(shù)的容器,而運(yùn)行 docker build 命令所生成的鏡像仍可在 Kubernetes 集群內(nèi)正常運(yùn)行。
如果你使用的是 GKE 或者 EKS 等托管 Kubernetes 服務(wù),則需要確保在未來(lái)的 Kubernetes 版本徹底去除 Docker 支持之前,為你的工作節(jié)點(diǎn)引入受支持的容器運(yùn)行時(shí)。
如果節(jié)點(diǎn)中包含自定義項(xiàng),你可能需要根據(jù)當(dāng)前環(huán)境及運(yùn)行時(shí)要求做出更新。請(qǐng)與服務(wù)供應(yīng)商合作,確保正確完成升級(jí)測(cè)試及規(guī)劃。
如果你的集群一直在滾動(dòng)擴(kuò)展,則需要配合變量以避免服務(wù)中斷。在 1.20 版本中,你將收到 Docker 棄用警告。
而在未來(lái)的 Kubernets 版本(計(jì)劃在 2021 年下半年發(fā)布的 1.23 版本)中,Docker 運(yùn)行時(shí)將被徹底移除、不再受到支持,屆時(shí)您必須切換至其他兼容的容器運(yùn)行時(shí),例如 containerd 或者 CRI-O。
只需要保證你所選定的運(yùn)行時(shí),能夠支持當(dāng)前使用的 Docker 守護(hù)程序配置即可(例如日志記錄)。
既然問(wèn)題不大,大家在慌什么?在怕什么?
這里我們需要探討兩種不同的環(huán)境,而這也是恐慌情緒的根源。首先,在 Kubernetes 集群內(nèi)部存在一種叫作容器運(yùn)行時(shí)的東西,負(fù)責(zé)提取并運(yùn)行容器鏡像。
Docker 是目前最流行的運(yùn)行時(shí)選項(xiàng)(其他常見(jiàn)選項(xiàng)還包括 containerd 與 CRI-O)。
但 Docker 在設(shè)計(jì)上并未考慮到被嵌入 Kubernetes 這種用法,所以可能引發(fā)問(wèn)題。
很明顯,這里我們提到的“Docker”并不是同一種東西——它代表著一整套技術(shù)棧,而 containerd 高級(jí)容器運(yùn)行時(shí)則是 Docker 中的一部分。
Docker 很酷、實(shí)用性極強(qiáng),提供多種用戶(hù)體驗(yàn)增強(qiáng)功能,讓我們能夠在開(kāi)發(fā)過(guò)程中輕松完成協(xié)同交互。
但是,用戶(hù)體驗(yàn)增強(qiáng)功能對(duì) Kubernetes 來(lái)說(shuō)并非必需,因?yàn)?Kubernetes 并不是什么人類(lèi)協(xié)作方。
結(jié)果就是,要想讓 containerd 這個(gè)人類(lèi)友好型抽象層發(fā)揮作用,Kubernetes 集群就必須引入另一款名為 Dockershimi 的工具。
但這款工具的介入又引發(fā)了新的問(wèn)題,因?yàn)槲覀儽仨氼~外加以維護(hù),否則就可能引發(fā)安全問(wèn)題。
事實(shí)上,Dockershim 早在 Kubelet 1.23 版本時(shí)就已經(jīng)被移除,或者說(shuō) Kubelet 很早就取消了將 Docker 作為容器運(yùn)行時(shí)的功能。
這時(shí)候很多朋友可能要問(wèn),既然 Docker 棧中已經(jīng)包含 containerd,Kubernetes 為什么還要畫(huà)蛇添足地搞出個(gè) Dockershim?
這是因?yàn)?Docker 與 CRI(即容器運(yùn)行時(shí)接口)并不相容。正是因?yàn)椴幌嗳?,所以我們才需?Dockershim 來(lái)緩沖一下。
但這不是什么大問(wèn)題,各位沒(méi)必要驚慌!這件事的本質(zhì),就是把容器運(yùn)行時(shí)從 Docker 轉(zhuǎn)換為另一種受支持的選項(xiàng)。
這里需要注意的是:如果大家將底層 Docker 套接字(/var/run/docker.sock)設(shè)定為集群工作流中的一部分,那么轉(zhuǎn)換至其他運(yùn)行時(shí)會(huì)破壞掉當(dāng)前業(yè)務(wù)的正常運(yùn)行。
這種模式稱(chēng)為 Docker in Docker,好在我們可以使用多種選項(xiàng)解決這個(gè)特定用例,包括 Kaniko、Img 以及 Buildah 等等。
對(duì)開(kāi)發(fā)者來(lái)說(shuō)意味著什么?
但這種變化對(duì)開(kāi)發(fā)者意味著什么?我們還需要編寫(xiě) Dockerfiles 嗎?未來(lái)還應(yīng)不應(yīng)該繼續(xù)使用 Docker?
請(qǐng)注意,本次變更所影響到的環(huán)境,其實(shí)跟大多數(shù)人用于進(jìn)行 Docker 交互的環(huán)境并不是一回事。
你在開(kāi)發(fā)中使用的 Docker 安裝,與 Kubernetes 集群中的 Docker 運(yùn)行時(shí)毫無(wú)關(guān)系。我知道,這事聽(tīng)起來(lái)讓人有點(diǎn)犯迷糊。
總之,對(duì)于開(kāi)發(fā)人員,Docker 在公布此次更改之前提供的所有方案都仍然適用。
Docker 生成的鏡像實(shí)際上并不特定于 Docker,更準(zhǔn)確地說(shuō)它應(yīng)該屬于 OCI(開(kāi)放容器倡議)鏡像。
任何與 OCI 相兼容的鏡像,無(wú)論使用哪種工具構(gòu)建而成,對(duì)于 Kubernetes 來(lái)說(shuō)都是一樣的。
Containerd 與 CRI-O 都能識(shí)別這些鏡像并正常運(yùn)行,這也是我們建立一套統(tǒng)一容器標(biāo)準(zhǔn)的意義所在。
因此,雖然變化即將到來(lái),雖然會(huì)給部分用戶(hù)帶來(lái)麻煩,但影響并不算大。而且從長(zhǎng)遠(yuǎn)角度看,這其實(shí)是件好事。
總而言之,希望大家放下抵觸和恐慌情緒,坦然接受這個(gè)變化。
參考鏈接:
- https://kubernetes.io/blog/2020/12/02/dont-panic-kubernetes-and-docker/
- https://dev.to/inductor/wait-docker-is-deprecated-in-kubernetes-now-what-do-i-do-e4m
出處:內(nèi)容來(lái)源公眾號(hào)分布式實(shí)驗(yàn)室(ID:dockerone)
分享題目:K8s宣布棄用Docker,千萬(wàn)別慌!
文章鏈接:http://www.5511xx.com/article/dhpsihg.html


咨詢(xún)
建站咨詢(xún)
