Containerd簡介

一,容器運行時

學(xué)習(xí)containerd時回顧一下docker的歷史,因為這里面牽涉到的組件實戰(zhàn)是有點多牢酵,有很多我們會經(jīng)常聽到,但是不清楚這些組件到底是干什么用的怖现,比如 libcontainer茁帽、runc、containerd屈嗤、CRI潘拨、OCI 等等。

Docker

從 Docker 1.11 版本開始饶号,Docker 容器運行就不是簡單通過 Docker Daemon 來啟動了铁追,而是通過集成 containerd、runc 等多個組件來完成的茫船。雖然 Docker Daemon 守護進程模塊在不停的重構(gòu)琅束,但是基本功能和定位沒有太大的變化,一直都是 CS 架構(gòu)算谈,守護進程負(fù)責(zé)和 Docker Client 端交互涩禀,并管理 Docker 鏡像和容器。現(xiàn)在的架構(gòu)中組件 containerd 就會負(fù)責(zé)集群節(jié)點上容器的生命周期管理然眼,并向上為 Docker Daemon 提供 gRPC 接口艾船。

20210809154608.png

當(dāng)我們要創(chuàng)建一個容器的時候,現(xiàn)在 Docker Daemon 并不能直接幫我們創(chuàng)建了,而是請求 containerd 來創(chuàng)建一個容器屿岂,containerd 收到請求后践宴,也并不會直接去操作容器,而是創(chuàng)建一個叫做 containerd-shim 的進程爷怀,讓這個進程去操作容器阻肩,我們指定容器進程是需要一個父進程來做狀態(tài)收集、維持 stdin 等 fd 打開等工作的运授,假如這個父進程就是 containerd烤惊,那如果 containerd 掛掉的話,整個宿主機上所有的容器都得退出了吁朦,而引入 containerd-shim 這個墊片就可以來規(guī)避這個問題了撕氧。

然后創(chuàng)建容器需要做一些 namespaces 和 cgroups 的配置,以及掛載 root 文件系統(tǒng)等操作喇完,這些操作其實已經(jīng)有了標(biāo)準(zhǔn)的規(guī)范,那就是 OCI(開放容器標(biāo)準(zhǔn))剥啤,runc 就是它的一個參考實現(xiàn)(Docker 被逼無耐將 libcontainer 捐獻出來改名為 runc 的)锦溪,這個標(biāo)準(zhǔn)其實就是一個文檔,主要規(guī)定了容器鏡像的結(jié)構(gòu)府怯、以及容器需要接收哪些操作指令刻诊,比如 create、start牺丙、stop则涯、delete 等這些命令。runc 就可以按照這個 OCI 文檔來創(chuàng)建一個符合規(guī)范的容器冲簿,既然是標(biāo)準(zhǔn)肯定就有其他 OCI 實現(xiàn)粟判,比如 Kata、gVisor 這些容器運行時都是符合 OCI 標(biāo)準(zhǔn)的峦剔。

所以真正啟動容器是通過 containerd-shim 去調(diào)用 runc 來啟動容器的档礁,runc 啟動完容器后本身會直接退出,containerd-shim 則會成為容器進程的父進程, 負(fù)責(zé)收集容器進程的狀態(tài), 上報給 containerd, 并在容器中 pid 為 1 的進程退出后接管容器中的子進程進行清理, 確保不會出現(xiàn)僵尸進程吝沫。

而 Docker 將容器操作都遷移到 containerd 中去是因為當(dāng)前做 Swarm呻澜,想要進軍 PaaS 市場,做了這個架構(gòu)切分惨险,讓 Docker Daemon 專門去負(fù)責(zé)上層的封裝編排羹幸,當(dāng)然后面的結(jié)果我們知道 Swarm 在 Kubernetes 面前是慘敗,然后 Docker 公司就把 containerd 項目捐獻給了 CNCF 基金會辫愉,這個也是現(xiàn)在的 Docker 架構(gòu)栅受。

二,CRI

我們知道 Kubernetes 提供了一個 CRI 的容器運行時接口,那么這個 CRI 到底是什么呢窘疮?這個其實也和 Docker 的發(fā)展密切相關(guān)的袋哼。

在 Kubernetes 早期的時候,當(dāng)時 Docker 實在是太火了闸衫,Kubernetes 當(dāng)然會先選擇支持 Docker涛贯,而且是通過硬編碼的方式直接調(diào)用 Docker API,后面隨著 Docker 的不斷發(fā)展以及 Google 的主導(dǎo)蔚出,出現(xiàn)了更多容器運行時弟翘,Kubernetes 為了支持更多更精簡的容器運行時,Google 就和紅帽主導(dǎo)推出了 CRI 標(biāo)準(zhǔn)骄酗,用于將 Kubernetes 平臺和特定的容器運行時(當(dāng)然主要是為了干掉 Docker)解耦稀余。

CRI(Container Runtime Interface 容器運行時接口)本質(zhì)上就是 Kubernetes 定義的一組與容器運行時進行交互的接口,所以只要實現(xiàn)了這套接口的容器運行時都可以對接到 Kubernetes 平臺上來趋翻。不過 Kubernetes 推出 CRI 這套標(biāo)準(zhǔn)的時候還沒有現(xiàn)在的統(tǒng)治地位睛琳,所以有一些容器運行時可能不會自身就去實現(xiàn) CRI 接口,于是就有了 shim(墊片)踏烙, 一個 shim 的職責(zé)就是作為適配器將各種容器運行時本身的接口適配到 Kubernetes 的 CRI 接口上师骗,其中 dockershim 就是 Kubernetes 對接 Docker 到 CRI 接口上的一個墊片實現(xiàn)。


image.png

Kubelet 通過 gRPC 框架與容器運行時或 shim 進行通信讨惩,其中 kubelet 作為客戶端辟癌,CRI shim(也可能是容器運行時本身)作為服務(wù)器。

CRI 定義的 API 主要包括兩個 gRPC 服務(wù)荐捻,ImageServiceRuntimeService黍少,ImageService 服務(wù)主要是拉取鏡像、查看和刪除鏡像等操作处面,RuntimeService 則是用來管理 Pod 和容器的生命周期厂置,以及與容器交互的調(diào)用(exec/attach/port-forward)等操作,可以通過 kubelet 中的標(biāo)志 --container-runtime-endpoint--image-service-endpoint 來配置這兩個服務(wù)的套接字鸳君。

image.png

不過這里同樣也有一個例外农渊,那就是 Docker,由于 Docker 當(dāng)時的江湖地位很高或颊,Kubernetes 是直接內(nèi)置了 dockershim 在 kubelet 中的砸紊,所以如果你使用的是 Docker 這種容器運行時的話是不需要單獨去安裝配置適配器之類的,當(dāng)然這個舉動似乎也麻痹了 Docker 公司囱挑。
image.png

現(xiàn)在如果我們使用的是 Docker 的話醉顽,當(dāng)我們在 Kubernetes 中創(chuàng)建一個 Pod 的時候,首先就是 kubelet 通過 CRI 接口調(diào)用 dockershim平挑,請求創(chuàng)建一個容器游添,kubelet 可以視作一個簡單的 CRI Client, 而 dockershim 就是接收請求的 Server系草,不過他們都是在 kubelet 內(nèi)置的。

dockershim 收到請求后, 轉(zhuǎn)化成 Docker Daemon 能識別的請求, 發(fā)到 Docker Daemon 上請求創(chuàng)建一個容器唆涝,請求到了 Docker Daemon 后續(xù)就是 Docker 創(chuàng)建容器的流程了找都,去調(diào)用 containerd,然后創(chuàng)建 containerd-shim 進程廊酣,通過該進程去調(diào)用 runc 去真正創(chuàng)建容器能耻。

其實我們仔細(xì)觀察也不難發(fā)現(xiàn)使用 Docker 的話其實是調(diào)用鏈比較長的,真正容器相關(guān)的操作其實 containerd 就完全足夠了亡驰,Docker 太過于復(fù)雜笨重了晓猛,當(dāng)然 Docker 深受歡迎的很大一個原因就是提供了很多對用戶操作比較友好的功能,但是對于 Kubernetes 來說壓根不需要這些功能凡辱,因為都是通過接口去操作容器的戒职,所以自然也就可以將容器運行時切換到 containerd 來。
[圖片上傳中...(image.png-53768d-1651282342321-0)]

image.png

切換到 containerd 可以消除掉中間環(huán)節(jié)透乾,操作體驗也和以前一樣洪燥,但是由于直接用容器運行時調(diào)度容器,所以它們對 Docker 來說是不可見的乳乌。 因此蚓曼,你以前用來檢查這些容器的 Docker 工具就不能使用了。

你不能再使用 docker ps 或 docker inspect 命令來獲取容器信息钦扭。由于不能列出容器,因此也不能獲取日志床绪、停止容器客情,甚至不能通過 docker exec 在容器中執(zhí)行命令。

當(dāng)然我們?nèi)匀豢梢韵螺d鏡像癞己,或者用 docker build 命令構(gòu)建鏡像膀斋,但用 Docker 構(gòu)建、下載的鏡像痹雅,對于容器運行時和 Kubernetes仰担,均不可見。為了在 Kubernetes 中使用绩社,需要把鏡像推送到鏡像倉庫中去摔蓝。

從上圖可以看出在 containerd 1.0 中,對 CRI 的適配是通過一個單獨的 CRI-Containerd 進程來完成的愉耙,這是因為最開始 containerd 還會去適配其他的系統(tǒng)(比如 swarm)贮尉,所以沒有直接實現(xiàn) CRI,所以這個對接工作就交給 CRI-Containerd 這個 shim 了朴沿。

然后到了 containerd 1.1 版本后就去掉了 CRI-Containerd 這個 shim猜谚,直接把適配邏輯作為插件的方式集成到了 containerd 主進程中败砂,現(xiàn)在這樣的調(diào)用就更加簡潔了。


image.png

與此同時 Kubernetes 社區(qū)也做了一個專門用于 Kubernetes 的 CRI 運行時 CRI-O魏铅,直接兼容 CRI 和 OCI 規(guī)范昌犹。


這個方案和 containerd 的方案顯然比默認(rèn)的 dockershim 簡潔很多,不過由于大部分用戶都比較習(xí)慣使用 Docker览芳,所以大家還是更喜歡使用 dockershim 方案斜姥。

但是隨著 CRI 方案的發(fā)展,以及其他容器運行時對 CRI 的支持越來越完善路操,Kubernetes 社區(qū)在2020年7月份就開始著手移除 dockershim 方案了:https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2221-remove-dockershim疾渴,現(xiàn)在的移除計劃是在 1.20 版本中將 kubelet 中內(nèi)置的 dockershim 代碼分離,將內(nèi)置的 dockershim 標(biāo)記為維護模式屯仗,當(dāng)然這個時候仍然還可以使用 dockershim搞坝,目標(biāo)是在 1.23/1.24 版本發(fā)布沒有 dockershim 的版本(代碼還在,但是要默認(rèn)支持開箱即用的 docker 需要自己構(gòu)建 kubelet魁袜,會在某個寬限期過后從 kubelet 中刪除內(nèi)置的 dockershim 代碼)桩撮。

那么這是否就意味這 Kubernetes 不再支持 Docker 了呢?當(dāng)然不是的峰弹,這只是廢棄了內(nèi)置的 dockershim 功能而已店量,Docker 和其他容器運行時將一視同仁,不會單獨對待內(nèi)置支持鞠呈,如果我們還想直接使用 Docker 這種容器運行時應(yīng)該怎么辦呢融师?可以將 dockershim 的功能單獨提取出來獨立維護一個 cri-dockerd 即可,就類似于 containerd 1.0 版本中提供的 CRI-Containerd蚁吝,當(dāng)然還有一種辦法就是 Docker 官方社區(qū)將 CRI 接口內(nèi)置到 Dockerd 中去實現(xiàn)旱爆。

但是我們也清楚 Dockerd 也是去直接調(diào)用的 Containerd,而 containerd 1.1 版本后就內(nèi)置實現(xiàn)了 CRI窘茁,所以 Docker 也沒必要再去單獨實現(xiàn) CRI 了怀伦,當(dāng) Kubernetes 不再內(nèi)置支持開箱即用的 Docker 的以后,最好的方式當(dāng)然也就是直接使用 Containerd 這種容器運行時山林,而且該容器運行時也已經(jīng)經(jīng)過了生產(chǎn)環(huán)境實踐的房待,接下來我們就來學(xué)習(xí)下 Containerd 的使用。

轉(zhuǎn)載處:https://www.qikqiak.com/k8strain2/containerd/runtime/
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末驼抹,一起剝皮案震驚了整個濱河市桑孩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌框冀,老刑警劉巖洼怔,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異左驾,居然都是意外死亡镣隶,警方通過查閱死者的電腦和手機极谊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來安岂,“玉大人轻猖,你說我怎么就攤上這事∮蚰牵” “怎么了咙边?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長次员。 經(jīng)常有香客問我败许,道長,這世上最難降的妖魔是什么淑蔚? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任市殷,我火速辦了婚禮,結(jié)果婚禮上刹衫,老公的妹妹穿的比我還像新娘醋寝。我一直安慰自己,他們只是感情好带迟,可當(dāng)我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布音羞。 她就那樣靜靜地躺著,像睡著了一般仓犬。 火紅的嫁衣襯著肌膚如雪嗅绰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天搀继,我揣著相機與錄音办陷,去河邊找鬼。 笑死律歼,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的啡专。 我是一名探鬼主播险毁,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼们童!你這毒婦竟也來了畔况?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤慧库,失蹤者是張志新(化名)和其女友劉穎跷跪,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體齐板,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡吵瞻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年葛菇,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片橡羞。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡眯停,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出卿泽,到底是詐尸還是另有隱情莺债,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布签夭,位于F島的核電站齐邦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏第租。R本人自食惡果不足惜措拇,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望煌妈。 院中可真熱鬧儡羔,春花似錦、人聲如沸璧诵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽之宿。三九已至族操,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間比被,已是汗流浹背色难。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留等缀,地道東北人枷莉。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像尺迂,于是被迫代替她去往敵國和親笤妙。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容