引言
最近公司打算在新的产品中不再使用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上使用,能够管理宿主机上容器整个生命周期,包括镜像传输、容器创建和管理,低级别的存储和网络附件等等。其架构如下:
功能
使用过docker的朋友肯定对docker很熟悉了。这里就只说一下containerd的功能。containerd的功能如下:
- 支持 OCI 的镜像标准
- OCI 的容器运行时
- 镜像的推送和拉取
- 容器运行时生命周期管理
- 多租户的镜像存储
- 网络管理以及网络 namespace 管理,支持容器网络加入已有的 namespace
对比
接下来,对docker和containerd进行一个多方面的比较。看看两者究竟有哪些缺别,也帮助大家以后进行选择合适的去用。
调用链
在使用k8s时,使用docker和containerd的调用链如下所示:
不难看出,使用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相关配置
CNI
当使用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命令一样了
命名空间
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过程中,具体使用哪一种作为运行时,还是根据实际情况选择。
参考
https://github.com/containerd/containerd
本文转载自微信公众号「运维开发故事」