问题背景
由于网络限制,k8s.gcr.io 和 registry.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.io 或 registry.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 init 或 kubeadm 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 批量迁移
当需要迁移大量镜像时,用 skopeo 或 crane 批量复制:
# 安装 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 | 容器镜像跨仓库复制工具 |