NVIDIA GPU 支援Containerd 小結
背景介紹
Kubernetes 要在1.20的changelog中提到,會廢棄對Docker的支援,引起大家廣泛關注

随後社群專門發了篇
部落格和
FAQ解釋這件事情 和 , 簡單說是docker出色的地方在于human-friendly的UX和易用性,而這部分對于kubernetes來說并不關心,相反kubelet 通過CRI 和運作時互動,而docker不支援标準CRI,于是kubelet維護了了一個dockerShim 用于相容docker互動,這種模式随着kubernetes疊代,給維護者帶來了沉重負擔。
而docker廢棄以後的替代者,社群建議可以用cri-o 或者containerd。 如果以前使用的docker,建議用containerd。
想要弄明白docker去掉後有什麼差別,需要弄清楚幾個概念,什麼是CRI,OCI, 還有Runc,containerd分别是什麼, 以及他們和Docker之間的關系。
- OCI 是Open Container Initiative, 由 Linux Foundation 主導的,定義了容器鏡像格式和運作時的工業标準(Define industry standards around container image formats and runtimes)
- CRI 是Container Runtime Interface, 是由 Kubernetes 對運作時的需求抽象出的接口,不同的容器運作時(kata,gvisor)想要對接kubernetes,可以通過GRPC的方式提供CRI相關接口實作 https://kubernetes.io/blog/2016/12/container-runtime-interface-cri-in-kubernetes/
- RunC 是Docker 将容器運作時層面抽取出來的OCI實作。
- Containerd 是Docker 中對容器管理的守護程序,于2019年在CNCF 孵化中畢業。 雖然Docker不支援CRI實作,但是Containerd 提供了豐富的插件擴充機制,可以通過 containerd-cri 插件 提供CRI 接口支援。
- DockerShim 是kubelet中的一個墊片子產品,由于Docker 不支援CRI, kubelet中為了Docker這種特殊類型的運作時維護一個 獨立子產品 相容。
事實上,Kubernetes 早在18年就将支援Containerd 的架構正式GA。
https://kubernetes.io/blog/2018/05/24/kubernetes-containerd-integration-goes-ga/使用Containerd 後,使用者依然可以在自己的筆記本上借助Docker 友好的UX 建構和管理鏡像。 在生産環境中則由Containerd替代Docker 管理容器程序,當需要在主控端上做容器trouble shooting時,也可以用crictl 工具。
Kubelet 通過DockerShim 支援Docker :
Kubelet 直接調用Containerd:
Containerd 介紹
containerd 是一個工業級的容器運作時管理工具,可以幫助管理容器的完整生命周期,鏡像傳輸存儲,容器底層存儲和網絡配置。 它最上層通過GRPC子產品暴露接口,内部分為不同子產品,每個子產品以插件的形式注冊到containerd中。
CRI也是通過插件的方式在Containerd中支援,CRI插件通過GRPC調用Containerd中各個子產品,完成容器的生命周期管理适配。可以在
cri 插件看到相關代碼。
Containerd中會為每個管理的容器程序啟動containerd-shim 程序, shim程序可以幫助守護容器程序,并提供GRPC接口讓containerd 于容器互動。 通過contaienrd-shim可以将容器程序和daemon 程序的生命周期解耦。
在containerd 早期shim v1 的模型裡,會給每個container配置設定一個shim程序。
Containerd-shim V2
早期shim不支援擴充,類似kata這樣的安全沙箱容器适配非常複雜,而且當有實體sandbox後,由于container運作在sandbox中,不需要在主控端上為每個容器配置設定獨立的shim程序,于是在2018年社群主導的shim v2出現 可以參考張磊的采訪:
https://www.infoq.cn/article/r*ikovovthhadaww1hb1。 通過shim v2,其他運作時可以通過containerd提供的腳手架搭建自己的shim 實作,例如
kata的containerd shim v2,并且containerd在runc-shim-v2中也實作了一個sandbox内container 複用shim ,
可以檢視代碼。
containerd-shim-v1 中kata的适配:
containerd-shim-v2 中kata的适配:
Containerd 支援Nvidia GPU
在
之前的文章中介紹過docker中如何使用GPU,當從docker 切換到containerd後,也需要在containerd中适配nvidia-container 。
适配
containerd中的配置檔案都在
/etc/containerd/config.toml
檔案中,我們可以在config.toml中修改runtime插件的配置,首先切換到runtime v2。
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
将CRI配置中的runc binary改為
nvidia-container-runtime
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
BinaryName = "nvidia-container-runtime"
驗證
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: cuda-vector-add
spec:
restartPolicy: OnFailure
containers:
- name: cuda-vector-add
image: "registry.cn-hangzhou.aliyuncs.com/cuda-vector-add/cuda:v0.1"
resources:
limits:
nvidia.com/gpu: 1
EOF