您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“如何在containerd中使用并配置Stream服務(wù)”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“如何在containerd中使用并配置Stream服務(wù)”吧!
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í)
已有集群通過 TKE 集群升級(jí)功能升級(jí)到 1.23時(shí), TKE會(huì)提供切換運(yùn)行時(shí)為 containerd 的選項(xiàng)。當(dāng)然,這種情況下沒辦法做到 Pod 不受影響,只能采用重裝節(jié)點(diǎn)的方式來升級(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ù),需要提前采取措施來避免產(chǎn)生問題,例如通過按節(jié)點(diǎn)標(biāo)簽調(diào)度,保證這類業(yè)務(wù)調(diào)度到 docker 節(jié)點(diǎn);或者采用如前文所述在 containerd 集群運(yùn)行 Docker in Docker 的方案)
當(dāng)然,在未來 docker 也有可能在內(nèi)部實(shí)現(xiàn) CRI 或者添加一個(gè) dockershim 進(jìn)程,如果 docker 做了相應(yīng)適配,TKE 這邊在未來也會(huì)進(jìn)行支持。
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. (#94624https://my.oschina.net/u/4534936/blog/, @dims) [SIG Node]
K8s 在 1.20的 change log 中提到 K8s 將于 1.20版本開始逐步放棄對(duì) Docker 的支持。在 K8s 的官方博客中也提到具體的聲明和一些 FAQ。
Don't Panic: Kubernetes and Docker
Dockershim FAQ
在博客中提到 K8s 將在 1.20版本中添加不推薦使用 docker 的信息,且最早將于 1.23版本中把 dockershim 從 kubelet 中移除,屆時(shí)用戶將無法使用 docker 作為 K8s 集群的運(yùn)行時(shí),不過通過 docker 構(gòu)建的鏡像在沒有 docker 的 K8s 集群中依然可以使用。
本次改動(dòng)主要內(nèi)容是準(zhǔn)備刪除 kubelet 中的 dockershim,當(dāng)然這種做法也是符合預(yù)期的。在早期 rkt 和 docker 爭(zhēng)霸時(shí),kubelet 中需要維護(hù)兩坨代碼分別來適配 docker 和 rkt ,這使得 kubelet 每次發(fā)布新功能都需要考慮對(duì)運(yùn)行時(shí)組件的適配問題,嚴(yán)重拖慢了新版本發(fā)布速度。另外虛擬化已經(jīng)是一個(gè)普遍的需求,如果出現(xiàn)了類型的運(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 就能通過這組接口來適配所有的運(yùn)行時(shí)。但 Docker 當(dāng)時(shí)并沒有(也不打算)實(shí)現(xiàn)這組接口, kubelet 只能在內(nèi)部維護(hù)一個(gè)稱之為“dockershim”組件,這個(gè)組件充當(dāng)了 docker 的 CRI 轉(zhuǎn)接器,kubelet 在創(chuàng)建容器時(shí)通過 CRI 接口調(diào)用 dockershim ,而 dockershim 在通過 http 請(qǐng)求把請(qǐng)求交給 docker 。于是 kubelet 的架構(gòu)變成下圖這樣: 在使用實(shí)現(xiàn)了 CRI 接口的組件作為容器運(yùn)行時(shí)的情況下,kubelet 創(chuàng)建容器的調(diào)用鏈如圖中紅色箭頭所示,kubelet 中的 ContainerManager 可以直接通過 CRI 調(diào)用到容器運(yùn)行時(shí),這過程中只需要一次 grpc 請(qǐng)求;而在使用 docker 時(shí),ContainerManager 會(huì)走圖中藍(lán)色的調(diào)用鏈, CRI 的請(qǐng)求通過 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)接器本來就是一種不優(yōu)雅的實(shí)現(xiàn),這種做法讓調(diào)用鏈變長(zhǎng)且不穩(wěn)定性,還給 kubelet 的維護(hù)添加了額外工作,把這部分內(nèi)容從 kubelet 刪掉就是時(shí)間問題了。
If you’re an end-user of Kuberneteshttps://my.oschina.net/u/4534936/blog/, not a whole lot will be changing for you. This doesn’t mean the death of Dockerhttps://my.oschina.net/u/4534936/blog/, and it doesn’t mean you can’thttps://my.oschina.net/u/4534936/blog/, or shouldn’thttps://my.oschina.net/u/4534936/blog/, use Docker as a development tool anymore. Docker is still a useful tool for building containershttps://my.oschina.net/u/4534936/blog/, 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)心的問題,我們來分析下官方提到的這些方面:
正常的 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è)基本無痛的過程。CRI-O 是另一個(gè)常被提及的運(yùn)行時(shí)組件,由 redhat 提供,比 containerd 更加輕量級(jí),不過和 docker 的區(qū)別較大,可能轉(zhuǎn)換時(shí)會(huì)有一些不同之處。
開發(fā)環(huán)境中通過docker build
構(gòu)建出來的鏡像依然可以在集群中使用
鏡像一直是容器生態(tài)的一大優(yōu)勢(shì),雖然人們總是把鏡像稱之為“docker鏡像”,但鏡像早就成為了一種規(guī)范了。具體規(guī)范可以參考image-spec。在任何地方只要構(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。我們可以通過把 docker daemon 作為 DaemonSet 或者給想要使用 docker 的 Pod 添加一個(gè) docker daemon 的 sidecar 的方式在任意運(yùn)行時(shí)中使用 DinD 的方案。TKE 也專門為在 containerd 集群中使用 DinD 提供了方案,詳見 在containerd中使用DinD。
所以 containerd 到底是個(gè)啥?和 docker 又是什么關(guān)系?可能有些同學(xué)看到博客后會(huì)發(fā)出這樣的疑問,接下來就給同學(xué)們講解下 containerd 和 docker 的淵源。
2016年,docker 把負(fù)責(zé)容器生命周期的模塊拆分出來,并將其捐贈(zèng)給了社區(qū),也就是現(xiàn)在的 containerd。docker 拆分后結(jié)構(gòu)如下圖所示(當(dāng)然 docker 公司還在 docker 中添加了部分編排的代碼)。 在我們調(diào)用 docker 命令創(chuàng)建容器后,docker daemon 會(huì)通過 Image 模塊下載鏡像并保存到 Graph Driver 模塊中,之后通過 client 調(diào)用containerd 創(chuàng)建并運(yùn)行容器。我們?cè)谑褂?docker 創(chuàng)建容器時(shí)可能需要使用--volume
給容器添加持久化存儲(chǔ);還有可能通過--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í)的模塊。 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 帶來創(chuàng)建 Pod 所需的全部功能,同時(shí)還得到了更純粹的功能模塊以及更短的調(diào)用鏈。 從上面的對(duì)比可以看出從 containerd 被捐贈(zèng)給社區(qū)開始,就一直以成為簡(jiǎn)單、穩(wěn)定且可靠的容器運(yùn)行時(shí)為目標(biāo);而 docker 則是希望能成為一個(gè)完整的產(chǎn)品。官方文檔中也提到了這一點(diǎn),docker 為了給用戶更好的交互和使用體驗(yàn)以及更多的功能,提供了很多開發(fā)人員所需要的特性,同時(shí)為了給 swarm 做基礎(chǔ),提供了網(wǎng)絡(luò)和卷的功能。而這些功能其實(shí)都是是 K8s 用不上的;containerd 則相反,僅提供了 kubelet 創(chuàng)建 Pod 所需要的基礎(chǔ)功能,當(dāng)然這換來的就是更高的魯棒性以及更好的性能。在一定程度上講,即使在 kubelet 1.23 版本之后 docker 提供了 CRI 接口,containerd 仍然是更好的選擇。
當(dāng)然現(xiàn)在有諸多的 CRI 實(shí)現(xiàn)者,比較主要的除了 containerd 還有 CRI-O。CRI-O 是主要由 Red Hat 員工開發(fā)的 CRI 運(yùn)行時(shí),完全和 docker 沒有關(guān)系,因此從 docker 遷移過來可能會(huì)比較困難。無疑 containerd 才是 docker 被拋棄后的 CRI 運(yùn)行時(shí)的最佳人選,對(duì)于開發(fā)同學(xué)來說整個(gè)遷移過程應(yīng)該是無感知的,不過對(duì)于部分運(yùn)維同學(xué)可能會(huì)比較在意部署和運(yùn)行中細(xì)節(jié)上的差異。接下來我們重點(diǎn)介紹下在 K8s 中使用 containerd 和 docker 的幾處區(qū)別。
容器日志對(duì)比項(xiàng)
對(duì)比項(xiàng) | Docker | Containerd |
---|---|---|
存儲(chǔ)路徑 | 如果 docker 作為 K8s 容器運(yùn)行時(shí),容器日志的落盤將由 docker 來完成,保存在類似/var/lib/docker/containers/$CONTAINERID 目錄下。kubelet 會(huì)在 /var/log/pods 和 /var/log/containers 下面建立軟鏈接,指向 /var/lib/docker/containers/$CONTAINERID 該目錄下的容器日志文件。 | 如果 Containerd 作為 K8s 容器運(yùn)行時(shí), 容器日志的落盤由 kubelet 來完成,保存至 /var/log/pods/$CONTAINER_NAME 目錄下,同時(shí)在 /var/log/containers 目錄下創(chuàng)建軟鏈接,指向日志文件。 |
配置參數(shù) | 在 docker 配置文件中指定:"log-driver": "json-file"https://cache.yisu.com/upload/information/20210522/355/608106"log-opts": {"max-size": "100m"https://cache.yisu.com/upload/information/20210522/355/608106"max-file": "5"} | 方法一:在 kubelet 參數(shù)中指定:--container-log-max-files=5 --container-log-max-size="100Mi" 方法二:在 KubeletConfiguration 中指定: "containerLogMaxSize": "100Mi"https://my.oschina.net/u/4534936/blog/, "containerLogMaxFiles": 5https://my.oschina.net/u/4534936/blog/, |
把容器日志保存到數(shù)據(jù)盤 | 把數(shù)據(jù)盤掛載到 “data-root”(缺省是 /var/lib/docker)即可。 | 創(chuàng)建一個(gè)軟鏈接 /var/log/pods 指向數(shù)據(jù)盤掛載點(diǎn)下的某個(gè)目錄。在 TKE 中選擇“將容器和鏡像存儲(chǔ)在數(shù)據(jù)盤”,會(huì)自動(dòng)創(chuàng)建軟鏈接 /var/log/pods。 |
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ū)別
說明:
Kubectl exec/logs 等命令需要在 apiserver 跟容器運(yùn)行時(shí)之間建立流轉(zhuǎn)發(fā)通道。
如何在 containerd 中使用并配置 Stream 服務(wù)?
Docker API 本身提供 stream 服務(wù),kubelet 內(nèi)部的 docker-shim 會(huì)通過 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
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 直接訪問 containerd 的 stream 服務(wù)。此時(shí),您需要給 stream 服務(wù)轉(zhuǎn)發(fā)器認(rèn)證,用于安全防護(hù)。
在 K8s 1.11 之后: K8s1.11 引入了 kubelet stream proxy, 使 containerd stream 服務(wù)只需要監(jiān)聽本地地址即可。
從 2019年5月份開始,TKE就開始支持把 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 的問題并且及時(shí)進(jìn)行了修復(fù),如:
由于錯(cuò)誤處理問題導(dǎo)致的 Pod Terminating
由于內(nèi)核版本問題導(dǎo)致鏡像文件丟失
想要在TKE集群中使用 containerd 作為運(yùn)行時(shí)有三種方式:
在創(chuàng)建集群時(shí),選擇 1.12.4 及以上版本的 K8s 后,選擇 containerd 為運(yùn)行時(shí)組件即可
在已有 docker 集群中,通過創(chuàng)建運(yùn)行時(shí)為 containerd 的節(jié)點(diǎn)池來創(chuàng)建一部分 containerd 節(jié)點(diǎn)(新建節(jié)點(diǎn)池 > 更多設(shè)置 > 運(yùn)行時(shí)組件)
在已有 docker 集群中,修改集群或者節(jié)點(diǎn)池的"運(yùn)行時(shí)組件"屬性為"containerd"
注意: 后兩種方式會(huì)造成同一集群中 docker 節(jié)點(diǎn)與 containerd 節(jié)點(diǎn)共存,如果有使用 Docker in Docker, 或者其他依賴節(jié)點(diǎn)上 docker daemon 與 docker.sock 的業(yè)務(wù),需要提前采取措施來避免產(chǎn)生問題,例如通過按節(jié)點(diǎn)標(biāo)簽調(diào)度,保證這類業(yè)務(wù)調(diào)度到 docker 節(jié)點(diǎn);或者采用如前文所述在 containerd 集群運(yùn)行 Docker in Docker 的方案。
到此,相信大家對(duì)“如何在containerd中使用并配置Stream服務(wù)”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。