在Kubernetes宣布弃用对Docker的集成支持后,如何选择一款合适的容器产品进行替代,也成为了一个热门话题。在众多备选产品中,containerd无疑是其中最受欢迎的方案之一。
如果你对containerd还不熟悉,那么本文将带你揭开它的神秘面纱!
一. 产品介绍
containerd是由Docker Inc.开发的容器运行时,最初是作为Docker Daemon的一个功能模块存在,负责对容器进行操作。随着Docker架构的不断演进,为了使其更加层次分明,Docker Inc.将containerd分离出来作为独立的组件运行,并与Docker Daemon集成使用。
在2017年,Docker Inc.将其捐献给了CNCF(云原生计算基金会)成为正式项目,并在此后得到了快速的发展。
目前,containerd已成为一个工业级标准的容器运行时产品,它强调简单性、健壮性和可移植性,可以完成下面这些功能:
- 容器生命周期管理(从创建到销毁容器)
- 拉取/上传容器镜像
- 管理镜像及容器数据的存储
- 启动、停止、重启容器
- 建立和管理容器网络
作为一个轻量级的容器运行时,containerd旨在嵌入到更大的系统中,而不是直接由开发人员或最终用户使用。containerd可以被Docker嵌入使用,也可以与Kubernetes、Swarm等容器编排工具集成使用。
相较于Docker 而言,containerd的设计更加轻便和灵活。它专注于容器运行时的管理,不涉及 Docker 中的高级特性和复杂逻辑。这使得 containerd更加易于扩展和定制,用户可以根据自身需求进行灵活的配置和使用。长远来看,这种设计也更加符合容器生态的健康与可持续发展。
二. 功能架构
containerd可作为 Linux 和 Windows 的守护进程使用,管理其主机系统的完整容器生命周期:镜像传输和存储、容器执行和监督、低级存储和网络附件等。
下图是containerd整体的功能架构,最上层是暴露出来的gRPC API和Metrics API,前者用于客户端工具或第三方产品进行调用管理,后者则是提供监控数据,给到监控系统收集。
往下是核心层部分,这一层由多个功能模块组成,它们以插件的形式集成到containerd,并且插件之间相互依赖。最后,则是负责容器管理的容器运行时(Runtimes)。
containerd提供了一系列的 API 和命令行工具,可以让用户对容器进行操作,例如创建容器、启动容器、停止容器和删除容器等。
containerd支持的命令行工具有三款,分别是ctr、nerdctl和crictl。其中ctr是containerd自带的命令行工具,但支持的功能较少;nerdctl是一款第三方工具,需要单独安装,它出现的目的是为了兼容docker命令,所以在命令使用上和docker完全一样;crictl则是Kubernetes的CRI客户端,由于containerd实现了对CRI(Container Runtime Interface 容器运行时接口)标准的支持,因此可以使用该工具对其进行操作。
限于篇幅原因,本文不对命令行工具的使用进行介绍,留到我们后面的文章进行讲解。
containerd被称为高级容器运时行,它本身并不会处理所有事务,对于某些操作,它会调用另一个名为runc的组件来运行。runc是一个符合OCI(开放容器计划)规范的容器运行时,在2014年由Docker Inc.贡献给了OCI社区。runc可以被认为是低级的容器运行时,因为它只能处理有限功能业务。
当containerd收到创建容器的请求时,它会生成一个名为containerd-shim的进程 ,由这个进程去操作容器。此时,该进程会调用runc来启动容器。在容器启动完成后,runc退出并由containerd-shim来作为容器进程的父进程 ,负责收集容器进程的状态,并上报给containerd。
三. 从Docker到Containerd
作为容器编排系统,Kubernetes需要支持多种容器产品,因此需要制定容器运行时的接口标准来实现标准化。在谷歌和红帽公司的主导下,推出了前面提到的CRI标准,只要符合该标准的产品就可以轻松地接入Kubernetes平台。
而Docker由于出现在Kuberentes之前,因此在接口的设计上无法与CRI标准兼容。鉴于Docker当时强大的影响力,Kubernetes在早期开发了dockershim插件用于调用Docker,并将其集成到kubelet中。
在这种架构下,当Kubernetes需要创建一个Pod时,需要通过kubelet基于CRI接口调用dockershim,然后由dockershim进行格式转换后再转发给Docker Daemon,最终由内嵌的containerd去操作容器。
在这里我们可以看到,这种方式的调用链冗长且没有必要。一方面需要维护dockershim的代码,随着功能的增加相关代码部分会变得越加复杂,增加社区的人力维护成本。另外,较长的调用链也会导致增加故障点的风险,并影响容器的调用效率。
随着Kubernetes在后续的发展中一路狂飙,并打败了Swarm、Mesos等对手成为容器编排领域的绝对领导者。此时,Kuberenetes已经有了足够的实力来实现与Docker的分割。在2020年底时,Kuberentes社区正式宣布将在后续版本中弃用dockershim,这在当时产生了不小的轰动。
如何找到Docker的替代产品,成为了在此之后人们的关注点。此时,作为之前一直藏在背后默默无闻工作的小透明,containerd开始受到越来越多人的注意。
由于containerd和Kubernetes同属于CNCF(云原生计算基金会)组织,在本身的设计上可以很好地遵循CRI(容器运行时接口)标准,因此,可以直接通过kubelet去调用。
从 Kubernetes的角度看,选择 containerd作为容器运行时是更优的方案。相较于Docker而言,它的调用链更短,占用节点资源更少且更加稳定。这也使得containerd成为目前最受欢迎的Docker替代方案之一。
当前,Kubernetes在1.20的版本中已将dockershim标记为维护模式,并在1.24版开始,将这部分功能代码禁用,这标志着Docker与Kubernetes的正式分手。
因此,我相信对Docker的替代会是未来的主要趋势,而containerd将是一个不错的选择。
专注于Devops、SRE、运维开发等技术分享,扫码关注公众号,获取更多精彩内容!
标签:容器,调用,Kubernetes,Containerd,containerd,Docker,运行 From: https://blog.51cto.com/u_14065119/6140130