1. kubelet如何使用容器运行时

在早期 rkt 和 docker 争霸时,kubelet 中需要维护两坨代码分别来适配 docker 和 rkt ,这使得 kubelet 每次发布新功能都需要考虑对运行时组件的适配问题,严重拖慢了新版本发布速度。
容器运行时可能未来越来越多,如果出现新的运行时,kubelet可能还需要适配新的运行时。于是2016年,k8s提出来容器运行时接口CRI(container Runtime Interface)。CRI是对容器操作的一组抽象,只要容器运行时实现了这个接口,kubelet就能通过这个接口来适配他。不过,docker并没有实现这个接口,似乎也不打算实现这个接口,kubelet只能在内部维护一个称之为docker-shim
组件,这个组件充当了docker和CRI的转接器,kubelet在创建容器时通过CRI调用docker-shim
,而docker-shim
再通过http把请求转给docker。
注意: 现版本docker中,已经使用containerd作为底层容器运行时
所以,若改用containerd替代docker,则kubelet创建容器的调用链如红色所示。可以直接通过一次grpc
调用containerd。
通过上面可知k8s要删除docker是可以理解的一部分了。
其实这是谁胳膊粗的问题,若docker的用户多,且大家都使用,估计也不会剔除它
2. 迁移kubelet容器运行时
2.1 关闭节点服务
关闭相关服务
1 |
|
由于新版本中的docker在安装时默认使用containerd
做为后端容器运行时,故不需要再安装containerd
2.2 修改containerd的plugin
containerd中默认已经实现了cri,但是以plugin的形式。在默认安装的过程中,这个plugin一般是disable状态,需要将其开启
1 |
|
一般默认cni和stream配置即可满足kubelet运行使用
可以通过crictl info
查看,但是某些自定义的k8s安装需要配置
cni是被containerd-cri调用
1
2
3 [plugins.cri.cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"stream是kubectl exec/log等命令建立流转发通道
1
2
3
4 [plugins.cri]
stream_server_address = "127.0.0.1"
stream_server_port = "0"
enable_tls_streaming = false
1 | systemctl start containerd |
2.2 安装配置crictl客户端工具
下载工具
1 | wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.19.0/crictl-v1.19.0-linux-amd64.tar.gz |
配置
修改配置文件 /etc/crictl.yaml
1 | root@node6 lib]# cat /etc/crictl.yaml |
测试使用
1 | [root@node6 lib]# crictl pods |
2.3 修改kubelet启动参数
查看kubelet启动方式,添加启动参数
1 | --container-runtime=remote |
重启kubelet
1 | systemctl restart kubelet |
查看相关节点的CONTAINER-RUNTIME
是否已经修改
1 | [root@node1 ~]# kubectl get no -o wide |
kubelet使用docker和containerd不同的架构图

