K8S集群使用containerd (2.0+) 镜像拉取 + 配置国内镜像加速

1.确认使用  containerd (2.0+) 

判断 K8s 集群由谁负责拉取镜像,核心是确认 kubelet 对接的 CRI 容器运行时—— 镜像拉取动作由该运行时实际执行,和系统安装了哪些容器工具没有必然关系。

Kubernetes 官方推荐的方式,直接读取节点上报的运行时信息

kubectl get nodes -o wide

输出最后一列 CONTAINER-RUNTIME 直接给出结果:

  • containerd://2.0.x → 容器运行时为 containerd,镜像由 containerd 的 CRI 插件直接拉取
  • docker://24.0.x → 容器运行时为 Docker(通过 cri-dockerd 适配层对接 K8s),镜像由 dockerd 拉取
  • cri-o://1.30.x → 容器运行时为 CRI-O,镜像由 CRI-O 拉取
2.配置国内镜像加速

 containerd 较新版本(1.5+)的镜像仓库配置方式,通过目录中的 hosts.toml 文件来定义镜像仓库的镜像和加速器。

每个节点执行:

DaoCloud 镜像加速器(docker.m.daocloud.io)无需认证,DNS 解析正常

mkdir -p /etc/containerd/certs.d/docker.io

cat > /etc/containerd/certs.d/docker.io/hosts.toml <<EOF
server = "https://registry-1.docker.io"

[host."https://docker.m.daocloud.io"]
  capabilities = ["pull", "resolve"]
EOF

为什么这样配置?

2.1. server = "https://registry-1.docker.io"
  • 含义:这是 默认的上游仓库地址

  • 作用:当 containerd 需要拉取 docker.io/library/nginx:latest 时,在没有加速器的情况下会直接访问 https://registry-1.docker.io/v2/library/nginx/manifests/latest

  • 在本配置中:它仅作为“官方来源”的声明,因为下面配置了 host 加速地址,containerd 会优先使用加速器,基本不会直接访问这个 server

2.2. [host."https://docker.m.daocloud.io"]
• 含义:定义一个 镜像加速器主机(mirror host)。
• 地址:https://docker.m.daocloud.io 是 DaoCloud 提供的免费、无需认证的 Docker Hub 镜像加速器。
• 工作机制:containerd 在拉取 docker.io 镜像时,会将请求 重定向到该主机。例如拉取 docker.io/library/nginx:latest,实际访问的是 https://docker.m.daocloud.io/v2/library/nginx/manifests/latest。
• 优先级:host 的优先级高于 server,所以只要配置了 host,containerd 就会先尝试通过加速器拉取。
2.3. capabilities = ["pull", "resolve"]
  • 含义:声明这个主机支持的操作类型:

    • pull:可以拉取镜像(下载层、清单等)。

    • resolve:可以解析镜像名(将镜像标签转换为镜像摘要)。

  • 作用:告诉 containerd 这个主机不仅能下载镜像,还能做镜像存在性校验。

  • 注意:没有包含 push,所以不能向这个主机推送镜像(这是公共加速器,本就不允许推送)。

3.编辑 containerd 配置文件

vim /etc/containerd/config.toml

找到下面这两行(大约 53-54 行):

    [plugins.'io.containerd.cri.v1.images'.registry]
      config_path = ' '

修改为

      config_path = '/etc/containerd/certs.d'

4.重启 containerd 和 kubelet

systemctl restart containerd
systemctl restart kubelet

5.验证配置生效

任意节点执行:

crictl pull docker.io/library/busybox:latest

应该能看到从你配置的 docker.m.daocloud.io 拉取,并成功完成。

6.创建测试 Pod
kubectl run test-busybox --image=docker.io/library/busybox:latest --restart=Never --command -- sleep 3600
kubectl get pod test-busybox -w

 Pod 应该很快变成 Running

完成后,你的集群就拥有了稳定、不依赖认证、无需私有仓库的镜像拉取能力,将来所有来自 docker.io的镜像都会自动通过 DaoCloud 加速。

tips:

消除 crictl 警告(可选)

默认情况下 crictl 会尝试多个 socket,产生报错噪音。

# 临时生效
export CONTAINER_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock
crictl images | grep pause

# 永久生效可写入 ~/.bashrc
echo "export CONTAINER_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock" >> ~/.bashrc

source ~/.bashrc

注:containerd 2.0+ 的变动
containerd 2.0 最大的变化是废弃了旧的 mirrors 配置方式,强制要求使用 config_path(即 hosts.toml 目录)。但 CRI 服务暴露的 socket 路径并没有改变,仍然是 /run/containerd/containerd.sock,因此上述 endpoint 配置完全兼容 2.0+ 版本。

更多推荐