这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

从 dockershim 迁移

本节提供从 dockershim 迁移到其他容器运行时的必备知识。

自从 Kubernetes 1.20 宣布 弃用 dockershim, 各类疑问随之而来:这对各类工作负载和 Kubernetes 部署会产生什么影响。 你会发现这篇博文对于更好地理解此问题非常有用: 弃用 Dockershim 常见问题

建议从 dockershim 迁移到其他替代的容器运行时。 请参阅容器运行时 一节以了解可用的备选项。 当在迁移过程中遇到麻烦,请上报问题。 那么问题就可以及时修复,你的集群也可以进入移除 dockershim 前的就绪状态。

1 - 检查弃用 Dockershim 对你的影响

Kubernetes 的 dockershim 组件使得你可以把 Docker 用作 Kubernetes 的 容器运行时。 在 Kubernetes v1.20 版本中,内建组件 dockershim 被弃用。

本页讲解你的集群把 Docker 用作容器运行时的运作机制, 并提供使用 dockershim 时,它所扮演角色的详细信息, 继而展示了一组验证步骤,可用来检查弃用 dockershim 对你的工作负载的影响。

检查你的应用是否依赖于 Docker

虽然你通过 Docker 创建了应用容器,但这些容器却可以运行于所有容器运行时。 所以这种使用 Docker 容器运行时的方式并不构成对 Docker 的依赖。

当用了替代的容器运行时之后,Docker 命令可能不工作,甚至产生意外的输出。 这才是判定你是否依赖于 Docker 的方法。

  1. 确认没有特权 Pod 执行 docker 命令。
  2. 检查 Kubernetes 基础架构外部节点上的脚本和应用,确认它们没有执行 Docker 命令。可能的命令有:
    • SSH 到节点排查故障;
    • 节点启动脚本;
    • 直接安装在节点上的监视和安全代理。
  3. 检查执行了上述特权操作的第三方工具。详细操作请参考: 从 dockershim 迁移遥测和安全代理
  4. 确认没有对 dockershim 行为的间接依赖。这是一种极端情况,不太可能影响你的应用。 一些工具很可能被配置为使用了 Docker 特性,比如,基于特定指标发警报,或者在故障排查指令的一个环节中搜索特定的日志信息。 如果你有此类配置的工具,需要在迁移之前,在测试集群上完成功能验证。

Docker 依赖详解

容器运行时是一个软件,用来运行组成 Kubernetes Pod 的容器。 Kubernetes 负责编排和调度 Pod;在每一个节点上, kubelet 使用抽象的容器运行时接口,所以你可以任意选用兼容的容器运行时。

在早期版本中,Kubernetes 提供的兼容性支持一个容器运行时:Docker。 在 Kubernetes 发展历史中,集群运营人员希望采用更多的容器运行时。 于是 CRI 被设计出来满足这类灵活性需要 - 而 kubelet 亦开始支持 CRI。 然而,因为 Docker 在 CRI 规范创建之前就已经存在,Kubernetes 就创建了一个适配器组件:dockershim。 dockershim 适配器允许 kubelet 与 Docker交互,就好像 Docker 是一个 CRI 兼容的运行时一样。

你可以阅读博文 Kubernetes 容器集成功能的正式发布

Dockershim 和 Containerd CRI 的实现对比图

切换到容器运行时 Containerd 可以消除掉中间环节。 所有以前遗留的容器可由 Containerd 这类容器运行时来运行和管理,操作体验也和以前一样。 但是现在,由于直接用容器运行时调度容器,所以它们对 Docker 来说是不可见的。 因此,你以前用来检查这些容器的 Docker 工具或漂亮的 UI 都不再可用。

你不能再使用 docker psdocker inspect 命令来获取容器信息。 由于你不能列出容器,因此你不能获取日志、停止容器,甚至不能通过 docker exec 在容器中执行命令。

你仍然可以下载镜像,或者用 docker build 命令创建它们。 但用 Docker 创建、下载的镜像,对于容器运行时和 Kubernetes,均不可见。 为了在 Kubernetes 中使用,需要把镜像推送(push)到某注册中心。

2 - 从 dockershim 迁移遥测和安全代理

在 Kubernetes 1.20 版本中,dockershim 被弃用。 在博文弃用 Dockershim 常见问题中, 你大概已经了解到,大多数应用并没有直接通过运行时来托管容器。 但是,仍然有大量的遥测和安全代理依赖 docker 来收集容器元数据、日志和指标。 本文汇总了一些信息和链接:信息用于阐述如何探查这些依赖,链接用于解释如何迁移这些代理去使用通用的工具或其他容器运行。

遥测和安全代理

为了让代理运行在 Kubernetes 集群中,我们有几种办法。 代理既可以直接在节点上运行,也可以作为守护进程运行。

为什么遥测代理依赖于 Docker?

因为历史原因,Kubernetes 建立在 Docker 之上。 Kubernetes 管理网络和调度,Docker 则在具体的节点上定位并操作容器。 所以,你可以从 Kubernetes 取得调度相关的元数据,比如 Pod 名称;从 Docker 取得容器状态信息。 后来,人们开发了更多的运行时来管理容器。 同时一些项目和 Kubernetes 特性也不断涌现,支持跨多个运行时收集容器状态信息。

一些代理和 Docker 工具紧密绑定。此类代理可以这样运行命令,比如用 docker psdocker top 这类命令来列出容器和进程,用 docker logs 订阅 Docker 的日志。 但随着 Docker 作为容器运行时被弃用,这些命令将不再工作。

识别依赖于 Docker 的 DaemonSet

如果某 Pod 想调用运行在节点上的 dockerd,该 Pod 必须满足以下两个条件之一:

  • 将包含 Docker 守护进程特权套接字的文件系统挂载为一个;或
  • 直接以卷的形式挂载 Docker 守护进程特权套接字的特定路径。

举例来说:在 COS 镜像中,Docker 通过 /var/run/docker.sock 开放其 Unix 域套接字。 这意味着 Pod 的规约中需要包含 hostPath 卷以挂载 /var/run/docker.sock

下面是一个 shell 示例脚本,用于查找包含直接映射 Docker 套接字的挂载点的 Pod。 你也可以删掉 grep /var/run/docker.sock 这一代码片段以查看其它挂载信息。

kubectl get pods --all-namespaces \
-o=jsonpath='{range .items[*]}{"\n"}{.metadata.namespace}{":\t"}{.metadata.name}{":\t"}{range .spec.volumes[*]}{.hostPath.path}{", "}{end}{end}' \
| sort \
| grep '/var/run/docker.sock'

检测节点代理对 Docker 的依赖性

在你的集群节点被定制、且在各个节点上均安装了额外的安全和遥测代理的场景下, 一定要和代理的供应商确认:该代理是否依赖于 Docker。

遥测和安全代理的供应商

我们通过 谷歌文档 提供了为各类遥测和安全代理供应商准备的持续更新的迁移指导。 请与供应商联系,获取从 dockershim 迁移的最新说明。