日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
一文搞定Containerd的使用

一文搞定 Containerd 的使用

作者:k8s技術(shù)圈 2021-08-13 05:50:01

云計算 從 docker 1.11 版本開始,Docker 容器運行就不是簡單通過 Docker Daemon 來啟動了,而是通過集成 containerd、runc 等多個組件來完成的。

創(chuàng)新互聯(lián)公司堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、成都網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的德清網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

在學(xué)習(xí) Containerd 之前我們有必要對 Docker 的發(fā)展歷史做一個簡單的回顧,因為這里面牽涉到的組件實戰(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 鏡像和容器?,F(xiàn)在的架構(gòu)中組件 containerd 就會負(fù)責(zé)集群節(jié)點上容器的生命周期管理,并向上為 Docker Daemon 提供 gRPC 接口。

docker 架構(gòu)

當(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)。

cri shim

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

CRI 定義的 API(https://github.com/kubernetes/kubernetes/blob/release-1.5/pkg/kubelet/api/v1alpha1/runtime/api.proto) 主要包括兩個 gRPC 服務(wù),ImageService 和 RuntimeService,ImageService 服務(wù)主要是拉取鏡像、查看和刪除鏡像等操作,RuntimeService 則是用來管理 Pod 和容器的生命周期,以及與容器交互的調(diào)用(exec/attach/port-forward)等操作,可以通過 kubelet 中的標(biāo)志 --container-runtime-endpoint 和 --image-service-endpoint 來配置這兩個服務(wù)的套接字。

kubelet cri

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

dockershim

現(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 來。

切換到containerd

切換到 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)用就更加簡潔了。

containerd cri

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

cri-o

這個方案和 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 的使用。

Containerd

我們知道很早之前的 Docker Engine 中就有了 containerd,只不過現(xiàn)在是將 containerd 從 Docker Engine 里分離出來,作為一個獨立的開源項目,目標(biāo)是提供一個更加開放、穩(wěn)定的容器運行基礎(chǔ)設(shè)施。分離出來的 containerd 將具有更多的功能,涵蓋整個容器運行時管理的所有需求,提供更強大的支持。

containerd 是一個工業(yè)級標(biāo)準(zhǔn)的容器運行時,它強調(diào)簡單性、健壯性和可移植性,containerd 可以負(fù)責(zé)干下面這些事情:

  • 管理容器的生命周期(從創(chuàng)建容器到銷毀容器)
  • 拉取/推送容器鏡像
  • 存儲管理(管理鏡像及容器數(shù)據(jù)的存儲)
  • 調(diào)用 runc 運行容器(與 runc 等容器運行時交互)
  • 管理容器網(wǎng)絡(luò)接口及網(wǎng)絡(luò)

架構(gòu)

containerd 可用作 Linux 和 Windows 的守護程序,它管理其主機系統(tǒng)完整的容器生命周期,從鏡像傳輸和存儲到容器執(zhí)行和監(jiān)測,再到底層存儲到網(wǎng)絡(luò)附件等等。

containerd 架構(gòu)

上圖是 containerd 官方提供的架構(gòu)圖,可以看出 containerd 采用的也是 C/S 架構(gòu),服務(wù)端通過 unix domain socket 暴露低層的 gRPC API 接口出去,客戶端通過這些 API 管理節(jié)點上的容器,每個 containerd 只負(fù)責(zé)一臺機器,Pull 鏡像,對容器的操作(啟動、停止等),網(wǎng)絡(luò),存儲都是由 containerd 完成。具體運行容器由 runc 負(fù)責(zé),實際上只要是符合 OCI 規(guī)范的容器都可以支持。

為了解耦,containerd 將系統(tǒng)劃分成了不同的組件,每個組件都由一個或多個模塊協(xié)作完成(Core 部分),每一種類型的模塊都以插件的形式集成到 Containerd 中,而且插件之間是相互依賴的,例如,上圖中的每一個長虛線的方框都表示一種類型的插件,包括 Service Plugin、Metadata Plugin、GC Plugin、Runtime Plugin 等,其中 Service Plugin 又會依賴 Metadata Plugin、GC Plugin 和 Runtime Plugin。每一個小方框都表示一個細(xì)分的插件,例如 Metadata Plugin 依賴 Containers Plugin、Content Plugin 等。比如:

  • Content Plugin: 提供對鏡像中可尋址內(nèi)容的訪問,所有不可變的內(nèi)容都被存儲在這里。
  • Snapshot Plugin: 用來管理容器鏡像的文件系統(tǒng)快照,鏡像中的每一層都會被解壓成文件系統(tǒng)快照,類似于 Docker 中的 graphdriver。

總體來看 containerd 可以分為三個大塊:Storage、Metadata 和 Runtime。

containerd 架構(gòu)2

安裝

這里我使用的系統(tǒng)是 Linux Mint 20.2,首先需要安裝 seccomp 依賴:

  
 
 
 
  1.   ~ apt-get update
  2.   ~ apt-get install libseccomp2 -y

由于 containerd 需要調(diào)用 runc,所以我們也需要先安裝 runc,不過 containerd 提供了一個包含相關(guān)依賴的壓縮包 cri-containerd-cni-${VERSION}.${OS}-${ARCH}.tar.gz,可以直接使用這個包來進行安裝。首先從 release 頁面下載最新版本的壓縮包,當(dāng)前為 1.5.5 版本:

  
 
 
 
  1.   ~ wget https://github.com/containerd/containerd/releases/download/v1.5.5/cri-containerd-cni-1.5.5-linux-amd64.tar.gz
  2. # 如果有限制,也可以替換成下面的 URL 加速下載
  3. # wget https://download.fastgit.org/containerd/containerd/releases/download/v1.5.5/cri-containerd-cni-1.5.5-linux-amd64.tar.gz

可以通過 tar 的 -t 選項直接看到壓縮包中包含哪些文件:

  
 
 
 
  1.   ~ tar -tf cri-containerd-cni-1.4.3-linux-amd64.tar.gz
  2. etc/
  3. etc/cni/
  4. etc/cni/net.d/
  5. etc/cni/net.d/10-containerd-net.conflist
  6. etc/crictl.yaml
  7. etc/systemd/
  8. etc/systemd/system/
  9. etc/systemd/system/containerd.service
  10. usr/
  11. usr/local/
  12. usr/local/bin/
  13. usr/local/bin/containerd-shim-runc-v2
  14. usr/local/bin/ctr
  15. usr/local/bin/containerd-shim
  16. usr/local/bin/containerd-shim-runc-v1
  17. usr/local/bin/crictl
  18. usr/local/bin/critest
  19. usr/local/bin/containerd
  20. usr/local/sbin/
  21. usr/local/sbin/runc
  22. opt/
  23. opt/cni/
  24. opt/cni/bin/
  25. opt/cni/bin/vlan
  26. opt/cni/bin/host-local
  27. opt/cni/bin/flannel
  28. opt/cni/bin/bridge
  29. opt/cni/bin/host-device
  30. opt/cni/bin/tuning
  31. opt/cni/bin/firewall
  32. opt/cni/bin/bandwidth
  33. opt/cni/bin/ipvlan
  34. opt/cni/bin/sbr
  35. opt/cni/bin/dhcp
  36. opt/cni/bin/portmap
  37. opt/cni/bin/ptp
  38. opt/cni/bin/static
  39. opt/cni/bin/macvlan
  40. opt/cni/bin/loopback
  41. opt/containerd/
  42. opt/containerd/cluster/
  43. opt/containerd/cluster/version
  44. opt/containerd/cluster/gce/
  45. opt/containerd/cluster/gce/cni.template
  46. opt/containerd/cluster/gce/configure.sh
  47. opt/containerd/cluster/gce/cloud-init/
  48. opt/containerd/cluster/gce/cloud-init/master.yaml
  49. opt/containerd/cluster/gce/cloud-init/node.yaml
  50. opt/containerd/cluster/gce/env

直接將壓縮包解壓到系統(tǒng)的各個目錄中:

  
 
 
 
  1.   ~ tar -C / -xzf cri-containerd-cni-1.5.5-linux-amd64.tar.gz

當(dāng)然要記得將 /usr/local/bin 和 /usr/local/sbin 追加到 ~/.bashrc 文件的 PATH 環(huán)境變量中:

  
 
 
 
  1. export PATH=$PATH:/usr/local/bin:/usr/local/sbin

然后執(zhí)行下面的命令使其立即生效:

  
 
 
 
  1.   ~ source ~/.bashrc

containerd 的默認(rèn)配置文件為 /etc/containerd/config.toml,我們可以通過如下所示的命令生成一個默認(rèn)的配置:

  
 
 
 
  1.   ~ mkdir /etc/containerd
  2.   ~ containerd config default > /etc/containerd/config.toml

由于上面我們下載的 containerd 壓縮包中包含一個 etc/systemd/system/containerd.service 的文件,這樣我們就可以通過 systemd 來配置 containerd 作為守護進程運行了,內(nèi)容如下所示:

  
 
 
 
  1.   ~ cat /etc/systemd/system/containerd.service
  2. [Unit]
  3. Description=containerd container runtime
  4. Documentation=https://containerd.io
  5. After=network.target local-fs.target
  6. [Service]
  7. ExecStartPre=-/sbin/modprobe overlay
  8. ExecStart=/usr/local/bin/containerd
  9. Type=notify
  10. Delegate=yes
  11. KillMode=process
  12. Restart=always
  13. RestartSec=5
  14. # Having non-zero Limit*s causes performance problems due to accounting overhead
  15. # in the kernel. We recommend using cgroups to do container-local accounting.
  16. LimitNPROC=infinity
  17. LimitCORE=infinity
  18. LimitNOFILE=1048576
  19. # Comment TasksMax if your systemd version does not supports it.
  20. # Only systemd 226 and above support this version.
  21. TasksMax=infinity
  22. OOMScoreAdjust=-999
  23. [Install]
  24. WantedBy=multi-user.target

這里有兩個重要的參數(shù):

Delegate: 這個選項允許 containerd 以及運行時自己管理自己創(chuàng)建容器的 cgroups。如果不設(shè)置這個選項,systemd 就會將進程移到自己的 cgroups 中,從而導(dǎo)致 containerd 無法正確獲取容器的資源使用情況。

KillMode: 這個選項用來處理 containerd 進程被殺死的方式。默認(rèn)情況下,systemd 會在進程的 cgroup 中查找并殺死 containerd 的所有子進程。KillMode 字段可以設(shè)置的值如下。

  • control-group(默認(rèn)值):當(dāng)前控制組里面的所有子進程,都會被殺掉
  • process:只殺主進程
  • mixed:主進程將收到 SIGTERM 信號,子進程收到 SIGKILL 信號
  • none:沒有進程會被殺掉,只是執(zhí)行服務(wù)的 stop 命令

我們需要將 KillMode 的值設(shè)置為 process,這樣可以確保升級或重啟 containerd 時不殺死現(xiàn)有的容器。

現(xiàn)在我們就可以啟動 containerd 了,直接執(zhí)行下面的命令即可:

  
 
 
 
  1.   ~ systemctl enable containerd --now

啟動完成后就可以使用 containerd 的本地 CLI 工具 ctr 了,比如查看版本:

ctr version

配置

我們首先來查看下上面默認(rèn)生成的配置文件 /etc/containerd/config.toml:

  
 
 
 
  1. disabled_plugins = []
  2. imports = []
  3. oom_score = 0
  4. plugin_dir = ""
  5. required_plugins = []
  6. root = "/var/lib/containerd"
  7. state = "/run/containerd"
  8. version = 2
  9. [cgroup]
  10.   path = ""
  11. [debug]
  12.   address = ""
  13.   format = ""
  14.   gid = 0
  15.   level = ""
  16.   uid = 0
  17. [grpc]
  18.   address = "/run/containerd/containerd.sock"
  19.   gid = 0
  20.   max_recv_message_size = 16777216
  21.   max_send_message_size = 16777216
  22.   tcp_address = ""
  23.   tcp_tls_cert = ""
  24.   tcp_tls_key = ""
  25.   uid = 0
  26. [metrics]
  27.   address = ""
  28.   grpc_histogram = false
  29. [plugins]
  30.   [plugins."io.containerd.gc.v1.scheduler"]
  31.     deletion_threshold = 0
  32.     mutation_threshold = 100
  33.     pause_threshold = 0.02
  34.     schedule_delay = "0s"
  35.     startup_delay = "100ms"
  36.   [plugins."io.containerd.grpc.v1.cri"]
  37.     disable_apparmor = false
  38.     disable_cgroup = false
  39.     disable_hugetlb_controller = true
  40.     disable_proc_mount = false
  41.     disable_tcp_service = true
  42.     enable_selinux = false
  43.     enable_tls_streaming = false
  44.     ignore_image_defined_volumes = false
  45.     max_concurrent_downloads = 3
  46.     max_container_log_line_size = 16384
  47.     netns_mounts_under_state_dir = false
  48.     restrict_oom_score_adj = false
  49.     sandbox_image = "k8s.gcr.io/pause:3.5"
  50.     selinux_category_range = 1024
  51.     stats_collect_period = 10
  52.     stream_idle_timeout = "4h0m0s"
  53.     stream_server_address = "127.0.0.1"
  54.     stream_server_port = "0"
  55.     systemd_cgroup = false
  56.     tolerate_missing_hugetlb_controller = true
  57.     unset_seccomp_profile = ""
  58.     [plugins."io.containerd.grpc.v1.cri".cni]
  59.       bin_dir = "/opt/cni/bin"
  60.       conf_dir = "/etc/cni/net.d"
  61.       conf_template = ""
  62.       max_conf_num = 1
  63.     [plugins."io.containerd.grpc.v1.cri".containerd]
  64.       default_runtime_name = "runc"
  65.       disable_snapshot_annotations = true
  66.       discard_unpacked_layers = false
  67.       no_pivot = false
  68.       snapshotter = "overlayfs"
  69.       [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
  70.         base_runtime_spec = ""
  71.         container_annotations = []
  72.         pod_annotations = []
  73.         privileged_without_host_devices = false
  74.         runtime_engine = ""
  75.         runtime_root = ""
  76.         runtime_type = ""
  77.         [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options]
  78.       [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
  79.         [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  80.           base_runtime_spec = ""
  81.           container_annotations = []
  82.           pod_annotations = []
  83.           privileged_without_host_devices = false
  84.           runtime_engine = ""
  85.           runtime_root = ""
  86.           runtime_type = "io.containerd.runc.v2"
  87.           [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
  88.             BinaryName = ""
  89.             CriuImagePath = ""
  90.             CriuPath = ""
  91.             CriuWorkPath = ""
  92.             IoGid = 0
  93.             IoUid = 0
  94.             NoNewKeyring = false
  95.             NoPivotRoot = false
  96.             Root = ""
  97.             ShimCgroup = ""
  98.             SystemdCgroup = false
  99.       [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]
  100.         base_runtime_spec = ""
  101.         container_annotations = []
  102.         pod_annotations = []
  103.         privileged_without_host_devices = false
  104.         runtime_engine = ""
  105.         runtime_root = ""
  106.         runtime_type = ""
  107.         [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options]
  108.     [plugins."io.containerd.grpc.v1.cri".image_decryption]
  109.       key_model = "node"
  110.     [plugins."io.containerd.grpc.v1.cri".registry]
  111.       config_path = ""
  112.       [plugins."io.containerd.grpc.v1.cri".registry.auths]
  113.       [plugins."io.containerd.grpc.v1.cri".registry.configs]
  114.       [plugins."io.containerd.grpc.v1.cri".registry.headers]
  115.       [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
  116.     [plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
  117.       tls_cert_file = ""
  118.       tls_key_file = ""
  119.   [plugins."io.containerd.internal.v1.opt"]
  120.     path = "/opt/containerd"
  121.   [plugins."io.containerd.internal.v1.restart"]
  122.     interval = "10s"
  123.   [plugins."io.containerd.metadata.v1.bolt"]
  124.     content_sharing_policy = "shared"
  125.   [plugins."io.containerd.monitor.v1.cgroups"]
  126.     no_prometheus = false
  127.   [plugins."io.containerd.runtime.v1.linux"]
  128.     no_shim = false
  129.     runtime = "runc"
  130.     runtime_root = ""
  131.     shim = "containerd-shim"
  132.     shim_debug = false
  133.   [plugins."io.containerd.runtime.v2.task"]
  134.     platforms = ["linux/amd64"]
  135.   [plugins."io.containerd.service.v1.diff-service"]
  136.     default = ["walking"]
  137.   [plugins."io.containerd.snapshotter.v1.aufs"]
  138.     root_path = ""
  139.   [plugins."io.containerd.snapshotter.v1.btrfs"]
  140.     root_path = ""
  141.   [plugins."io.containerd.snapshotter.v1.devmapper"]
  142.     async_remove = false
  143.     base_image_size = ""
  144.     pool_name = ""
  145.     root_path = ""
  146.   [plugins."io.containerd.snapshotter.v1.native"]
  147.     root_path = ""
  148.   [plugins."io.containerd.snapshotter.v1.overlayfs"]
  149.     root_path = ""
  150.   [plugins."io.containerd.snapshotter.v1.zfs"]
  151.     root_path = ""
  152. [proxy_plugins]
  153. [stream_processors]
  154.   [stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]
  155.     accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]
  156.     args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
  157.     env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
  158.     path = "ctd-decoder"
  159.     returns = "application/vnd.oci.image.layer.v1.tar"
  160.   [stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]
  161.     accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]
  162.     args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
  163.     env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
  164.     path = "ctd-decoder"
  165.     returns = "application/vnd.oci.image.layer.v1.tar+gzip"
  166. [timeouts]
  167.   "io.containerd.timeout.shim.cleanup" = "5s"
  168.   "io.containerd.timeout.shim.load" = "5s"
  169.   "io.containerd.timeout.shim.shutdown" = "3s"
  170.   "io.containerd.timeout.task.state" = "2s"
  171. [ttrpc]
  172.   address = ""
  173.   gid = 0
  174.   uid = 0

這個配置文件比較復(fù)雜,我們可以將重點放在其中的 plugins 配置上面,仔細(xì)觀察我們可以發(fā)現(xiàn)每一個頂級配置塊的命名都是 plugins."io.containerd.xxx.vx.xxx" 這種形式,每一個頂級配置塊都表示一個插件,其中 io.containerd.xxx.vx 表示插件的類型,vx 后面的 xxx 表示插件的 ID,我們可以通過 ctr 查看插件列表:

  
 
 
 
  1.   ~ ctr plugin ls
  2. ctr plugin ls
  3. TYPE                            ID                       PLATFORMS      STATUS
  4. io.containerd.content.v1        content                  -              ok
  5. io.containerd.snapshotter.v1    aufs                     linux/amd64    ok
  6. io.containerd.snapshotter.v1    btrfs                    linux/amd64    skip
  7. io.containerd.snapshotter.v1    devmapper                linux/amd64    error
  8. io.containerd.snapshotter.v1    native                   linux/amd64    ok
  9. io.containerd.snapshotter.v1    overlayfs                linux/amd64    ok
  10. io.containerd.snapshotter.v1    zfs                      linux/amd64    skip
  11. io.containerd.metadata.v1       bolt                     -              ok
  12. io.containerd.differ.v1         walking                  linux/amd64    ok
  13. io.containerd.gc.v1             scheduler                -              ok
  14. io.containerd.service.v1        introspection-service    -              ok
  15. io.containerd.service.v1        containers-service       -              ok
  16. io.containerd.service.v1        content-service          -              ok
  17. io.containerd.service.v1        diff-service             -              ok
  18. io.containerd.service.v1        images-service           -              ok
  19. io.containerd.service.v1        leases-service           -              ok
  20. io.containerd.service.v1        namespaces-service       -              ok
  21. io.containerd.service.v1        snapshots-service        -              ok
  22. io.containerd.runtime.v1        linux                    linux/amd64    ok
  23. io.containerd.runtime.v2        task                     linux/amd64    ok
  24. io.containerd.monitor.v1        cgroups                  linux/amd64    ok
  25. io.containerd.service.v1        tasks-service            -              ok
  26. io.containerd.internal.v1       restart                  -              ok
  27. io.containerd.grpc.v1           containers               -              ok
  28. io.containerd.grpc.v1           content                  -              ok
  29. io.containerd.grpc.v1           diff                     -              ok
  30. io.containerd.grpc.v1           events                   -              ok
  31. io.containerd.grpc.v1           healthcheck              -              ok
  32. io.containerd.grpc.v1           images                   -              ok
  33. io.containerd.grpc.v1           leases                   -              ok
  34. io.containerd.grpc.v1           namespaces               -              ok
  35. io.containerd.internal.v1       opt                      -              ok
  36. io.containerd.grpc.v1           snapshots                -              ok
  37. io.containerd.grpc.v1           tasks                    -              ok
  38. io.containerd.grpc.v1           version                  -              ok
  39. io.containerd.grpc.v1           cri                      linux/amd64    ok

頂級配置塊下面的子配置塊表示該插件的各種配置,比如 cri 插件下面就分為 containerd、cni 和 registry 的配置,而 containerd 下面又可以配置各種 runtime,還可以配置默認(rèn)的 runtime。比如現(xiàn)在我們要為鏡像配置一個加速器,那么就需要在 cri 配置塊下面的 registry 配置塊下面進行配置 registry.mirrors:

  
 
 
 
  1. [plugins."io.containerd.grpc.v1.cri".registry]
  2.   [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
  3.     [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
  4.       endpoint = ["https://bqr1dr1n.mirror.aliyuncs.com"]
  5.     [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
  6.       endpoint = ["https://registry.aliyuncs.com/k8sxio"]
  • registry.mirrors."xxx": 表示需要配置 mirror 的鏡像倉庫,例如 registry.mirrors."docker.io" 表示配置 docker.io 的 mirror。
  • endpoint: 表示提供 mirror 的鏡像加速服務(wù),比如我們可以注冊一個阿里云的鏡像服務(wù)來作為 docker.io 的 mirror。

另外在默認(rèn)配置中還有兩個關(guān)于存儲的配置路徑:

  
 
 
 
  1. root = "/var/lib/containerd"
  2. state = "/run/containerd"

其中 root 是用來保存持久化數(shù)據(jù),包括 Snapshots, Content, Metadata 以及各種插件的數(shù)據(jù),每一個插件都有自己單獨的目錄,Containerd 本身不存儲任何數(shù)據(jù),它的所有功能都來自于已加載的插件。

而另外的 state 是用來保存運行時的臨時數(shù)據(jù)的,包括 sockets、pid、掛載點、運行時狀態(tài)以及不需要持久化的插件數(shù)據(jù)。

使用

我們知道 Docker CLI 工具提供了需要增強用戶體驗的功能,containerd 同樣也提供一個對應(yīng)的 CLI 工具:ctr,不過 ctr 的功能沒有 docker 完善,但是關(guān)于鏡像和容器的基本功能都是有的。接下來我們就先簡單介紹下 ctr 的使用。

幫助

直接輸入 ctr 命令即可獲得所有相關(guān)的操作命令使用方式:

  
 
 
 
  1.   ~ ctr
  2. NAME:
  3.    ctr -
  4.         __
  5.   _____/ /______
  6.  / ___/ __/ ___/
  7. / /__/ /_/ /
  8. \___/\__/_/
  9. containerd CLI
  10. USAGE:
  11.    ctr [global options] command [command options] [arguments...]
  12. VERSION:
  13.    v1.5.5
  14. DESCRIPTION:
  15. ctr is an unsupported debug and administrative client for interacting
  16. with the containerd daemon. Because it is unsupported, the commands,
  17. options, and operations are not guaranteed to be backward compatible or
  18. stable from release to release of the containerd project.
  19. COMMANDS:
  20.    plugins, plugin            provides information about containerd plugins
  21.    version                    print the client and server versions
  22.    containers, c, container   manage containers
  23.    content                    manage content
  24.    events, event              display containerd events
  25.    images, image, i           manage images
  26. 文章標(biāo)題:一文搞定Containerd的使用
    轉(zhuǎn)載源于:http://www.dlmjj.cn/article/dhepcee.html