騰訊云:K8s終將廢棄docker,TKE早已支持containerd

來(lái)源: 騰訊云原生
作者:李志宇 洪志國(guó)
時(shí)間:2020-12-14
17066
本文會(huì)做詳細(xì)解讀,并介紹docker與containerd的關(guān)系,以及為什么containerd是更好的選擇。

近日K8s官方稱最早將在1.23版本棄用docker作為容器運(yùn)行時(shí),并在博客中強(qiáng)調(diào)可以使用如containerd等CRI運(yùn)行時(shí)來(lái)代替docker。

本文會(huì)做詳細(xì)解讀,并介紹docker與containerd的關(guān)系,以及為什么containerd是更好的選擇。

這里先回答下TKE用戶關(guān)心的問(wèn)題:我們的集群該怎么辦?

TKE集群該怎么辦

·TKE早在2019年5月就已經(jīng)支持選擇containerd作為容器運(yùn)行時(shí)。如果新建集群,推薦選擇containerd作為容器運(yùn)行時(shí)

·已有集群在升級(jí)到K8s 1.23(假定TKE第一個(gè)不支持dockershim的K8s版本,也可能是1.24)之前,仍然可以繼續(xù)使用docker作為容器運(yùn)行時(shí)

·已有集群通過(guò)TKE集群升級(jí)功能升級(jí)到1.23時(shí),TKE會(huì)提供切換運(yùn)行時(shí)為containerd的選項(xiàng)。當(dāng)然,這種情況下沒(méi)辦法做到Pod不受影響,只能采用重裝節(jié)點(diǎn)的方式來(lái)升級(jí)

·已有集群也可以將運(yùn)行時(shí)切換為containerd,新增節(jié)點(diǎn)會(huì)使用containerd,存量節(jié)點(diǎn)不受影響仍然使用docker(注意:這會(huì)造成同一集群中docker節(jié)點(diǎn)與containerd節(jié)點(diǎn)共存,如果·有使用Docker in Docker,或者其他依賴節(jié)點(diǎn)上docker daemon與docker.sock的業(yè)務(wù),需要提前采取措施來(lái)避免產(chǎn)生問(wèn)題,例如通過(guò)按節(jié)點(diǎn)標(biāo)簽調(diào)度,保證這類(lèi)業(yè)務(wù)調(diào)度到docker節(jié)點(diǎn);或者采用如前文所述在containerd集群運(yùn)行Docker in Docker的方案)

·當(dāng)然,在未來(lái)docker也有可能在內(nèi)部實(shí)現(xiàn)CRI或者添加一個(gè)dockershim進(jìn)程,如果docker做了相應(yīng)適配,TKE這邊在未來(lái)也會(huì)進(jìn)行支持。

解讀K8s棄用dockershim

Docker support in the kubelet is now deprecated and will be removed in a future release.The kubelet uses a module called"dockershim"which implements CRI support for Docker and it has seen maintenance issues in the Kubernetes community.We encourage you to evaluate moving to a container runtime that is a full-fledged implementation of CRI(v1alpha1 or v1 compliant)as they become available.(#94624[1],dims[2])[SIG Node]

K8s在1.20的change log中提到K8s將于1.20版本開(kāi)始逐步放棄對(duì)Docker的支持。在K8s的官方博客中也提到具體的聲明和一些FAQ。

·Don't Panic:Kubernetes and Docker[3]

·Dockershim FAQ[4]

在博客中提到K8s將在1.20版本中添加不推薦使用docker的信息,且最早將于1.23版本中把dockershim從kubelet中移除,屆時(shí)用戶將無(wú)法使用docker作為K8s集群的運(yùn)行時(shí),不過(guò)通過(guò)docker構(gòu)建的鏡像在沒(méi)有docker的K8s集群中依然可以使用。

“寄生”在kubelet中的dockershim

本次改動(dòng)主要內(nèi)容是準(zhǔn)備刪除kubelet中的dockershim,當(dāng)然這種做法也是符合預(yù)期的。

在早期rkt和docker爭(zhēng)霸時(shí),kubelet中需要維護(hù)兩坨代碼分別來(lái)適配docker和rkt,這使得kubelet每次發(fā)布新功能都需要考慮對(duì)運(yùn)行時(shí)組件的適配問(wèn)題,嚴(yán)重拖慢了新版本發(fā)布速度。

另外虛擬化已經(jīng)是一個(gè)普遍的需求,如果出現(xiàn)了類(lèi)型的運(yùn)行時(shí),SIG-Node小組可能還需要把和新運(yùn)行時(shí)適配的代碼添加到kubelet中。這種做法并不是長(zhǎng)久之計(jì),于是在2016年,SIG-Node提出了容器操作接口CRI(Container Runtime Interface)。

CRI是對(duì)容器操作的一組抽象,只要每種容器運(yùn)行時(shí)都實(shí)現(xiàn)這組接口,kubelet就能通過(guò)這組接口來(lái)適配所有的運(yùn)行時(shí)。但Docker當(dāng)時(shí)并沒(méi)有(也不打算)實(shí)現(xiàn)這組接口,kubelet只能在內(nèi)部維護(hù)一個(gè)稱之為“dockershim”組件,這個(gè)組件充當(dāng)了docker的CRI轉(zhuǎn)接器,kubelet在創(chuàng)建容器時(shí)通過(guò)CRI接口調(diào)用dockershim,而dockershim在通過(guò)http請(qǐng)求把請(qǐng)求交給docker。

于是kubelet的架構(gòu)變成下圖這樣:

640.png

在使用實(shí)現(xiàn)了CRI接口的組件作為容器運(yùn)行時(shí)的情況下,kubelet創(chuàng)建容器的調(diào)用鏈如圖中紅色箭頭所示,kubelet中的ContainerManager可以直接通過(guò)CRI調(diào)用到容器運(yùn)行時(shí),這過(guò)程中只需要一次grpc請(qǐng)求;

而在使用docker時(shí),ContainerManager會(huì)走圖中藍(lán)色的調(diào)用鏈,CRI的請(qǐng)求通過(guò)unix:///var/run/dockershim.sock流向dockershim,dockershim做轉(zhuǎn)換后把請(qǐng)求轉(zhuǎn)發(fā)給docker,至于為什么docker后面還有個(gè)containerd稍后會(huì)講到。

在kubelet中實(shí)現(xiàn)docker的轉(zhuǎn)接器本來(lái)就是一種不優(yōu)雅的實(shí)現(xiàn),這種做法讓調(diào)用鏈變長(zhǎng)且不穩(wěn)定性,還給kubelet的維護(hù)添加了額外工作,把這部分內(nèi)容從kubelet刪掉就是時(shí)間問(wèn)題了。

棄用Docker后會(huì)有什么不同?

If you’re an end-user of Kubernetes,not a whole lot will be changing for you.This doesn’t mean the death of Docker,and it doesn’t mean you can’t,or shouldn’t,use Docker as a development tool anymore.Docker is still a useful tool for building containers,and the images that result from running docker build can still run in your Kubernetes cluster.

消息一出,大家最關(guān)心的事情應(yīng)該就是棄用docker后到底會(huì)產(chǎn)生什么影響?

官方的答復(fù)是:Don't Panic!隨后又重點(diǎn)解釋了幾個(gè)大家最關(guān)心的問(wèn)題,我們來(lái)分析下官方提到的這些方面:

·正常的K8s用戶不會(huì)有任何影響

是的,生產(chǎn)環(huán)境中高版本的集群只需要把運(yùn)行時(shí)從docker切換到其他的runtime(如containerd)即可。containerd是docker中的一個(gè)底層組件,主要負(fù)責(zé)維護(hù)容器的生命周期,跟隨docker經(jīng)歷了長(zhǎng)期考驗(yàn)。同時(shí)2019年初就從CNCF畢業(yè),可以單獨(dú)作為容器運(yùn)行時(shí)用在集群中。TKE也早在2019年就已經(jīng)提供了containerd作為運(yùn)行時(shí)選項(xiàng),因此把runtime從docker轉(zhuǎn)換到containerd是一個(gè)基本無(wú)痛的過(guò)程。CRI-O是另一個(gè)常被提及的運(yùn)行時(shí)組件,由redhat提供,比containerd更加輕量級(jí),不過(guò)和docker的區(qū)別較大,可能轉(zhuǎn)換時(shí)會(huì)有一些不同之處。

·開(kāi)發(fā)環(huán)境中通過(guò)docker build構(gòu)建出來(lái)的鏡像依然可以在集群中使用

鏡像一直是容器生態(tài)的一大優(yōu)勢(shì),雖然人們總是把鏡像稱之為“docker鏡像”,但鏡像早就成為了一種規(guī)范了。具體規(guī)范可以參考image-spec[5]。在任何地方只要構(gòu)建出符合Image Spec的鏡像,就可以拿到其他符合Image Spec的容器運(yùn)行時(shí)上運(yùn)行。

·在Pod中使用DinD(Docker in Docker)的用戶會(huì)受到影響

有些使用者會(huì)把docker的socket(/run/docker.sock)掛載到Pod中,并在Pod中調(diào)用docker的api構(gòu)建鏡像或創(chuàng)建編譯容器等,官方在這里的建議是使用Kaniko、Img或Buildah。我們可以通過(guò)把docker daemon作為DaemonSet或者給想要使用docker的Pod添加一個(gè)docker daemon的sidecar的方式在任意運(yùn)行時(shí)中使用DinD的方案。TKE也專(zhuān)門(mén)為在containerd集群中使用DinD提供了方案,詳見(jiàn)在containerd中使用DinD[6]。

containerd的今生前世

所以containerd到底是個(gè)啥?和docker又是什么關(guān)系?可能有些同學(xué)看到博客后會(huì)發(fā)出這樣的疑問(wèn),接下來(lái)就給同學(xué)們講解下containerd和docker的淵源。

docker與containerd

2016年,docker把負(fù)責(zé)容器生命周期的模塊拆分出來(lái),并將其捐贈(zèng)給了社區(qū),也就是現(xiàn)在的containerd。docker拆分后結(jié)構(gòu)如下圖所示(當(dāng)然docker公司還在docker中添加了部分編排的代碼)。

640.png

在我們調(diào)用docker命令創(chuàng)建容器后,docker daemon會(huì)通過(guò)Image模塊下載鏡像并保存到Graph Driver模塊中,之后通過(guò)client調(diào)用containerd創(chuàng)建并運(yùn)行容器。我們?cè)谑褂胐ocker創(chuàng)建容器時(shí)可能需要使用--volume給容器添加持久化存儲(chǔ);還有可能通過(guò)--network連接我們用docker命令創(chuàng)建的幾個(gè)容器,當(dāng)然,這些功能是docker中的Storage模塊和Networking模塊提供給我們的。但K8s提供了更強(qiáng)的卷掛載能力和集群級(jí)別的網(wǎng)絡(luò)能力,在集群中kubelet只會(huì)使用到docker提供的鏡像下載和容器管理功能,而編排、網(wǎng)絡(luò)、存儲(chǔ)等功能都不會(huì)用到。下圖中可以看出當(dāng)前的模式下各模塊的調(diào)用鏈,同時(shí)圖中被紅框標(biāo)注出的幾個(gè)模塊就是kubelet創(chuàng)建Pod時(shí)所依賴的幾個(gè)運(yùn)行時(shí)的模塊。

640 (1).png

containerd被捐贈(zèng)給CNCF社區(qū)后,社區(qū)給其添加了鏡像管理模塊和CRI模塊,這樣containerd不只可以管理容器的生命周期,還可以直接作為K8s的運(yùn)行時(shí)使用。于是containerd在2019年2月從CNCF社區(qū)畢業(yè),正式進(jìn)入生產(chǎn)環(huán)境。下圖中能看出以containerd作為容器運(yùn)行時(shí),可以給kubelet帶來(lái)創(chuàng)建Pod所需的全部功能,同時(shí)還得到了更純粹的功能模塊以及更短的調(diào)用鏈。

640 (2).png

從上面的對(duì)比可以看出從containerd被捐贈(zèng)給社區(qū)開(kāi)始,就一直以成為簡(jiǎn)單、穩(wěn)定且可靠的容器運(yùn)行時(shí)為目標(biāo);而docker則是希望能成為一個(gè)完整的產(chǎn)品。官方文檔中也提到了這一點(diǎn),docker為了給用戶更好的交互和使用體驗(yàn)以及更多的功能,提供了很多開(kāi)發(fā)人員所需要的特性,同時(shí)為了給swarm做基礎(chǔ),提供了網(wǎng)絡(luò)和卷的功能。而這些功能其實(shí)都是是K8s用不上的;containerd則相反,僅提供了kubelet創(chuàng)建Pod所需要的基礎(chǔ)功能,當(dāng)然這換來(lái)的就是更高的魯棒性以及更好的性能。在一定程度上講,即使在kubelet 1.23版本之后docker提供了CRI接口,containerd仍然是更好的選擇。

在Kubernetes集群中使用containerd

當(dāng)然現(xiàn)在有諸多的CRI實(shí)現(xiàn)者,比較主要的除了containerd還有CRI-O。CRI-O是主要由Red Hat員工開(kāi)發(fā)的CRI運(yùn)行時(shí),完全和docker沒(méi)有關(guān)系,因此從docker遷移過(guò)來(lái)可能會(huì)比較困難。無(wú)疑containerd才是docker被拋棄后的CRI運(yùn)行時(shí)的最佳人選,對(duì)于開(kāi)發(fā)同學(xué)來(lái)說(shuō)整個(gè)遷移過(guò)程應(yīng)該是無(wú)感知的,不過(guò)對(duì)于部分運(yùn)維同學(xué)可能會(huì)比較在意部署和運(yùn)行中細(xì)節(jié)上的差異。接下來(lái)我們重點(diǎn)介紹下在K8s中使用containerd和docker的幾處區(qū)別。

·容器日志對(duì)比項(xiàng)

640 (3).png

cni配置方式的區(qū)別在使用docker時(shí),kubelet中的dockershim負(fù)責(zé)調(diào)用cni插件,而containerd的場(chǎng)景中containerd中內(nèi)置的containerd-cri插件負(fù)責(zé)調(diào)用cni,因此關(guān)于cni的配置文件需要放在containerd的配置文件中(/etc/containerd/containerd.toml):

 [plugins.cri.cni]

      bin_dir = "/opt/cni/bin"

      conf_dir = "/etc/cni/net.d"

·stream服務(wù)的區(qū)別

說(shuō)明:

Kubectl exec/logs等命令需要在apiserver跟容器運(yùn)行時(shí)之間建立流轉(zhuǎn)發(fā)通道。

如何在containerd中使用并配置Stream服務(wù)?

Docker API本身提供stream服務(wù),kubelet內(nèi)部的docker-shim會(huì)通過(guò)docker API做流轉(zhuǎn)發(fā)。而containerd的stream服務(wù)需要單獨(dú)配置:

[plugins.cri]

stream_server_address="127.0.0.1"

stream_server_port="0"

enable_tls_streaming=false[plugins.cri]stream_server_address="127.0.0.1"stream_server_port="0"enable_tls_streaming=false

K8s 1.11前后版本配置區(qū)別是什么?

containerd的stream服務(wù)在K8s不同版本運(yùn)行時(shí)場(chǎng)景下配置不同。

·在K8s 1.11之前:kubelet不會(huì)做stream proxy,只會(huì)做重定向。即kubelet會(huì)將containerd暴露的stream server地址發(fā)送給apiserver,并讓apiserver直接訪問(wèn)containerd的stream服務(wù)。此時(shí),您需要給stream服務(wù)轉(zhuǎn)發(fā)器認(rèn)證,用于安全防護(hù)。

·在K8s 1.11之后:K8s1.11引入了kubelet stream proxy[7],使containerd stream服務(wù)只需要監(jiān)聽(tīng)本地地址即可。

在TKE集群中使用containerd

從2019年5月份開(kāi)始,TKE就開(kāi)始支持把containerd作為容器運(yùn)行時(shí)選項(xiàng)之一。隨著TKE逐步在containerd集群中支持日志收集服務(wù)和GPU能力,2020年9月份containerd在TKE也摘掉了Beta版本的標(biāo)簽,可以正式用于生產(chǎn)環(huán)境中了。在長(zhǎng)期使用中,我們也發(fā)現(xiàn)了一些containerd的問(wèn)題并且及時(shí)進(jìn)行了修復(fù),如:

·由于錯(cuò)誤處理問(wèn)題導(dǎo)致的Pod Terminating

·由于內(nèi)核版本問(wèn)題導(dǎo)致鏡像文件丟失

想要在TKE集群中使用containerd作為運(yùn)行時(shí)有三種方式:

1.在創(chuàng)建集群時(shí),選擇1.12.4及以上版本的K8s后,選擇containerd為運(yùn)行時(shí)組件即可

640 (4).png

2.在已有docker集群中,通過(guò)創(chuàng)建運(yùn)行時(shí)為containerd的節(jié)點(diǎn)池來(lái)創(chuàng)建一部分containerd節(jié)點(diǎn)(新建節(jié)點(diǎn)池>更多設(shè)置>運(yùn)行時(shí)組件)

640 (5).png

3.在已有docker集群中,修改集群或者節(jié)點(diǎn)池的"運(yùn)行時(shí)組件"屬性為"containerd"

640 (6).png

注意:后兩種方式會(huì)造成同一集群中docker節(jié)點(diǎn)與containerd節(jié)點(diǎn)共存,如果有使用Docker in Docker,或者其他依賴節(jié)點(diǎn)上docker daemon與docker.sock的業(yè)務(wù),需要提前采取措施來(lái)避免產(chǎn)生問(wèn)題,例如通過(guò)按節(jié)點(diǎn)標(biāo)簽調(diào)度,保證這類(lèi)業(yè)務(wù)調(diào)度到docker節(jié)點(diǎn);或者采用如前文所述在containerd集群運(yùn)行Docker in Docker的方案。

現(xiàn)階段關(guān)于containerd和docker選擇問(wèn)題可以查看文檔如何選擇Containerd和Docker[8]。

參考資料

[1]#94624:https://github.com/kubernetes/kubernetes/pull/94624

[2]dims:https://github.com/dims

[3]Don't Panic:Kubernetes and Docker:https://kubernetes.io/blog/2020/12/02/dont-panic-kubernetes-and-docker/

[4]Dockershim FAQ:https://kubernetes.io/blog/2020/12/02/dockershim-faq/

[5]image-spec:https://github.com/opencontainers/image-spec

[6]在containerd中使用DinD:https://tencentcloudcontainerteam.github.io/2020/12/08/dind-in-containerd/

[7]kubelet stream proxy:https://github.com/kubernetes/kubernetes/pull/64006

[8]如何選擇Containerd和Docker:https://cloud.tencent.com/document/product/457/35747

[9]Dockershim Removal Kubernetes Enhancement Proposal:https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/1985-remove-dockershim

[10]kubernetes CHANGELOG-1.20:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#deprecation

立即登錄,閱讀全文
版權(quán)說(shuō)明:
本文內(nèi)容來(lái)自于騰訊云原生,本站不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。文章內(nèi)容系作者個(gè)人觀點(diǎn),不代表快出海對(duì)觀點(diǎn)贊同或支持。如有侵權(quán),請(qǐng)聯(lián)系管理員(zzx@kchuhai.com)刪除!
相關(guān)文章
騰訊云數(shù)據(jù)庫(kù)PostgreSQL全面支持PG 17
騰訊云數(shù)據(jù)庫(kù)PostgreSQL全面支持PG 17
即日起,騰訊云PostgreSQL全面支持PostgreSQL 17.0。所有用戶可使用大版本升級(jí)能力升級(jí)至最新的PostgreSQL 17.0進(jìn)行體驗(yàn),也可以在產(chǎn)品購(gòu)買(mǎi)頁(yè)直接購(gòu)買(mǎi)。
騰訊云
云服務(wù)
2024-12-152024-12-15
高可用這個(gè)問(wèn)題,加機(jī)器就能解決?
高可用這個(gè)問(wèn)題,加機(jī)器就能解決?
互聯(lián)網(wǎng)服務(wù)的可用性問(wèn)題是困擾企業(yè)IT人員的達(dá)摩克利斯之劍:防于未然,體現(xiàn)不出價(jià)值。已然發(fā)生,又面臨P0危機(jī)。就更別提穩(wěn)定性建設(shè)背后顯性的IT預(yù)算問(wèn)題與隱性的人員成本問(wèn)題。
騰訊云
云服務(wù)
2024-11-252024-11-25
TDSQL TDStore引擎版替換HBase:在歷史庫(kù)場(chǎng)景中的成本與性能優(yōu)勢(shì)
TDSQL TDStore引擎版替換HBase:在歷史庫(kù)場(chǎng)景中的成本與性能優(yōu)勢(shì)
HBase憑借其高可用性、高擴(kuò)展性和強(qiáng)一致性,以及在廉價(jià)PC服務(wù)器上的低部署成本,廣泛應(yīng)用于大規(guī)模數(shù)據(jù)分析。
騰訊云
云服務(wù)
2024-11-042024-11-04
復(fù)雜查詢性能弱,只讀分析引擎來(lái)幫忙
復(fù)雜查詢性能弱,只讀分析引擎來(lái)幫忙
隨著當(dāng)今業(yè)務(wù)的高速發(fā)展,復(fù)雜多表關(guān)聯(lián)的場(chǎng)景越來(lái)越普遍。但基于行式存儲(chǔ)的數(shù)據(jù)庫(kù)在進(jìn)行復(fù)雜查詢時(shí)性能相對(duì)較弱。
騰訊云
云服務(wù)
2024-11-022024-11-02
優(yōu)質(zhì)服務(wù)商推薦
更多
掃碼登錄
打開(kāi)掃一掃, 關(guān)注公眾號(hào)后即可登錄/注冊(cè)
加載中
二維碼已失效 請(qǐng)重試
刷新
賬號(hào)登錄/注冊(cè)
個(gè)人VIP
小程序
快出海小程序
公眾號(hào)
快出海公眾號(hào)
商務(wù)合作
商務(wù)合作
投稿采訪
投稿采訪
出海管家
出海管家