从Docker到Containerd:容器运行时的下一步

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Docker到Containerd:容器运行时的下一步相关的知识,希望对你有一定的参考价值。

在Kubernetes宣布弃用对Docker的集成支持后,如何选择一款合适的容器产品进行替代,也成为了一个热门话题。在众多备选产品中,containerd无疑是其中最受欢迎的方案之一。

如果你对containerd还不熟悉,那么本文将带你揭开它的神秘面纱!

一. 产品介绍

containerd是由Docker Inc.开发的容器运行时,最初是作为Docker Daemon的一个功能模块存在,负责对容器进行操作。随着Docker架构的不断演进,为了使其更加层次分明,Docker Inc.将containerd分离出来作为独立的组件运行,并与Docker Daemon集成使用。

在2017年,Docker Inc.将其捐献给了CNCF(云原生计算基金会)成为正式项目,并在此后得到了快速的发展。

从Docker到Containerd:容器运行时的下一步_容器

目前,containerd已成为一个工业级标准的容器运行时产品,它强调简单性、健壮性和可移植性,可以完成下面这些功能:

  • 容器生命周期管理(从创建到销毁容器)
  • 拉取/上传容器镜像
  • 管理镜像及容器数据的存储
  • 启动、停止、重启容器
  • 建立和管理容器网络

作为一个轻量级的容器运行时,containerd旨在嵌入到更大的系统中,而不是直接由开发人员或最终用户使用。containerd可以被Docker嵌入使用,也可以与Kubernetes、Swarm等容器编排工具集成使用。

相较于Docker 而言,containerd的设计更加轻便和灵活。它专注于容器运行时的管理,不涉及 Docker 中的高级特性和复杂逻辑。这使得 containerd更加易于扩展和定制,用户可以根据自身需求进行灵活的配置和使用。长远来看,这种设计也更加符合容器生态的健康与可持续发展。


二. 功能架构

containerd可作为 Linux 和 Windows 的守护进程使用,管理其主机系统的完整容器生命周期:镜像传输和存储、容器执行和监督、低级存储和网络附件等。

下图是containerd整体的功能架构,最上层是暴露出来的gRPC API和Metrics API,前者用于客户端工具或第三方产品进行调用管理,后者则是提供监控数据,给到监控系统收集。

往下是核心层部分,这一层由多个功能模块组成,它们以插件的形式集成到containerd,并且插件之间相互依赖。最后,则是负责容器管理的容器运行时(Runtimes)。


从Docker到Containerd:容器运行时的下一步_容器_02

containerd提供了一系列的 API 和命令行工具,可以让用户对容器进行操作,例如创建容器、启动容器、停止容器和删除容器等。

containerd支持的命令行工具有三款,分别是ctr、nerdctl和crictl。其中ctr是containerd自带的命令行工具,但支持的功能较少;nerdctl是一款第三方工具,需要单独安装,它出现的目的是为了兼容docker命令,所以在命令使用上和docker完全一样;crictl则是Kubernetes的CRI客户端,由于containerd实现了对CRI(Container Runtime Interface 容器运行时接口)标准的支持,因此可以使用该工具对其进行操作。

限于篇幅原因,本文不对命令行工具的使用进行介绍,留到我们后面的文章进行讲解。

从Docker到Containerd:容器运行时的下一步_容器_03

containerd被称为高级容器运时行,它本身并不会处理所有事务,对于某些操作,它会调用另一个名为runc的组件来运行。runc是一个符合OCI(开放容器计划)规范的容器运行时,在2014年由Docker Inc.贡献给了OCI社区。runc可以被认为是低级的容器运行时,因为它只能处理有限功能业务。

containerd收到创建容器的请求时,它会生成一个名为containerd-shim的进程 ,由这个进程去操作容器。此时,该进程会调用runc来启动容器。在容器启动完成后,runc退出并由containerd-shim来作为容器进程的父进程 ,负责收集容器进程的状态,并上报给containerd

从Docker到Containerd:容器运行时的下一步_kubernetes_04


三. 从Docker到Containerd

作为容器编排系统,Kubernetes需要支持多种容器产品,因此需要制定容器运行时的接口标准来实现标准化。在谷歌和红帽公司的主导下,推出了前面提到的CRI标准,只要符合该标准的产品就可以轻松地接入Kubernetes平台。

而Docker由于出现在Kuberentes之前,因此在接口的设计上无法与CRI标准兼容。鉴于Docker当时强大的影响力,Kubernetes在早期开发了dockershim插件用于调用Docker,并将其集成到kubelet中。

在这种架构下,当Kubernetes需要创建一个Pod时,需要通过kubelet基于CRI接口调用dockershim,然后由dockershim进行格式转换后再转发给Docker Daemon,最终由内嵌的containerd去操作容器。

从Docker到Containerd:容器运行时的下一步_容器_05

在这里我们可以看到,这种方式的调用链冗长且没有必要。一方面需要维护dockershim的代码,随着功能的增加相关代码部分会变得越加复杂,增加社区的人力维护成本。另外,较长的调用链也会导致增加故障点的风险,并影响容器的调用效率。

随着Kubernetes在后续的发展中一路狂飙,并打败了Swarm、Mesos等对手成为容器编排领域的绝对领导者。此时,Kuberenetes已经有了足够的实力来实现与Docker的分割。在2020年底时,Kuberentes社区正式宣布将在后续版本中弃用dockershim,这在当时产生了不小的轰动。

如何找到Docker的替代产品,成为了在此之后人们的关注点。此时,作为之前一直藏在背后默默无闻工作的小透明,containerd开始受到越来越多人的注意。

由于containerd和Kubernetes同属于CNCF(云原生计算基金会)组织,在本身的设计上可以很好地遵循CRI(容器运行时接口)标准,因此,可以直接通过kubelet去调用。​

从Docker到Containerd:容器运行时的下一步_kubernetes_06

从 Kubernetes的角度看,选择 containerd作为容器运行时是更优的方案。相较于Docker而言,它的调用链更短,占用节点资源更少且更加稳定。这也使得containerd成为目前最受欢迎的Docker替代方案之一。

当前,Kubernetes在1.20的版本中已将dockershim标记为维护模式,并在1.24版开始,将这部分功能代码禁用,这标志着Docker与Kubernetes的正式分手。

因此,我相信对Docker的替代会是未来的主要趋势,而containerd将是一个不错的选择。



专注于Devops、SRE、运维开发等技术分享,扫码关注公众号,获取更多精彩内容!  

从Docker到Containerd:容器运行时的下一步_containerd_07

containerd和docker技术的比较

containerd和docker技术的比较

一、容器运行时概念

容器运行时(Container Runtime)是Kubernetes(k8s)最重要的组件之一,
负责管理镜像和容器的生命周期。Kubelet通过Container Runtime Interface (CRI) 与容器运行时交互,以管理镜像和容器。

二、选择docker作为运行时组件的场景

1.使用docker in docker。
2.华为云的云容器引擎中,CCE节点使用docker build/push/save/load等命令。
3.调用docker API。
4.docker compose或docker swarm。

三、两者命令比较

1.Containerd不支持dockerAPI和do

以上是关于从Docker到Containerd:容器运行时的下一步的主要内容,如果未能解决你的问题,请参考以下文章

容器运行时docker和containerd兼容问题

将Kubernetes的Runtime由Docker修改为containerd

containerd和docker技术的比较

k8s使用containerd作为容器运行时

在Linux中安装containerd作为kubernetes的容器运行时

K3s 集群内 containerd 跟 docker 的区别