微信公众号:运维开发故事,作者:华仔
最近公司打算在新的产品中不再使用docker,而是使用containerd作为运行时。至于原因嘛,没有直接告诉我们。于是,我就打算自己去了解一番;并与docker做个对比,看看两者的差异。
docker相信大家已经非常熟悉了,我就不介绍了。这里来介绍一下containerd。github上针对containerd的介绍如下:
containerd is an industry-standard container runtime with an emphasis on simplicity, robustness and portability.
It is available as a daemon for Linux and Windows,
which can manage the complete container lifecycle of its host system: image transfer and storage,
container execution and supervision, low-level storage and network attachments, etc.
大致意思就是说Containerd是一个强调简单性、健壮性和可移植性的行业标准容器运行时。可以在windows和linux上使用,能够管理宿主机上容器整个生命周期,包括镜像传输、容器创建和管理,低级别的存储和网络附件等等。其架构如下:
![image.png](https://img-blog.csdnimg.cn/img_convert/e532a971f386cbbe065c012ee1d219aa.png#clientId=uf135d509-6e76-4&from=paste&height=575&id=u4b15ffec&margin=[object Object]&name=image.png&originHeight=1149&originWidth=2004&originalType=binary&ratio=1&size=134095&status=done&style=none&taskId=u7d25e136-7228-4abc-b05c-8320f67500c&width=1002)
使用过docker的朋友肯定对docker很熟悉了。这里就只说一下containerd的功能。containerd的功能如下:
接下来,对docker和containerd进行一个多方面的比较。看看两者究竟有哪些缺别,也帮助大家以后进行选择合适的去用。
在使用k8s时,使用docker和containerd的调用链如下所示:
![image.png](https://img-blog.csdnimg.cn/img_convert/6448b20d027b76e1e48c51ef19291d78.png#clientId=uf135d509-6e76-4&from=paste&height=185&id=u47fd8d21&margin=[object Object]&name=image.png&originHeight=370&originWidth=1258&originalType=binary&ratio=1&size=186211&status=done&style=none&taskId=u3a2a1123-5ba1-494a-86fb-e70a68c561d&width=629)
不难看出,使用containerd时,调用链更短,不再需要经过dockershim和docker
相信大家都知道docker的数据目录默认是在/var/lib/docker目录下;而切换到containerd时,数据目录默认为/var/lib/containerd
当我们在使用k8s时,如果使用了docker作为运行时,其实容器程序日志的落盘是由docker来负责的。/var/log/pod和/var/log/container下的日志文件会软连接到/var/lib/docker下对应的日志文件,如果还需要对日志做一些参数配置,直接修改docker配置文件即可;而如果我们现在使用containerd作为运行时,则容器日志的落盘将由kubelet来负责,/var/log/container下的日志文件会软连接到/var/log/pod下的日志文件,如果需要调整日志参数,则需要修改kubelet相关配置
当使用docker作为运行时时,kubelet中的docker-shim负责调用cni;而当使用containerd作为运行时时,containerd中内置的containerd-cri负责调用cni
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"
熟悉k8s的朋友都知道,kubectl exec 和 kubelet log等命令需要通过apiserver与容器通信,这其中就涉及到了流服务。而docker API本身支持,kubelet中的docker-shim通过docker API流转发;但containerd却要对此进行单独配置
[plugins."io.containerd.grpc.v1.cri"]
stream_idle_timeout = "4h0m0s"
stream_server_address = "127.0.0.1"
stream_server_port = "0"
enable_tls_streaming = false
使用containerd作为运行时后,常用的命令也变了。下面举两个例子。另外,使用containerd时,可以安装nerdctl工具配合containerd的namespace来一起使用,这样就跟使用docker命令一样了
Container runtime | 列出容器 | 列出镜像 |
---|---|---|
docker | docker ps -a | docker images |
containerd | ctr c list/ctr task list | ctr images list |
containerd引入了namespace。名称空间允许多个使用者使用同一容器,彼此之间不会发生冲突。它的优点是可以共享内容,但仍然与容器和镜像分离。所以,在使用containerd相关命令时,需要添加-n namespace参数。
Namespaces allow multiple consumers to use the same containerd without conflicting with each other.
It has the benefit of sharing content but still having separation with containers and images.
总体来看,containerd与docker还是有很多不同之处,但最终要实现的效果都一致。至于我们在使用k8s过程中,具体使用哪一种作为运行时,还是根据实际情况选择。