Kubernetes1.24版本发布时,正式宣布弃用Dockershim,转向Containerd作为默认的容器运行环境。Kubernetes以CRI(Container Runtime Interface)容器运行时接口制定接入准则,用户可以使用Containerd、CRI-O、CRI- Dockerd及其他容器运行时作为Kubernetes的容器引擎。

Kubernetes为何弃用Dockershim?

Docker在早期没有实现Container Runtime Interface (CRI),而CRI是Kubernetes后来增加的对额外运行时的支持标准。Dockershim的存在是为了支持将Docker硬编码到Kubernetes中,但随着容器化成为行业标准,Kubernetes项目增加了对额外运行时的支持,比如通过Container Runtime Interface (CRI)容器运行时接口来支持运行容器。因此,在Kubernetes1.20版本发布的时候提到未来会弃用Dockershim引擎,而在Kubernetes1.24版本发布时,正式弃用之。

什么是 Containerd ?

containerd是一种容器运行时引擎,原属于Docker的组件的一部分,主要提供容器生命周期管理(从创建到销毁容器)、拉取和推送镜像、存储管理(管理镜像及容器数据的存储)、调用runc容器运行等,现已由开源社区拆分脱离出来单独作为容器运行时项目。

在Kubernetes中,Containerd作为容器运行环境,负责管理Pod的生命周期,包括容器的创建、启动、停止和删除等操作。与Dockershim相比,Containerd具有更好的性能、更强的可扩展性以及更简洁的架构。

容器运行底层组件有哪些关系?

Docker Client和Docker Daemon:Docker Client是Docker的客户端,它可以通过命令行或API向Docker Daemon发送请求。Docker Daemon是Docker的核心组件,负责管理镜像、容器、网络和卷等资源,并将Docker API暴露给客户端。

Docker镜像和Docker容器:Docker镜像是只读的模板,包含了所有用于运行应用程序所需要的代码、库文件、环境变量和配置文件等内容。Docker容器是基于Docker镜像创建的可运行实例。每个容器都是一个独立的、轻量级的操作系统,它们之间相互隔离并且可以共享主机的内核。

CRI(Container Runtime Interface)和容器运行时:CRI是Kubernetes的容器运行时标准接口,满足这个标准的所有容器运行时都可以被使用。容器运行时则提供了一个轻量级的容器运行环境,用于创建、启动和停止容器。

OCI(Open Container Initiative)和runc:OCI是一个开放的容器组织,它制定了容器运行时的规范,包括运行时规范、容器镜像规范等。runc是OCI标准的一个参考实现,它与容器所依赖的cgroup/linux kernel等进行交互,是容器最终运行的形态之一。

Containerd在Kubernetes的运行变化

在Kubernetes 1.24版本以前,Kubernetes通过调用Docker命令来创建容器。具体来说,Kubernetes将任务发送给Docker客户端,然后Docker客户端通过与Docker守护进程(daemon)通信来创建容器。Docker守护进程会通过Image模块下载镜像并保存,然后通过client调用containerd创建并运行容器。在这个过程中,如果需要给容器添加持久化存储,可以使用volume参数;如果需要配置容器网络,可以通过network参数来实现。

然而,Kubernetes提供了更强大的卷挂载能力和集群级别的网络能力。在集群中,kubelet只会使用到Docker提供的镜像下载和容器管理功能,而编排、网络、存储等功能都不会用到。

在Kubernetes 1.24版本以后,Containerd作为容器运行时被引入,带来了创建Pod所需的所有功能。与之前的方案相比,这不仅带来了更纯粹的功能模块,而且缩短了调用链,提高了系统的效率和稳定性。因此,用户可以使用Containerd、CRI-O、CRI-Dockerd及其他容器运行时作为Kubernetes的容器引擎。

Containerd在Kubernetes中的工作流

  1. Kubelet通过CRI运行时服务API调用CRI插件来创建Pod。
  2. CRI创建一个特殊的沙箱容器(pause容器),并将其放置在Pod的Cgroups和NameSpace命名空间中。
  3. CRI使用CNI配置Pod的网络命名空间。
  4. Kubelet随后通过CRI镜像服务API调用CRI插件来拉取应用容器镜像。如果镜像不存在于节点上,CRI会进一步使用Containerd来拉取镜像。
  5. Kubelet通过CRI运行时服务API调用CRI,并使用拉取的容器镜像在Pod内创建和启动应用程序容器。
  6. CRI创建应用程序容器,将其放入Pod的Cgroups和NameSpace中,然后启动Pod的新应用容器。

在这些步骤之后,一个Pod及其相应的应用程序容器被创建并运行。

Kubernetes弃用Dockershim的影像

容器镜像,由于Docker镜像符合OCI规范,因此可以直接使用而不受影响。此外,原镜像打包方式仍然可用,即使用docker build方式打包镜像。这意味着用户在构建和打包镜像时不需要做出任何改变

Kubernetes中的运行过程,作为终端用户(Kubernetes使用者)基本也不会有任何影响,因为Kubernetes的使用逻辑没有任何变化。然而,与Dockershim相关的API接口已经弃用,如果创建了此类CRD,需要注意修改相关代码。

运维方式,节点后端运维时使用的命令由docker命令改为containerd。如果旧环境使用的是Dockershim引擎,需要先改为containerd运行时再进行升级。运维人员则需要适应新的命令行工具和运行时环境。

Kubernetes弃用Dockershim而采用containerd作为容器运行时对用户和运维方式会有一些影响,但对于已经符合OCI规范的镜像和使用docker build方式打包镜像的用户来说,基本无感知。

Kubernetes用户如何应对?

用户需要按照Kubernetes官方提供的迁移指南进行操作。这包括更新Kubernetes版本、修改Pod配置文件、调整部署流程、更换镜像管理工具以及重新配置监控和日志采集工具等步骤。在迁移过程中,用户还需要注意测试新环境的稳定性和性能,确保迁移成功。

在迁移过程中,用户可能会遇到各种问题,如配置错误、兼容性问题、性能下降等。为了解决这些问题,用户可以参考Kubernetes官方文档和社区资源,或者向灵雀云的服务团队寻求帮助和支持。此外,用户还可以在测试环境中模拟迁移过程,提前发现和解决问题。

迁移到Containerd后,用户可以对系统进行一系列优化和改进,以提高性能和稳定性。例如,优化Pod的配置和部署流程、使用更高效的网络配置方式、改进监控和日志采集策略等。此外,用户还可以关注Kubernetes和Containerd的最新版本和功能更新,及时跟进技术发展趋势。

结论与展望

Kubernetes弃用Dockershim并转向Containerd已经成为一个明显的趋势信号。对于现有的Kubernetes用户来说,应尽快了解这一变化的影响和应对策略,找到适合自己的方案并尽早进行改进。未来,Kubernetes与Containerd的发展趋势将更加紧密地结合在一起,共同推动容器技术的不断创新和发展。

参考文档:

  • https://kubernetes.io/zh-cn/blog/2022/02/17/dockershim-faq/
  • https://kubernetes.io/zh-cn/blog/2020/12/02/dont-panic-kubernetes-and-docker/