问题背景

由于网络限制,k8s.gcr.ioregistry.k8s.io 在国内无法直接访问。在部署 Kubernetes 组件或安装 CSI、CNI 等插件时,经常会遇到:

Error response from daemon: manifest for k8s.gcr.io/xxx not found: manifest unknown
# 或
Failed to pull image "registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2"

方案一:域名替换(最简单,手动拉取时用)

k8s.gcr.ioregistry.k8s.io 替换为国内可用的镜像站:

原始地址 替换为
k8s.gcr.io/xxx registry.lank8s.cn/xxx
registry.k8s.io/xxx registry.lank8s.cn/xxx
k8s.gcr.io/xxx m.daocloud.io/xxx
registry.k8s.io/xxx m.daocloud.io/xxx

示例:NFS Subdir External Provisioner

# 原始命令(会失败)
docker pull registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2

# 替换为 lank8s.cn 镜像
docker pull registry.lank8s.cn/sig-storage/nfs-subdir-external-provisioner:v4.0.2

# 或使用 DaoCloud 镜像
docker pull m.daocloud.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2

# 拉取后重新打标签
docker tag registry.lank8s.cn/sig-storage/nfs-subdir-external-provisioner:v4.0.2 \
           registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2

常用镜像站对比

镜像站 同步速度 稳定性 备注
registry.lank8s.cn ⚡ 快 ✅ 稳定 个人维护,长期可用
m.daocloud.io ⚡ 快 ✅ 稳定 DaoCloud 官方维护
gcr.mirrors.ustc.edu.cn 🐢 较慢 ⚠️ 有时断 中科大源
registry.aliyuncs.com/google_containers ⚡ 快 ✅ 稳定 阿里云,需拼接路径

方案二:配置 Docker / containerd 镜像加速(推荐,一劳永逸)

Docker Engine 配置

编辑 /etc/docker/daemon.json

{
  "registry-mirrors": [
    "https://registry.lank8s.cn",
    "https://m.daocloud.io"
  ],
  "insecure-registries": []
}

重启 Docker:

systemctl daemon-reload && systemctl restart docker

之后 docker pull registry.k8s.io/xxx 会自动走镜像站。

containerd 配置(Kubernetes 1.24+ 默认运行时)

编辑 /etc/containerd/config.toml,找到 [plugins."io.containerd.grpc.v1.cri".registry.mirrors] 段:

[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]
    endpoint = ["https://registry.lank8s.cn", "https://m.daocloud.io"]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
    endpoint = ["https://registry.lank8s.cn", "https://m.daocloud.io"]

重启 containerd:

systemctl restart containerd

方案三:kubeadm 初始化时指定镜像仓库

使用 kubeadm initkubeadm config 时,通过 --image-repository 指定国内镜像:

# 使用阿里云镜像
kubeadm init \
  --image-repository=registry.aliyuncs.com/google_containers \
  --kubernetes-version=v1.30.0 \
  --pod-network-cidr=10.244.0.0/16

# 或使用 lank8s
kubeadm init \
  --image-repository=registry.lank8s.cn \
  --kubernetes-version=v1.30.0

或者在 kubeadm 配置文件中指定:

apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
imageRepository: registry.aliyuncs.com/google_containers
kubernetesVersion: v1.30.0

方案四:私有仓库中转(企业级)

在企业内网搭建自己的镜像代理,避免依赖第三方镜像站:

使用 Harbor 或 Docker Registry 做 Pull-Through Cache

# 运行 Registry 作为 k8s.gcr.io 的代理缓存
docker run -d --name registry-cache \
  -p 5000:5000 \
  -e REGISTRY_PROXY_REMOTEURL=https://registry.k8s.io \
  -v /data/registry:/var/lib/registry \
  registry:2

之后所有节点将 registry.k8s.io 指向内网 registry.internal:5000

# containerd 配置
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]
  endpoint = ["http://registry.internal:5000"]

优势: 不受第三方镜像站可用性影响,镜像缓存到内网,重复拉取速度极快。


方案五:使用 Skopeo / Crane 批量迁移

当需要迁移大量镜像时,用 skopeocrane 批量复制:

# 安装 skopeo
apt install skopeo

# 从镜像站复制到私有仓库
skopeo copy \
  docker://registry.lank8s.cn/sig-storage/nfs-subdir-external-provisioner:v4.0.2 \
  docker://registry.internal:5000/sig-storage/nfs-subdir-external-provisioner:v4.0.2

总结:不同场景推荐方案

场景 推荐方案
临时拉取一两个镜像 方案一:手动域名替换
个人开发环境 / 单机 方案二:配置 Docker/containerd 镜像加速
kubeadm 初始化集群 方案三:--image-repository
生产环境 / 企业内网 方案四:私有 Registry Pull-Through Cache
批量迁移大量镜像 方案五:Skopeo / Crane

Professional English Terms

Term Meaning
Image Registry Mirror 镜像仓库加速/代理
Pull-Through Cache 透传缓存代理(拉取时自动缓存到本地)
Container Runtime 容器运行时(Docker / containerd / CRI-O)
Image Repository 镜像仓库地址
Skopeo / Crane 容器镜像跨仓库复制工具