这是本节的多页打印视图。
点击此处打印.
返回本页常规视图.
从 dockershim 迁移
本节提供从 dockershim 迁移到其他容器运行时的必备知识。
自从 Kubernetes 1.20 宣布
弃用 dockershim,
各类疑问随之而来:这对各类工作负载和 Kubernetes 部署会产生什么影响。
我们的弃用 Dockershim 常见问题可以帮助你更好地理解这个问题。
建议从 dockershim 迁移到其他替代的容器运行时。
请参阅容器运行时
一节以了解可用的备选项。
当在迁移过程中遇到麻烦,请上报问题。
那么问题就可以及时修复,你的集群也可以进入移除 dockershim 前的就绪状态。
1 - 将节点上的容器运行时从 Docker Engine 改为 containerd
本任务给出将容器运行时从 Docker 改为 containerd 所需的步骤。
此任务适用于运行 1.23 或更早版本 Kubernetes 的集群操作人员。
同时,此任务也涉及从 dockershim 迁移到 containerd 的示例场景,
以及可以从此页面
获得的其他容器运行时列表。
Before you begin
Note:
This section links to third party projects that provide functionality required by Kubernetes. The Kubernetes project authors aren't responsible for these projects, which are listed alphabetically. To add a project to this list, read the
content guide before submitting a change.
More information.
安装 containerd。进一步的信息可参见
containerd 的安装文档。
关于一些特定的环境准备工作,请遵循 containerd 指南。
腾空节点
kubectl drain <node-to-drain> --ignore-daemonsets
将 <node-to-drain>
替换为你所要腾空的节点的名称
停止 Docker 守护进程
systemctl stop kubelet
systemctl disable docker.service --now
安装 Containerd
遵循此指南
了解安装 containerd 的详细步骤。
- 从官方的 Docker 仓库安装
containerd.io
包。关于为你所使用的 Linux 发行版来设置
Docker 仓库,以及安装 containerd.io
包的详细说明,可参见
Install Docker Engine。
-
配置 containerd:
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
-
重启 containerd:
sudo systemctl restart containerd
启动一个 Powershell 会话,将 $Version
设置为期望的版本(例如:$Version="1.4.3"
),
之后运行下面的命令:
-
下载 containerd:
curl.exe -L https://github.com/containerd/containerd/releases/download/v$Version/containerd-$Version-windows-amd64.tar.gz -o containerd-windows-amd64.tar.gz
tar.exe xvf .\containerd-windows-amd64.tar.gz
-
解压缩并执行配置:
Copy-Item -Path ".\bin\" -Destination "$Env:ProgramFiles\containerd" -Recurse -Force
cd $Env:ProgramFiles\containerd\
.\containerd.exe config default | Out-File config.toml -Encoding ascii
# 请审查配置信息。取决于你的安装环境,你可能需要调整:
# - the sandbox_image (Kubernetes pause 镜像)
# - cni bin_dir 和 conf_dir 的位置
Get-Content config.toml
# (可选步骤,但强烈建议执行)将 containerd 排除在 Windows Defender 扫描之外
Add-MpPreference -ExclusionProcess "$Env:ProgramFiles\containerd\containerd.exe"
-
启动 containerd:
.\containerd.exe --register-service
Start-Service containerd
配置 kubelet 使用 containerd 作为其容器运行时
编辑文件 /var/lib/kubelet/kubeadm-flags.env
,将 containerd 运行时添加到标志中:
--container-runtime=remote
和 --container-runtime-endpoint=unix:///run/containerd/containerd.sock"
。
对于使用 kubeadm 的用户,可以考虑下面的问题:
kubeadm
工具将每个主机的 CRI 套接字保存在该主机对应的 Node 对象的注解中。
使用 kubeadm
的用户应该知道,kubeadm
工具将每个主机的 CRI 套接字保存在该主机对应的 Node 对象的注解中。
要更改这一注解信息,你可以在一台包含 kubeadm /etc/kubernetes/admin.conf
文件的机器上执行以下命令:
kubectl edit no <node-name>
这一命令会打开一个文本编辑器,供你在其中编辑 Node 对象。
要选择不同的文本编辑器,你可以设置 KUBE_EDITOR
环境变量。
-
更改 kubeadm.alpha.kubernetes.io/cri-socket
值,将其从
/var/run/dockershim.sock
改为你所选择的 CRI 套接字路径
(例如:unix:///run/containerd/containerd.sock
)。
注意新的 CRI 套接字路径必须带有 unix://
前缀。
-
保存文本编辑器中所作的修改,这会更新 Node 对象。
重启 kubelet
验证节点处于健康状态
运行 kubectl get nodes -o wide
,containerd 会显示为我们所更改的节点上的运行时。
Note:
This section links to third party projects that provide functionality required by Kubernetes. The Kubernetes project authors aren't responsible for these projects, which are listed alphabetically. To add a project to this list, read the
content guide before submitting a change.
More information.
最后,在一切顺利时删除 Docker。
sudo yum remove docker-ce docker-ce-cli
sudo apt-get purge docker-ce docker-ce-cli
sudo dnf remove docker-ce docker-ce-cli
sudo apt-get purge docker-ce docker-ce-cli
2 - 查明节点上所使用的容器运行时
本页面描述查明集群中节点所使用的容器运行时
的步骤。
取决于你运行集群的方式,节点所使用的容器运行时可能是事先配置好的,
也可能需要你来配置。如果你在使用托管的 Kubernetes 服务,
可能存在特定于厂商的方法来检查节点上配置的容器运行时。
本页描述的方法应该在能够执行 kubectl
的场合下都可以工作。
Before you begin
安装并配置 kubectl
。参见安装工具 节了解详情。
查明节点所使用的容器运行时
使用 kubectl
来读取并显示节点信息:
kubectl get nodes -o wide
输出如下面所示。CONTAINER-RUNTIME
列给出容器运行时及其版本。
# For dockershim
NAME STATUS VERSION CONTAINER-RUNTIME
node-1 Ready v1.16.15 docker://19.3.1
node-2 Ready v1.16.15 docker://19.3.1
node-3 Ready v1.16.15 docker://19.3.1
# For containerd
NAME STATUS VERSION CONTAINER-RUNTIME
node-1 Ready v1.19.6 containerd://1.4.1
node-2 Ready v1.19.6 containerd://1.4.1
node-3 Ready v1.19.6 containerd://1.4.1
你可以在容器运行时
页面找到与容器运行时相关的更多信息。
3 - 检查弃用 Dockershim 对你的影响
Kubernetes 的 dockershim
组件使得你可以把 Docker 用作 Kubernetes 的
容器运行时。
在 Kubernetes v1.20 版本中,内建组件 dockershim
被弃用。
本页讲解你的集群把 Docker 用作容器运行时的运作机制,
并提供使用 dockershim
时,它所扮演角色的详细信息,
继而展示了一组操作,可用来检查弃用 dockershim
对你的工作负载是否有影响。
检查你的应用是否依赖于 Docker
即使你是通过 Docker 创建的应用容器,也不妨碍你在其他任何容器运行时上运行这些容器。
这种使用 Docker 的方式并不构成对 Docker 作为一个容器运行时的依赖。
当用了别的容器运行时之后,Docker 命令可能不工作,或者产生意外的输出。
下面是判定你是否依赖于 Docker 的方法。
- 确认没有特权 Pod 执行 Docker 命令(如
docker ps
)、重新启动 Docker
服务(如 systemctl restart docker.service
)或修改 Docker 配置文件
/etc/docker/daemon.json
。
- 检查 Docker 配置文件(如
/etc/docker/daemon.json
)中容器镜像仓库的镜像(mirror)站点设置。
这些配置通常需要针对不同容器运行时来重新设置。
- 检查确保在 Kubernetes 基础设施之外的节点上运行的脚本和应用程序没有执行 Docker 命令。
可能的情况如:
- SSH 到节点排查故障;
- 节点启动脚本;
- 直接安装在节点上的监控和安全代理。
- 检查执行上述特权操作的第三方工具。详细操作请参考
从 dockershim 迁移遥测和安全代理。
- 确认没有对 dockershim 行为的间接依赖。这是一种极端情况,不太可能影响你的应用。
一些工具很可能被配置为使用了 Docker 特性,比如,基于特定指标发警报,
或者在故障排查指令的一个环节中搜索特定的日志信息。
如果你有此类配置的工具,需要在迁移之前,在测试集群上测试这类行为。
Docker 依赖详解
容器运行时是一个软件,用来运行组成 Kubernetes Pod 的容器。
Kubernetes 负责编排和调度 Pod;在每一个节点上,kubelet
使用抽象的容器运行时接口,所以你可以任意选用兼容的容器运行时。
在早期版本中,Kubernetes 提供的兼容性支持一个容器运行时:Docker。
在 Kubernetes 发展历史中,集群运营人员希望采用更多的容器运行时。
于是 CRI 被设计出来满足这类灵活性需要 - 而 kubelet 亦开始支持 CRI。
然而,因为 Docker 在 CRI 规范创建之前就已经存在,Kubernetes 就创建了一个适配器组件 dockershim
。
dockershim 适配器允许 kubelet 与 Docker 交互,就好像 Docker 是一个 CRI 兼容的运行时一样。
你可以阅读博文
Kubernetes 正式支持集成 Containerd。
切换到容器运行时 Containerd 可以消除掉中间环节。
所有相同的容器都可由 Containerd 这类容器运行时来运行。
但是现在,由于直接用容器运行时调度容器,它们对 Docker 是不可见的。
因此,你以前用来检查这些容器的 Docker 工具或漂亮的 UI 都不再可用。
你不能再使用 docker ps
或 docker inspect
命令来获取容器信息。
由于你不能列出容器,因此你不能获取日志、停止容器,甚至不能通过 docker exec
在容器中执行命令。
Note: 如果你在用 Kubernetes 运行工作负载,最好通过 Kubernetes API 停止容器,
而不是通过容器运行时来停止它们
(此建议适用于所有容器运行时,不仅仅是针对 Docker)。
你仍然可以下载镜像,或者用 docker build
命令创建它们。
但用 Docker 创建、下载的镜像,对于容器运行时和 Kubernetes,均不可见。
为了在 Kubernetes 中使用,需要把镜像推送(push)到某镜像仓库。
What's next
4 - 从 dockershim 迁移遥测和安全代理
在 Kubernetes 1.20 版本中,dockershim 被弃用。
在博文弃用 Dockershim 常见问题中,
你大概已经了解到,大多数应用并没有直接通过运行时来托管容器。
但是,仍然有大量的遥测和安全代理依赖 docker 来收集容器元数据、日志和指标。
本文汇总了一些信息和链接:信息用于阐述如何探查这些依赖,链接用于解释如何迁移这些代理去使用通用的工具或其他容器运行。
遥测和安全代理
为了让代理运行在 Kubernetes 集群中,我们有几种办法。
代理既可以直接在节点上运行,也可以作为守护进程运行。
为什么遥测代理依赖于 Docker?
因为历史原因,Kubernetes 建立在 Docker 之上。
Kubernetes 管理网络和调度,Docker 则在具体的节点上定位并操作容器。
所以,你可以从 Kubernetes 取得调度相关的元数据,比如 Pod 名称;从 Docker 取得容器状态信息。
后来,人们开发了更多的运行时来管理容器。
同时一些项目和 Kubernetes 特性也不断涌现,支持跨多个运行时收集容器状态信息。
一些代理和 Docker 工具紧密绑定。此类代理可以这样运行命令,比如用
docker ps
或 docker 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'
Note: 对于 Pod 来说,访问宿主机上的 Docker 还有其他方式。
例如,可以挂载
/var/run
的父目录而非其完整路径
(就像
这个例子)。
上述脚本只检测最常见的使用方式。
检测节点代理对 Docker 的依赖性
在你的集群节点被定制、且在各个节点上均安装了额外的安全和遥测代理的场景下,
一定要和代理的供应商确认:该代理是否依赖于 Docker。
遥测和安全代理的供应商
我们通过
谷歌文档
提供了为各类遥测和安全代理供应商准备的持续更新的迁移指导。
请与供应商联系,获取从 dockershim 迁移的最新说明。