前 言
Docker是我们常用的容器runtime,友好的CLI,丰富的社区资料,外加研发运维人员多年的经验积累,使用Docker几乎是没有任何门槛的事。而k3s为了降低资源消耗,将默认的runtime修改为containerd,虽然containerd很早就已经是Docker的一部分,但是纯粹使用containerd还是给大家带来了诸多困扰。本文收集了一些社区常见的containerd问题,寻求到解决方案后整理成文,供大家需要时查阅。
入门简介
我们都知道Kubernetes定义了自己运行时接口规范CRI,containerd虽然具备容器管理能力,但是不能被直接被Kubernetes使用。k3s作为Kubernetes的精简版本,也是如此,k3s自身的kubelet通过cri-containerd plugin(https://github.com/containerd/cri)来驱动containerd创建Pod。
单纯的Containerd没有Docker CLI,对于经常使用Docker的用户来说,一下就会感到不习惯。根据CRI规范,Kubernetes社区也定义了专门CLI工具crictl(https://github.com/kubernetes-sigs/cri-tools)。k3s中也内置了crictl,它被直接编译到k3s binary中,你在安装k3s时,会自动创建crictl的软连接。crictl具备了和Docker CLI类似的功能:
除了crictl,k3s还内置了ctr(https://github.com/containerd/containerd/tree/master/cmd/ctr),ctr是containerd本身的CLI,更对容器和镜像API的基本封装:
目前k3s的containerd使用的runc-v2版本,这个版本有个巨大的优化就是针对每个Pod创建containerd-shim进程。以Traefik Pod为例,pause容器和traefik容器都是containerd-shim的子进程,这种进程划分方式更加合理,对Kubernetes更加友好。
常用技巧
containerd相关的CLI确实没有Docker CLI方便,比如笔者在使用containerd时碰到一个场景,期望实现对镜像重新tag的操作,这在Docker下非常容易做到,但是在containerd下非常麻烦。crictl中并不支持这种操作,社区中也有相关issue解释:
https://github.com/kubernetes-sigs/cri-tools/issues/438
所以我们只能使用其他方式,通常我会这样做:
# 在一台机去上使用docker tag转换image
# 导出镜像,并拷贝到k3s机器上
docker tag busybox busyboxaaa
docker save -o busybox.tar busyboxaaa
scp busybox.tar ubuntu@172.31.24.12:~/
# 用ctr导入
ctr image import busybox.tar
k3s集成的containerd的配置文件被存放在 /var/lib/rancher/k3s/agent/etc/containerd/config.toml 中,但是如果要修改其配置不能单纯修改它,你需要通过模版修改它:
cd /var/lib/rancher/k3s/agent/etc/containerd
cp config.toml config.toml.tmpl
# update config.toml.tmpl
# reboot k3s to take affect
systemctl restart k3s
通常来说,我们都会在本地环境使用k3s,使用私有Registry也是不可避免的,Docker中配置私有registry是非常方便的,而在containerd中该如何配置?关于containerd的registry配置请参考:
https://github.com/containerd/cri/blob/master/docs/registry.md
值得一提的是一个特殊场景,通常你会在内网在用registry镜像启用一个镜像仓库服务,为了简单方便,你可以不启用tls证书而单纯使用http模式。这种情况下,k3s有一个方便的配置方式,即编辑/etc/rancher/k3s/registries.yaml,比如:
$ cat /etc/rancher/k3s/registries.yaml
mirrors:
"172.31.7.129:5000":
endpoint:
- "http://172.31.7.129:5000”
$ systemctl restart k3s
重启后,containerd的配置会出现变化,直接使用crictl命令即可拉取镜像:
后 记
从业界的技术发展趋势上看,Docker越来越被Kubernetes社区所抛弃,以实现CRI接口的各种容器runtime会与Kubernetes兼容性越发友好。Docker本身的迭代速度已经无法满足容器的发展,k3s直接使用containerd可以很快跟踪各种容器技术本身的新特性,对技术人员来说,尽早适应Docker以外的runtime,才能跟上社区主流的前进方向。