如何选择运行时组件?
容器运行时组件(Container Runtime)是 Kubernetes 的核心组件之一,负责管理镜像和容器的生命周期。  通过平台创建集群时,支持选择 Containerd 或 Docker(Kubernetes 版本小于 1.24)作为运行时组件。
说明:出于组件间依赖关系及平台架构的考虑,目前,平台自建集群支持的 Kubernetes 版本和容器运行时组件的类型及版本对应关系参见 集群组件版本要求 ,本文档仅介绍 Containerd 和 Docker 的区别,供您参考。
快速选型
| 选择 Containerd | 选择 Docker | 
|---|---|
| 调用链更短、组件更少、更稳定、占用节点资源更少 | 可使用 docker in docker; 可在节点上使用 docker build/push/save/load等命令;可调用 docker API; 可使用 docker compose 或 docker swarm。 | 
Docker、Containerd 组件区别
组件常用命令
| Containerd | Docker | 说明 | 
|---|---|---|
| crictl ps | docker ps | 查看运行的容器 | 
| crictl inspect | docker inspect | 查看容器详情 | 
| crictl logs | docker logs | 查看容器日志 | 
| crictl exec | docker exec | 容器内执行命令 | 
| crictl attach | docker attach | 挂载容器 | 
| crictl stats | docker stats | 显示容器资源使用情况 | 
| crictl create | docker create | 创建容器 | 
| crictl start | docker start | 启动容器 | 
| crictl stop | docker stop | 停止容器 | 
| crictl rm | docker rm | 删除容器 | 
| crictl images | docker images | 查看镜像列表 | 
| crictl pull | docker pull | 拉取镜像 | 
| 无 | docker push | 推送镜像 | 
| crictl rmi | docker rmi | 删除镜像 | 
| crictl pods | 无 | 查看 pod 列表 | 
| crictl inspectp | 无 | 查看 pod 详情 | 
| crictl runp | 无 | 启动 pod | 
| crictl stopp | docker images | 查看镜像 | 
| ctr images ls | 无 | 停止 pod | 
| crictl stopp | docker load/save | 镜像导入/导出 | 
| ctr images import/exporter | 无 | 停止 pod | 
| ctr images pull/push | docker pull/push | 镜像拉取/推送 | 
| ctr images tag | docker tag | 镜像tag | 
调用链区别
- 
Docker 作为 kubernetes 容器运行时,调用关系如下: kubelet > docker shim (在 kubelet 进程中) > dockerd > containerd > runC   
- 
Containerd 作为 Kubernetes 容器运行时,调用关系如下: kubelet > cri plugin(在 containerd 进程中) > containerd > runC   
总结:其中 dockerd 虽增加了swarm cluster、docker build、docker API等功能,但也会引入一些 bug,而与 containerd 相比,多了一层调用。Containerd 调用链更短,组件更少,更稳定,占用节点资源更少。
日志及相关参数对比
| 对比项 | Docker | Containerd | 
|---|---|---|
| 存储路径 | 如果 Docker 作为 Kubernetes 容器运行时,容器日志的落盘将由 docker 来完成,保存在类似 /var/lib/docker/containers/$CONTAINERID目录下。Kubelet 会在/var/log/pods和/var/log/containers下面建立软链接,指向/var/lib/docker/containers/$CONTAINERID该目录下的容器日志文件。 | 如果 Containerd 作为 Kubernetes 容器运行时, 容器日志的落盘由 Kubelet 来完成,保存至 /var/log/pods/$CONTAINER_NAME目录下,同时在/var/log/containers目录下创建软链接,指向日志文件。 | 
| 配置参数 | 在 docker 配置文件中指定: "log-driver": "json-file","log-opts": {"max-size": "100m","max-file": "5"} | *   方法一:在 kubelet 参数中指定: --container-log-max-files=5  <br>    --container-log-max-size="100Mi"* 方法二:在 KubeletConfiguration 中指定: "containerLogMaxSize": "100Mi","containerLogMaxFiles": 5, | 
| 把容器日志保存到数据盘 | 把数据盘挂载到 “data-root”(缺省是 /var/lib/docker)即可。 | 创建一个软链接 /var/log/pods指向数据盘挂载点下的某个目录。 | 
CNI 网络对比
| 对比项 | Docker | Containerd | 
|---|---|---|
| 谁负责调用 CNI | Kubelet 内部的 docker-shim | Containerd 内置的 cri-plugin(containerd 1.1 以后) | 
| 如何配置 CNI | Kubelet 参数 --cni-bin-dir和--cni-conf-dir | Containerd 配置文件(toml): [plugins.cri.cni]bin_dir = "/opt/cni/bin"conf_dir = "/etc/cni/net.d" |