K8s containerd 镜像源配置:用 1ms-helper 处理 ImagePullBackOff

环境和问题现象

这次记录一个 K8s 新节点初始化时遇到的镜像拉取问题。节点已经是 Ready,Pod 也被调度到了目标 Worker,但容器一直拉不起来:

text 复制代码
Failed to pull image
context deadline exceeded
Back-off pulling image
ImagePullBackOff

这类问题通常不是业务 YAML 的第一层错误,而是目标节点上的 containerd 没有正确配置镜像源。K8s 里镜像最终是在节点运行时里拉取,所以排查要回到节点上的 containerd。

本文只写 K8s / containerd 配置,不展开其它运行时。

参考文档:

1. 先确认节点和 containerd 版本

在集群侧看节点:

bash 复制代码
kubectl get node -owide
kubectl get pod -A -owide | grep -E 'ImagePullBackOff|ErrImagePull|ContainerCreating'
kubectl get events -A --sort-by=.lastTimestamp

进入目标节点后看 containerd:

bash 复制代码
containerd --version
systemctl status containerd

containerd 版本很关键:

版本 常见配置方式
< 1.5 /etc/containerd/config.toml 里配置 registry.mirrors
>= 1.5 /etc/containerd/config.toml 指向 config_path,各 registry 使用 hosts.toml

2. 用 1ms-helper 走标准化配置

先安装配置助手:

bash 复制代码
curl -sSL https://static.1ms.run/1ms-helper/install.sh | bash

然后在每个需要拉镜像的 K8s 节点上执行:

bash 复制代码
sudo 1ms-helper config:k8s

这一步会做几件事:

  • 检测 Kubernetes 集群和节点角色。
  • 检测 containerd 版本。
  • 按新版/旧版 containerd 生成对应配置。
  • 优先处理 K8s 核心镜像仓库。
  • 必要时重启 containerd 和 kubelet。

多节点集群不能只在控制面节点跑一次。Pod 被调度到哪台节点,镜像就在哪台节点上拉取。

3. containerd 1.5 及以后配置片段

确认 /etc/containerd/config.toml 里有 config_path

toml 复制代码
[plugins."io.containerd.grpc.v1.cri".registry]
  config_path = "/etc/containerd/certs.d"

创建目录:

bash 复制代码
BASE=/etc/containerd/certs.d
for r in docker.io ghcr.io gcr.io registry.k8s.io nvcr.io quay.io; do
  mkdir -p $BASE/$r
done

registry.k8s.io

toml 复制代码
# /etc/containerd/certs.d/registry.k8s.io/hosts.toml
server = "https://registry.k8s.io"

[host."https://k8s.1ms.run"]
  capabilities = ["pull", "resolve"]

docker.io

toml 复制代码
# /etc/containerd/certs.d/docker.io/hosts.toml
server = "https://registry-1.docker.io"

[host."https://docker.1ms.run"]
  capabilities = ["pull", "resolve"]

ghcr.io

toml 复制代码
# /etc/containerd/certs.d/ghcr.io/hosts.toml
server = "https://ghcr.io"

[host."https://ghcr.1ms.run"]
  capabilities = ["pull", "resolve"]

quay.io

toml 复制代码
# /etc/containerd/certs.d/quay.io/hosts.toml
server = "https://quay.io"

[host."https://quay.1ms.run"]
  capabilities = ["pull", "resolve"]

配置后重启:

bash 复制代码
systemctl restart containerd
systemctl status containerd

4. containerd 1.5 之前配置片段

旧版本常见写法是在 /etc/containerd/config.toml 中写 mirrors:

toml 复制代码
[plugins."io.containerd.grpc.v1.cri".registry]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
      endpoint = ["https://docker.1ms.run"]

    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
      endpoint = ["https://k8s.1ms.run"]

    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."gcr.io"]
      endpoint = ["https://gcr.1ms.run"]

    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."ghcr.io"]
      endpoint = ["https://ghcr.1ms.run"]

重启服务:

bash 复制代码
systemctl restart containerd
systemctl status containerd

5. 验证命令

crictl pull 直接从节点运行时验证,不要只看 kubectl apply 的结果:

bash 复制代码
crictl pull docker.io/library/redis:7-alpine
crictl pull registry.k8s.io/pause:3.10
crictl pull ghcr.io/containerd/nerdctl:latest
crictl pull nvcr.io/nvidia/cuda:12.4.1-runtime-ubuntu22.04

再回到集群侧看事件:

bash 复制代码
kubectl get pod -A | grep -E 'ImagePullBackOff|ErrImagePull'
kubectl get events -A --sort-by=.lastTimestamp

如果 crictl pull 可以成功,但业务 Pod 仍然失败,再看:

  • 镜像名称和 tag 是否真实存在。
  • namespace 下的 ImagePullSecret 是否正确。
  • ServiceAccount 是否挂了正确的 secret。
  • 业务 YAML 里的 image 地址是否写错。
  • 节点 DNS 是否异常,可以用 1ms-helper check:dns 做初步检查。

总结

K8s 的镜像拉取问题不要只盯 Deployment YAML。标准 K8s + containerd 场景下,镜像源配置主要在节点运行时。

我的处理顺序是:

  1. 查事件,确认是否为 ImagePullBackOff
  2. 到目标节点确认 containerd 版本。
  3. 1ms-helper config:k8s 标准化配置。
  4. 看新版 hosts.toml 或旧版 mirrors 是否正确。
  5. crictl pull 做多源验证。

这套流程适合写进 K8s 新节点初始化清单,后面扩容 Worker 节点时能少踩很多配置漂移的问题。

相关推荐
pigs20182 小时前
Docker容器中Kingbase数据库授权到期更换解决方案
数据库·docker·容器
人工智能培训3 小时前
AI人工智能未来发展趋势
人工智能·深度学习·机器学习·docker·容器
成为你的宁宁4 小时前
【基于 Docker-compose 部署 Prometheus 监控系统实战教程 】
docker·容器·prometheus
米高梅狮子4 小时前
03.OpenStack使用
linux·前端·云原生·容器·架构·kubernetes·openstack
ABILI .5 小时前
Linux上安装部署k8s单机版(minikube)
linux·运维·kubernetes
STDD5 小时前
KEDA:Kubernetes 事件驱动自动扩缩容
云原生·容器·kubernetes
weixin_408318045 小时前
企业级直播平台技术选型与成本分析:三种方案架构对比
微服务·云原生·架构
珂玥c5 小时前
k8s集群高可用的碎碎念
云原生·容器·kubernetes
xiaogg36785 小时前
k8s 部署yaml文件和Dockerfile文件配置
java·docker·kubernetes