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