随着Kubernetes社区正式移除了对内置的dockershim的支持,将K8s集群的容器运行时(CRI)从Docker切换到原生Containerd已成为主流趋势。虽然Containerd是Docker的核心组件,但这种切换并非无缝。本文将聚焦于迁移过程中最常见的几个“坑”以及如何利用crictl进行有效的故障排除。
陷阱一:熟悉的docker命令失效
对于运维人员和开发人员来说,最大的转变是失去了直接使用docker ps、docker logs等命令来检查K8s容器的能力。因为当Kubelet直接与Containerd通信时,标准的Docker守护进程不再管理K8s创建的Pod。
解决方案:拥抱 crictl
crictl是Kubernetes CRI兼容性工具,它是用于调试K8s节点上容器和镜像状态的标准工具。你需要学习将常用的docker命令映射到crictl命令上。
| Docker 命令 | crictl 对应命令 | 作用 |
|---|---|---|
| docker ps | crictl ps | 列出运行中的容器 |
| docker images | crictl images | 列出本地镜像 |
| docker logs |
crictl logs |
查看容器日志 |
| docker exec -it |
crictl exec -it |
进入容器内部 |
实用示例:查找正在运行的K8s容器
# 查找所有正在运行的Pod
sudo crictl pods
# 查找所有运行中的容器
sudo crictl ps
# 查找特定名称的容器ID,并查看其日志
CONTAINER_ID=$(sudo crictl ps | grep 'my-app' | awk '{print $1}')
sudo crictl logs $CONTAINER_ID
陷阱二:Kubelet配置路径变更
Kubelet需要知道在哪里找到容器运行时的Unix套接字(Socket)。从Docker切换到Containerd时,这个路径是必须更改的。
解决方案:更新Kubelet配置
如果你的Kubelet配置是通过配置文件(如/etc/kubernetes/kubelet.conf或类似的配置管理工具)管理的,你需要确保–container-runtime-endpoint参数指向正确的Containerd Socket路径。
旧配置 (Docker/dockershim):
KUBELET_ARGS="\n --container-runtime=remote\n --container-runtime-endpoint=unix:///var/run/dockershim.sock"
新配置 (Containerd):
KUBELET_ARGS="\n --container-runtime=remote\n --container-runtime-endpoint=unix:///run/containerd/containerd.sock"
注意: 如果你在使用kubeadm初始化集群,确保在初始化时传递正确的CRI Socket路径,kubeadm会自动进行配置。
陷阱三:镜像拉取故障(尤其是私有仓库)
Containerd和Docker在管理镜像凭证方面有细微差别。虽然K8s的imagePullSecrets机制适用于两者,但如果节点级别的配置(例如/etc/docker/daemon.json中的Registry Mirrors或不标准的认证文件)存在,迁移后可能会失效。
解决方案:使用Containerd标准配置
对于私有仓库认证,需要确保Containerd能够访问到认证信息。Containerd使用其配置文件(通常在/etc/containerd/config.toml)或特定的路径来管理私有仓库配置。
配置认证信息示例 (适用于私有仓库):
你需要将认证信息放在与Containerd配置兼容的位置。如果使用标准的CRI配置,你可以通过配置hosts.toml文件来定义特定registry的认证信息。
确保所有K8s节点上的Containerd服务已正确安装和启动:
# 检查Containerd服务状态
systemctl status containerd
# 重启Containerd服务以加载新配置
systemctl restart containerd
陷阱四:依赖于Docker Socket的第三方工具
一些遗留的安全扫描工具、监控代理或CI/CD构建工具可能硬编码依赖于/var/run/docker.sock的存在来执行操作(如构建镜像、扫描宿主机容器)。当切换到Containerd后,这些工具会立即停止工作。
解决方案:切换依赖或使用兼容层
- 更新工具: 如果可能,更新或替换这些工具,使其通过标准的CRI接口(crictl)或直接通过Kubernetes API进行交互。许多现代的安全扫描工具和监控代理已支持Containerd。
- 构建兼容层: 对于无法立即更新的工具,可以考虑使用像****cri-dockerd****这样的兼容层(它是社区创建的,用于在Kubelet和Containerd之间模拟dockershim行为的垫片),但请注意,引入兼容层会增加复杂性。
总之,向Containerd的迁移是K8s生态系统成熟的标志。关键在于理解底层工具链的转变,并熟练掌握crictl这一新的容器调试利器。
汤不热吧