第26节 OCI,CRI,runc,containerd,cri-containerd,dockershim等组件解释
❤️💕💕记录sealos开源项目的学习过程。k8s,docker和云原生的学习。Myblog:http://nsddd.top
[TOC]
层级调用关系
OCI(Open Container Initiative)
OCI(Open Container Initiative)即开放的容器运行时规范
,目的在于定义一个容器运行时及镜像的相关标准和规范,其中包括
- runtime-spec:容器的生命周期管理,具体参考runtime-spec。
- image-spec:镜像的生命周期管理,具体参考image-spec。
实现OCI标准的容器运行时有runc
,kata
等。
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
来创建和运行容器。
docker与containerd、runc的关系图
- 最终用户使用docker命令创建并运行容器。
- Containerd提取映像,管理网络和存储,并使用runc运行容器。
- Runc做低级的“事情”来创建和运行容器化的进程。
更具体的调用逻辑:
Containerd 是在 Docker 1.11 中引入的,用于管理节点上的 runC 容器。如下所示,它为每个容器创建一个containerd-shim,shim管理其对应容器的生命周期。
CRI(Container Runtime Interface )
CRI即容器运行时接口,主要用来定义k8s与容器运行时的API调用,kubelet通过CRI来调用容器运行时,只要实现了CRI接口的容器运行时就可以对接到k8s的kubelet组件。
Kubernetes 所有项目在所有版本中出产的工件(Kubernetes 二进制文件)都经过了验证。
此外,kind 项目使用 containerd 已经有一段时间了,并且提高了其用例的稳定性。 Kind 和 containerd 每天都会被多次使用来验证对 Kubernetes 代码库的任何更改。 其他相关项目也遵循同样的模式,从而展示了其他容器运行时的稳定性和可用性。 例如,OpenShift 4.x 从 2019 年 6 月以来,就一直在生产环境中使用 CRI-O 运行时。
至于其他示例和参考资料,你可以查看 containerd 和 CRI-O 的使用者列表, 这两个容器运行时是云原生基金会(CNCF)下的项目。
docker与k8s调用containerd的关系图
cri-containerd
CRI Plugin调用流程
- kubelet调用CRI插件,通过CRI Runtime Service接口创建pod
- cri通过CNI接口创建和配置pod的network namespace
- cri调用containerd创建sandbox container(pause container )并将容器放入pod的cgroup和namespace中
- kubelet调用CRI插件,通过image service接口拉取镜像,接着通过containerd来拉取镜像
- kubelet调用CRI插件,通过runtime service接口运行拉取下来的镜像服务,最后通过containerd来运行业务容器,并将容器放入pod的cgroup和namespace中。
k8s对runtime调用的演进
k3s 也是如此,关于对 Kubernetes 的调用,其中的
由原来通过dockershim调用docker再调用containerd,直接变成通过cri-containerd调用containerd,从而减少了一层docker调用逻辑。
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 Initiative 的缩写, 它标准化了容器工具和底层实现之间的大量接口。 它们维护了打包容器镜像(OCI image)和运行时(OCI runtime)的标准规范。 它们还以 runc 的形式维护了一个 runtime-spec 的真实实现, 这也是 containerd 和 CRI-O 依赖的默认运行时。 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 配置,则可能需要为新的容器运行时做一些适配工作。
另外还有一个需要关注的点,那就是当创建镜像时,系统维护或嵌入容器方面的任务将无法工作。 对于前者,可以用 crictl
工具作为临时替代方案 (参阅从 docker cli 到 crictl 的映射)。 对于后者,可以用新的容器创建选项,例如 img、 buildah、 kaniko 或 buildkit-cli-for-kubectl, 他们都不需要 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 image
✴️版权声明 © :本书所有内容遵循CC-BY-SA 3.0协议(署名-相同方式共享)©