Kubernetes Docker 弃用了?等等,Docker 在 Kubernetes 中已经弃用了?我该怎么办?

2025-05-24

Kubernetes Docker 弃用了?等等,Docker 在 Kubernetes 中已经弃用了?我该怎么办?

总结

对于开发人员

别担心,Docker 容器和镜像仍然有效。这并不意味着它会改变一切。

还值得一读:

https://kubernetes.io/blog/2020/12/02/dont-panic-kubernetes-and-docker/

https://kubernetes.io/blog/2020/12/02/dockershim-faq/

对于 K8s 管理员

仔细阅读并开始考虑 Docker 替代方案

这是真的吗?

是的,确实如此。Docker 现在在 Kubernetes 中已被弃用。

参考https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#deprecation

kubelet 中的 Docker 支持现已弃用,并将在未来版本中移除。kubelet 使用名为“dockershim”的模块来实现对 Docker 的 CRI 支持,该模块在 Kubernetes 社区中存在一些维护问题。我们建议您在 CRI 全面实现(v1alpha1 或兼容 v1)的容器运行时可用时,评估迁移到该容器运行时。

简而言之,这意味着 Docker 不支持Kubernetes 运行时 API(即 CRI,Container Runtime Interface),Kubernetes 团队一直在使用一种名为“dockershim”的桥接服务。该服务负责转换 Docker API 和 CRI,但在接下来的几个小版本中,Kubernetes 端将不再提供该服务。

本地 Docker 无疑是创建开发环境的非常强大的工具,但为了了解造成这种情况的原因,您需要了解 Docker 在当前 Kubernetes 架构中的作用。

Kubernetes 是一个基础架构编排工具,它将许多不同的计算资源(例如虚拟机/物理机)组合在一起,使其看起来像一个巨大的计算资源,供您的应用程序运行并与其他应用程序共享。在此架构中,Docker(或容器运行时)仅用于通过 Kubernetes 控制平面的调度在实际主机中运行这些应用程序。

替代文本

查看架构图。您可以看到每个 Kubernetes 节点都与控制平面通信。kubelet在每个节点上获取元数据,并执行 CRI 在节点上运行创建/删除容器的操作。

但是为什么 Docker 被弃用了呢?

再次强调,Kubernetes 仅通过 CRI 进行通信,而与 Docker 通信需要桥接服务。这就是原因 1。

为了解释下一个原因,我们需要先了解一下 Docker 的架构。如下图所示。

替代文本

是的,Kubernetes 实际上需要红色区域内的内容。Kubernetes 中不使用 Docker 网络和卷。

拥有更多你从未使用的功能本身就可能带来安全风险。功能越少,攻击面就越小。

所以这就是你开始考虑替代方案的地方。它被称为 CRI 运行时。

CRI 运行时

有两种主要的 CRI 运行时实现。

容器

如果您只是想从 Docker 迁移,这是最佳选择,因为如上图所示,Containerd 实际上在 Docker 内部用于执行所有“运行时”任务。他们提供 CRI,而且它与 Docker 提供的完全一致。

containerd 是 100% 开源的,因此您可以在 GitHub 上查看文档,甚至可以为其做出贡献。

https://github.com/containerd/containerd/

CRI-O

CRI-O 是一个主要由 Red Hat 团队开发的 CRI 运行时。事实上,这个运行时现在已经在 Red Hat OpenShift 中使用了。没错,它们不再依赖 Docker 了。

有趣的是,RHEL 7 也没有正式支持 Docker。相反,他们为容器环境提供了 Podman、Buildah 和 CRI-O。

https://github.com/cri-o/cri-o

我认为 CRI-O 的优势在于它的极简主义,因为它被设计为一个“CRI”运行时。虽然 containerd 最初是 Docker 的一部分,旨在更加开源,但它们是纯粹的 CRI 运行时,因此 CRI-O 没有任何 CRI 不需要的功能。

因此,从 Docker 迁移到 CRI-O 可能更具挑战性,但它仍然提供在 Kubernetes 上运行应用程序所需的功能。

还有一件事...

当我们谈论容器运行时时,我们需要注意具体指的是哪种类型的运行时。我们有两种类型的运行时:CRI 运行时和 OCI 运行时。

CRI 运行时

正如我所描述的,CRI 是 Kubernetes 提供的 API,用于与容器运行时通信以创建/删除容器化应用程序。

它们以 kubelet 的身份通过 IPC 使用 gRPC 进行通信,运行时也运行在同一台主机上。CRI 运行时负责从 kubelet 获取请求,并执行 OCI 容器运行时来运行容器。等等,什么?也许我应该用一张图来解释一下。

替代文本

因此,CRI 运行时的作用如下

  1. 从 kubelet 获取 gRPC 请求
  2. 按照规范创建 OCI json 配置

OCI 运行时

OCI 运行时负责使用 Linux 内核系统调用(例如 cgroups 和 namespace)来生成容器。您可能听说过runcgVisor。这就是它们的含义。

附录1:runC的工作原理

替代文本

CRI 通过调用 Linux 系统调用执行二进制文件后,runC 会生成容器。这表明 runC依赖于Linux 机器上运行的内核。

这也意味着,如果你发现 runC 漏洞,导致你窃取了主机的 root 权限,那么容器化应用程序也有可能得逞。恶意黑客可能会窃取你主机的 root 权限,然后轰!事情肯定会变得很糟糕。这就是为什么你应该持续更新 Docker(或任何其他容器运行时),而不仅仅是更新容器化应用程序的原因之一。

附录2:gVisor 的工作原理

替代文本

gVisor 是一个 OCI 运行时,最初由 Google 团队创建。它实际上运行在 Google 的基础架构上,用于运行 Google Cloud Run、Google App Engine(第二代)和 Google Cloud Functions(甚至更多!)等云服务。

有趣的是,gVisor 有一个“客户内核”层,这意味着容器化应用程序无法直接接触主机内核层。即使它们认为自己可以接触,也只能接触 gVisor 的客户内核。

gVisor 的安全模型实际上非常有趣,值得阅读官方文档

与 runC 的显著差异如下。

结论

1. Docker 肯定已被弃用,但仅限于 Kubernetes,因此如果您是 K8s 管理员,您应该开始考虑采用 CRI 运行时,例如 containerd 和 CRI-O。

a. containerd 与 Docker 兼容,核心组件相同。b
. 如果你希望 Kubernetes 拥有更精简的功能,CRI-O 是一个不错的选择

2. 了解 CRI 和 OCI 运行时职责和范围的区别

根据您的工作量,runC 可能并不总是最好的选择!

文章来源:https://dev.to/inductor/wait-docker-is-deprecated-in-kubernetes-now-what-do-i-do-e4m
PREV
字符串是邪恶的
NEXT
让我了解 JavaScript 的底层工作原理