Kubernetes 国内节点拉取 Docker Hub 超时:containerd 镜像加速配置
·
一、问题现象
Kubernetes Pod 出现:
ImagePullBackOff
ErrImagePull
ContainerCreating
查看事件:
kubectl describe pod POD名称 -n 命名空间
典型报错:
Head "https://registry-1.docker.io/v2/...":
dial tcp xxx.xxx.xxx.xxx:443: i/o timeout
服务器能正常访问国内网络,但 Docker Hub 超时,说明需要为 containerd 配置镜像加速。
二、确认运行时类型
查看节点运行时:
kubectl get nodes -o wide
查看 kubelet:
ps -ef | grep kubelet | grep -v grep
如果看到:
--container-runtime-endpoint=unix:///run/containerd/containerd.sock
并且服务为:
systemctl status containerd
说明当前是:
kubeadm + kubelet + containerd
配置文件为:
/etc/containerd/config.toml
不要配置:
/etc/rancher/rke2/registries.yaml
后者只适用于 RKE2。
三、备份 containerd 配置
在每个可能调度业务 Pod 的节点执行:
sudo cp -a /etc/containerd/config.toml \
/etc/containerd/config.toml.bak.$(date +%Y%m%d_%H%M%S)
四、配置 containerd 镜像目录
编辑:
sudo vim /etc/containerd/config.toml
删除旧的:
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
增加:
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"
核心配置示例:
version = 2
root = "/var/lib/containerd"
state = "/run/containerd"
[grpc]
address = "/run/containerd/containerd.sock"
[plugins]
[plugins."io.containerd.grpc.v1.cri"]
sandbox_image = "kubesphere/pause:3.9"
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"
max_conf_num = 1
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
五、配置 Docker Hub 加速
创建目录:
sudo mkdir -p /etc/containerd/certs.d/docker.io
创建文件:
sudo tee /etc/containerd/certs.d/docker.io/hosts.toml >/dev/null <<'EOF'
server = "https://dockerproxy.net"
[host."https://dockerproxy.net"]
capabilities = ["pull", "resolve"]
dial_timeout = "15s"
EOF
这里直接把 dockerproxy.net 设置为服务端,避免失败后再次回退到 Docker Hub。
六、配置私有镜像仓库
私有仓库地址:
172.17.0.169:30050
创建目录:
sudo mkdir -p '/etc/containerd/certs.d/172.17.0.169:30050'
创建配置:
sudo tee '/etc/containerd/certs.d/172.17.0.169:30050/hosts.toml' >/dev/null <<'EOF'
server = "http://172.17.0.169:30050"
[host."http://172.17.0.169:30050"]
capabilities = ["pull", "resolve", "push"]
EOF
私有仓库使用 HTTP 时,必须明确写 http://。
七、重启 containerd
sudo systemctl restart containerd
sudo systemctl status containerd --no-pager -l
检查日志:
sudo journalctl -u containerd -n 100 --no-pager
生产环境可先禁止调度:
kubectl cordon node1
重启完成后恢复:
kubectl uncordon node1
八、验证镜像加速
先测试基础镜像:
sudo crictl pull docker.io/library/busybox:1.36
sudo crictl pull docker.io/library/redis:7.2
成功示例:
Image is up to date for sha256:...
查看镜像:
sudo crictl images | grep -E 'busybox|redis'
只要 docker.io/library/redis:7.2 可以拉取,说明 containerd 镜像加速已经生效。
九、常见错误判断
网络问题
i/o timeout
DeadlineExceeded
说明仓库访问超时。
镜像不存在
NotFound
manifest unknown
说明镜像路径或标签错误。
权限问题
403 Forbidden
pull access denied
insufficient_scope
说明仓库需要认证,或代理不支持该镜像。
DNS 问题
Could not resolve host
no such host
说明节点 DNS 异常。
十、几个常见坑
1. 阿里云 ACR 地址不是 Docker Hub 加速器
下面配置通常无效:
endpoint = ["https://registry.cn-hangzhou.aliyuncs.com"]
它只是阿里云镜像仓库地址,不会自动代理所有 Docker Hub 镜像。
2. 必须在 Pod 所在节点测试
查看 Pod 调度节点:
kubectl get pod -A -o wide
Pod 在 node1,就必须在 node1 执行:
sudo crictl pull 镜像地址
3. Helm 的 APP VERSION 不等于镜像标签
例如:
APP VERSION: 8.8.1
不代表一定存在:
bitnami/redis:8.8.1
返回 NotFound 时,应检查实际镜像标签,而不是继续排查网络。
4. Bitnami Chart 不能直接换官方 Redis 镜像
Bitnami Chart 依赖:
/opt/bitnami/scripts/
不能直接把:
bitnami/redis
替换成:
library/redis
否则镜像能拉取,容器也可能无法启动。
十一、生产环境建议
公共镜像代理只适合临时拉取。
生产环境应将 Redis、RabbitMQ、Kafka 等镜像同步到内部仓库:
172.17.0.169:30050
业务 YAML 统一使用:
image: 172.17.0.169:30050/middleware/redis:固定版本
最终推荐架构:
公共镜像仓库
↓
私有 Registry / Harbor
↓
Kubernetes 节点
这样可以避免 Docker Hub 超时、代理限流、镜像下架和标签失效。
更多推荐
所有评论(0)