容器与 Docker 这个名称并不紧密相关。你可以使用其他工具来运行容器
您可以使用 Docker 或一堆非Docker 的其他工具来运行容器。docker
只是众多选项之一,Docker(公司)在生态系统中创建了一些很棒的工具,但不是全部。
容器方面有两大标准:
- 开放容器计划(OCI):一组容器标准,描述镜像格式、运行时和分发。
- Kubernetes中的容器运行时接口(CRI):允许您在 Kubernetes 中使用不同容器运行时的 API。
Docker 堆栈的工作原理
Docker Engine 附带一系列工具,让开发人员或系统管理员可以轻松构建和运行容器。它基本上 是一个用于处理容器的命令行界面 (CLI)。
因此,实际上,当您使用 运行容器时docker
,您实际上是通过 Docker 守护进程运行它,它会调用 containerd,然后使用 runc。
但docker
命令只是拼图的一小部分。它实际上调用一些较低级别的工具来完成繁重的工作:
Docker 堆栈中的低级工具有哪些?
ddocker
从下往上,这些是用于运行容器的工具:
- 最低级别 🔩低级容器运行时。runc 是一个低级容器运行时。它使用 Linux 的原生功能来创建和运行容器。它遵循 OCI 标准,并包含libcontainer,这是一个用于创建容器的 Go 库。
- 🔧高级容器运行时。containerd 位于低级运行时之上,并添加了许多功能,例如传输图像、存储和网络。它还完全支持 OCI 规范。
- 👺 Docker 守护进程。dockerd 是一个守护进程(在后台运行的长时间运行的进程),它提供标准 API,并与容器运行时进行通信
- 最高级别 👩💻 Docker CLI 工具。最后,docker-cli让您能够使用命令与 Docker 守护程序进行交互
docker ...
。这样您就可以控制容器,而无需了解较低级别。
Kubernetes 使用 Docker 吗?
一个非常常见的问题是“容器如何在 Kubernetes 中运行?”。Kubernetes 使用 Docker 吗?嗯,现在它不再使用 Docker 了——但以前是使用 Docker 的。
最初,Kubernetes 使用 Docker(Docker Engine)来运行容器。
但随着时间的推移,Kubernetes 逐渐演变成一个与容器无关的平台。Kubernetes中创建了容器运行时接口 (CRI) API,允许将不同的容器运行时插入其中。
Docker Engine 是一个比 Kubernetes 更老的项目,它没有实现 CRI。因此,为了帮助过渡,Kubernetes 项目包含了一个名为dockershim的组件,它允许 Kubernetes 使用 Docker 运行时运行容器。
它弥合了新旧世界之间的差距。
垫片(shim)的消亡
但从 Kubernetes 1.24 开始,dockershim 组件被彻底移除,Kubernetes 不再支持 Docker 作为容器运行时,你需要选择实现了 CRI 的容器运行时。
Kubernetes 集群中 Docker Engine 的逻辑继任者是...... containerd。(如果你答对了,可以得 10 分!)或者你也可以使用其他运行时,比如CRI-O。
这并不意味着 Kubernetes 无法运行所谓的 Docker 格式的容器。containerd和CRI -O 都可以在 Kubernetes 中运行 Docker 格式和 OCI 格式的镜像;它们无需使用命令docker
或 Docker 守护进程即可完成此操作。
开放容器计划 (OCI) 规范
OCI是首批为容器世界制定标准的组织之一。它由 Docker 和其他公司于 2015 年成立。
OCI 得到了众多科技公司的支持,并维护着容器镜像格式以及容器运行方式的规范。
例如:您可能对 Linux 主机使用一个符合 OCI 标准的运行时,但对 Windows 主机使用不同的运行时。
Kubernetes 容器运行时接口
我们需要讨论的另一个标准是容器运行时接口(CRI)。这是由 Kubernetes 项目创建的 API。
CRI 是 Kubernetes 用于控制创建和管理容器的不同运行时的接口。
因此,如果您更喜欢使用containerd在 Kubernetes 中运行容器,那么您可以这样做!或者,如果您更喜欢使用CRI-O,那么也可以。这是因为这两个运行时都实现了 CRI 规范。
但是,如果您付费从供应商处获得支持(安全性、错误修复等),那么您选择的容器运行时可能会为您做出选择。例如,Red Hat 的OpenShift 使用CRI-O,并为其提供支持。Docker 为他们自己的containerd提供支持。
containerd 和 CRI-O
我们已经看到 Docker Engine 调用了一堆底层工具。但这些工具是什么?它们如何组合在一起?
第一层是高级运行时:由 Docker 创建的containerd和由 Red Hat 创建的CRI-O 。
容器
containerd是源自 Docker 的高级容器运行时。它实现了 CRI 规范。它从注册表中提取镜像,对其进行管理,然后将其移交给较低级别的运行时,后者使用 Linux 内核的功能来创建我们称为“容器”的进程。
克里欧
CRI-O是另一个实现 Kubernetes 容器运行时接口 (CRI) 的高级容器运行时。它是 containerd 的替代品。它从注册表中提取容器映像,在磁盘上管理它们,并启动较低级别的运行时来运行容器进程。
是的,CRI-O 是另一个容器运行时。它诞生于 Red Hat、IBM、Intel 和 SUSE。
runc 和其他低级运行时
r unc是一个兼容 OCI 的容器运行时,它实现了 OCI 规范并运行容器进程。
runc有时被称为 OCI 的“参考实现”。
其他低级运行时
但是,runc 并不是唯一的低级运行时。OCI 规范允许其他工具以不同的方式实现相同的功能:
- crun 是一个用C编写的容器运行时(相比之下,runc 是用 Go 编写的。)
- AWS 的firecracker-containerd,它将 OCI 规范作为单独的轻量级虚拟机实现(它也与支持 AWS Lambda 的技术相同)
- Google 的gVisor可以创建具有自己内核的容器。它在其运行时中实现了 OCI,称为
runsc
。
概括
有一套开放标准,理论上可以更轻松地更换不同的实现。containerd 、runc和CRI -O等项目实现了这些标准的部分内容。
在 Kubernetes 中,你可以选择要使用的容器运行时,只要它支持 CRI API 即可。你可以使用containerd或CRI-O。
最后,这个故事的寓意是:
在 k8s 1.24 版本之后,docker/dockershim 已被弃用,即容器无法通过 docker 命令管理,
但您可以使用支持 CRI(K8s 原生 API)的其他容器运行时,
通过使用 crictl 命令(或其他支持的命令)来管理容器/pod,而不是 docker 命令。
通过 crictl 映射 docker cli :https://medium.com/@vineetcic/mapping-from-dockercli-to-crictl-life-after-docker-is-cri-a39ea5649d6c
享受!!!