第26节 OCI,CRI,runc,containerd,cri-containerd,dockershim等组件解释


❤️💕💕记录sealosopen in new window开源项目的学习过程。k8s,docker和云原生的学习open in new window。Myblog:http://nsddd.topopen in new window


[TOC]

层级调用关系

image-20230207113509803

OCI(Open Container Initiative)

OCI(Open Container Initiative)即开放的容器运行时规范,目的在于定义一个容器运行时及镜像的相关标准和规范,其中包括

实现OCI标准的容器运行时有runckata等。

RunC

runc(run container)是一个基于OCI标准实现的一个轻量级容器运行工具,用来创建和运行容器。而Containerd是用来维持通过runc创建的容器的运行状态。即runc用来创建和运行容器,containerd作为常驻进程用来管理容器。

runc包含libcontainer,包括对namespace和cgroup的调用操作。

root@cubmaster01:/opt/vpn/Clash# runc --help
USAGE:
   runc [global options] command [command options] [arguments...]

VERSION:
   1.0.0-rc10
commit: dc9208a3303feef5b3839f4323d9beb36df0a9dd
spec: 1.0.1-dev

COMMANDS:
     checkpoint  checkpoint a running container
     create      create a container
     delete      delete any resources held by the container often used with detached container
     events      display container events such as OOM notifications, cpu, memory, and IO usage statistics
     exec        execute new process inside the container
     init        initialize the namespaces and launch the process (do not call it outside of runc)
     kill        kill sends the specified signal (default: SIGTERM) to the container's init process
     list        lists containers started by runc with the given root
     pause       pause suspends all processes inside the container
     ps          ps displays the processes running inside a container
     restore     restore a container from a previous checkpoint
     resume      resumes all processes that have been previously paused
     run         create and run a container
     spec        create a new specification file
     start       executes the user defined process in a created container
     state       output the state of a container
     update      update container resource constraints
     help, h     Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug             enable debug output for logging
   --log value         set the log file path where internal debug information is written
   --log-format value  set the format used by logs ('text' (default), or 'json') (default: "text")
   --root value        root directory for storage of container state (this should be located in tmpfs) (default: "/run/runc")
   --criu value        path to the criu binary used for checkpoint and restore (default: "criu")
   --systemd-cgroup    enable systemd cgroup support, expects cgroupsPath to be of form "slice:prefix:name" for e.g. "system.slice:runc:434234"
   --rootless value    ignore cgroup permission errors ('true', 'false', or 'auto') (default: "auto")
   --help, -h          show help
   --version, -v       print the version

cantainerd

针对 runtime module

containerd(container daemon)是一个daemon进程用来管理和运行容器,可以用来拉取/推送镜像和管理容器的存储和网络。其中可以调用 runc 来创建和运行容器。

image-20230207132129355

docker与containerd、runc的关系图

image-20230207132203099

  • 最终用户使用docker命令创建并运行容器。
  • Containerd提取映像,管理网络和存储,并使用runc运行容器。
  • Runc做低级的“事情”来创建和运行容器化的进程。

更具体的调用逻辑:

Containerd 是在 Docker 1.11 中引入的,用于管理节点上的 runC 容器。如下所示,它为每个容器创建一个containerd-shim,shim管理其对应容器的生命周期。

image-20230207132215193

CRI(Container Runtime Interface )

CRI即容器运行时接口,主要用来定义k8s与容器运行时的API调用,kubelet通过CRI来调用容器运行时,只要实现了CRI接口的容器运行时就可以对接到k8s的kubelet组件。

Kubernetes 所有项目在所有版本中出产的工件(Kubernetes 二进制文件)都经过了验证。

此外,kindopen in new window 项目使用 containerd 已经有一段时间了,并且提高了其用例的稳定性。 Kind 和 containerd 每天都会被多次使用来验证对 Kubernetes 代码库的任何更改。 其他相关项目也遵循同样的模式,从而展示了其他容器运行时的稳定性和可用性。 例如,OpenShift 4.x 从 2019 年 6 月以来,就一直在生产环境中使用 CRI-Oopen in new window 运行时。

至于其他示例和参考资料,你可以查看 containerd 和 CRI-O 的使用者列表, 这两个容器运行时是云原生基金会(CNCFopen in new window)下的项目。

docker与k8s调用containerd的关系图

img

cri-containerd

image-20230207132921651

CRI Plugin调用流程

Link🔍 open in new window

  1. kubelet调用CRI插件,通过CRI Runtime Service接口创建pod
  2. cri通过CNI接口创建和配置pod的network namespace
  3. cri调用containerd创建sandbox container(pause containeropen in new window )并将容器放入pod的cgroup和namespace中
  4. kubelet调用CRI插件,通过image service接口拉取镜像,接着通过containerd来拉取镜像
  5. kubelet调用CRI插件,通过runtime service接口运行拉取下来的镜像服务,最后通过containerd来运行业务容器,并将容器放入pod的cgroup和namespace中。

k8s对runtime调用的演进

k3s 也是如此,关于对 Kubernetes 的调用,其中的

由原来通过dockershim调用docker再调用containerd,直接变成通过cri-containerd调用containerd,从而减少了一层docker调用逻辑。

image-20230207133512109

dockershim

这是个被淘汰的家伙。

在旧版本的k8s中,由于docker没有实现CRI接口,因此增加一个Dockershim来实现k8s对docker的调用。(shim:垫片,一般用来表示对第三方组件API调用的适配插件,例如k8s使用Dockershim来实现对docker接口的适配调用)

从 Kubernetes v1.24 开始,Dockershim 已被删除,这对该项目来说是一个积极的举措。然而,上下文对于完全理解某些东西很重要,无论是在社交上还是在软件开发中,这都值得更深入的回顾。除了在 Kubernetes v1.24 中删除 dockershim 之外,我们在社区中看到了一些混乱(有时处于恐慌级别)和对这一决定的不满,这主要是由于缺乏关于此删除的上下文。弃用并最终从 Kubernetes 中删除 dockershim 的决定并不是很快或轻易做出的。尽管如此,它已经存在了很长时间,以至于今天的许多用户比那个决定更新,而且肯定比导致 dockershim 成为必要的选择更新。

CRI-O

cri-o与containerd类似,用来实现容器的管理,可替换containerd的使用。

CRI-O 是一个 Kubernetes 容器运行时,特别为 OCI(Open Container Initiative)容器规范设计的。它的目的是提供一种轻量级、高效的方式来运行容器,同时保持与 Kubernetes 的兼容性。CRI-O 使用 Kubernetes 的 Container Runtime Interface (CRI) 来与 Kubernetes 集群通信,因此可以与 Kubernetes 结合使用,并且能够替代其他常用的容器运行时,如 Docker。

OCI 是 Open Container Initiativeopen in new window 的缩写, 它标准化了容器工具和底层实现之间的大量接口。 它们维护了打包容器镜像(OCI image)和运行时(OCI runtime)的标准规范。 它们还以 runcopen in new window 的形式维护了一个 runtime-spec 的真实实现, 这也是 containerdopen in new windowCRI-Oopen in new window 依赖的默认运行时。 CRI 建立在这些底层规范之上,为管理容器提供端到端的标准。

切换 CRI 时 要注意什么

虽然 Docker 和大多数 CRI(包括 containerd)之间的底层容器化代码是相同的, 但其周边部分却存在差异。迁移时要考虑如下常见事项:

  • 日志配置
  • 运行时的资源限制
  • 调用 docker 或通过其控制套接字使用 Docker Engine 的节点配置脚本
  • 需要 docker 命令或 Docker Engine 控制套接字的 kubectl 插件
  • 需要直接访问 Docker Engine 的 Kubernetes 工具(例如:已弃用的 'kube-imagepuller' 工具)
  • 配置 registry-mirrors 和不安全的镜像仓库等功能
  • 保障 Docker Engine 可用、且运行在 Kubernetes 之外的脚本或守护进程(例如:监视或安全代理)
  • GPU 或特殊硬件,以及它们如何与你的运行时和 Kubernetes 集成

如果你只是用了 Kubernetes 资源 请求/限制 或基于文件的日志收集 DaemonSet,它们将继续稳定工作, 但是如果你用了自定义了 dockerd 配置,则可能需要为新的容器运行时做一些适配工作。

另外还有一个需要关注的点,那就是当创建镜像时,系统维护或嵌入容器方面的任务将无法工作。 对于前者,可以用 crictlopen in new window 工具作为临时替代方案 (参阅从 docker cli 到 crictl 的映射open in new window)。 对于后者,可以用新的容器创建选项,例如 imgopen in new windowbuildahopen in new windowkanikoopen in new windowbuildkit-cli-for-kubectlopen in new window, 他们都不需要 Docker。

END 链接

参考:

  • https://opencontainers.org/about/overview/
  • https://github.com/opencontainers/runtime-spec
  • https://github.com/kubernetes/kubernetes/blob/242a97307b34076d5d8f5bbeb154fa4d97c9ef1d/docs/devel/container-runtime-interface.md
  • https://github.com/containerd/containerd/blob/main/docs/cri/architecture.md
  • https://www.tutorialworks.com/difference-docker-containerd-runc-crio-oci/
  • https://kubernetes.io/zh/docs/setup/production-environment/container-runtimes/
  • use non root OR rootless build imageopen in new window