
1. 为什么kubeadm config images pull会失败很多朋友第一次用kubeadm搭建Kubernetes集群时都会卡在kubeadm config images pull这一步。这个命令的作用是拉取Kubernetes运行所需的核心镜像包括API Server、Controller Manager这些关键组件。但在国内网络环境下你会发现命令执行后要么卡住不动要么直接报连接超时。这其实是因为kubeadm默认会从k8s.gcr.io这个谷歌的容器镜像仓库拉取镜像。由于众所周知的原因国内服务器直接访问谷歌服务会遇到网络问题。我刚开始接触Kubernetes时就因为这个坑折腾了大半天后来才发现原来有更简单的解决方案。除了主镜像仓库kubeadm还可能尝试从gcr.io、quay.io这些同样受限的仓库拉取镜像。这些域名在国内网络环境下基本都无法稳定访问。更让人头疼的是不同地区的网络情况还不一样有时候命令会卡住几分钟才报错很容易让人误以为是服务器性能问题。2. 如何诊断镜像拉取问题2.1 查看所需镜像列表遇到问题先别急着解决搞清楚状况更重要。首先我们可以用以下命令查看kubeadm需要哪些镜像kubeadm config images list这个命令会输出类似这样的结果k8s.gcr.io/kube-apiserver:v1.23.8 k8s.gcr.io/kube-controller-manager:v1.23.8 k8s.gcr.io/kube-scheduler:v1.23.8 k8s.gcr.io/kube-proxy:v1.23.8 k8s.gcr.io/pause:3.6 k8s.gcr.io/etcd:3.5.1-0 k8s.gcr.io/coredns/coredns:v1.8.6建议在执行解决方案前先运行这个命令因为不同版本的Kubernetes需要的镜像版本可能不同。我就遇到过同事直接照搬网上的解决方案结果因为版本不匹配导致集群初始化失败的情况。2.2 测试镜像仓库连通性知道需要哪些镜像后可以手动测试下这些仓库的连通性。比如用curl测试k8s.gcr.iocurl -v https://k8s.gcr.io如果看到连接超时或者直接被拒绝那就确认是网络问题了。有些企业内网会有更复杂的代理设置这时候还需要检查docker的代理配置是否正确。3. 国内镜像源解决方案3.1 使用阿里云镜像仓库国内最方便的替代方案是使用阿里云的镜像仓库。阿里云同步了所有Kubernetes官方镜像速度非常快。具体操作是先把镜像从阿里云拉下来然后再重命名为kubeadm需要的格式。以kube-apiserver为例原本的镜像是k8s.gcr.io/kube-apiserver:v1.23.8我们可以这样拉取docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.23.8其他组件的拉取方式类似只需要替换镜像名称即可。这里有个小细节要注意coredns的镜像路径有点特殊阿里云上是直接放在顶级目录下的。3.2 其他国内镜像源除了阿里云国内还有其他可用的镜像源腾讯云镜像仓库mirror.ccs.tencentyun.com华为云镜像仓库swr.cn-east-2.myhuaweicloud.com中科大镜像源docker.mirrors.ustc.edu.cn这些镜像源的使用方法大同小异都是先把镜像拉取到本地然后重命名。选择哪个镜像源主要看你的服务器所在位置选同区域的镜像源速度会更快。4. 镜像重命名完整流程4.1 拉取所有所需镜像根据之前kubeadm config images list的输出我们需要拉取以下镜像docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.23.8 docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.23.8 docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.23.8 docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.23.8 docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6 docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.1-0 docker pull coredns/coredns:1.8.6注意最后一个coredns的拉取命令和其他不太一样没有阿里云的前缀。这是因为它已经在docker官方仓库中存在可以直接拉取。4.2 重命名镜像标签拉取完成后需要用docker tag命令给这些镜像打上kubeadm需要的标签docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.23.8 k8s.gcr.io/kube-apiserver:v1.23.8 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.23.8 k8s.gcr.io/kube-controller-manager:v1.23.8 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.23.8 k8s.gcr.io/kube-scheduler:v1.23.8 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.23.8 k8s.gcr.io/kube-proxy:v1.23.8 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6 k8s.gcr.io/pause:3.6 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.1-0 k8s.gcr.io/etcd:3.5.1-0 docker tag coredns/coredns:1.8.6 k8s.gcr.io/coredns/coredns:v1.8.6这里最容易出错的是版本号的格式。比如coredns的版本号在阿里云上是1.8.6但kubeadm需要的是v1.8.6前面多了个v。如果标签打错了kubeadm init时还是会报镜像找不到的错误。5. 验证与后续操作5.1 检查镜像是否正确全部重命名完成后建议用docker images命令检查一下docker images | grep k8s.gcr.io应该能看到所有必须的镜像都已经就位且版本号完全匹配。确认无误后就可以放心地运行kubeadm init了。5.2 一键化脚本如果你经常需要搭建Kubernetes集群可以把这些步骤写成一个脚本。下面是我在用的一个简单示例#!/bin/bash K8S_VERSIONv1.23.8 COREDNS_VERSION1.8.6 PAUSE_VERSION3.6 ETCD_VERSION3.5.1-0 images( kube-apiserver:${K8S_VERSION} kube-controller-manager:${K8S_VERSION} kube-scheduler:${K8S_VERSION} kube-proxy:${K8S_VERSION} pause:${PAUSE_VERSION} etcd:${ETCD_VERSION} ) for image in ${images[]}; do docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/${image} docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/${image} k8s.gcr.io/${image} done docker pull coredns/coredns:${COREDNS_VERSION} docker tag coredns/coredns:${COREDNS_VERSION} k8s.gcr.io/coredns/coredns:v${COREDNS_VERSION}把这个脚本保存为pull-k8s-images.sh以后每次搭建新集群时运行一下就行了省时省力。6. 其他注意事项6.1 版本兼容性问题Kubernetes的不同版本对组件版本有严格要求。比如v1.23.8的kube-apiserver必须搭配v1.23.8的kube-controller-manager不能混用。使用国内镜像源时一定要确认镜像版本和你要安装的Kubernetes版本完全匹配。6.2 私有仓库方案对于企业环境更稳妥的做法是搭建私有镜像仓库把所有需要的镜像都同步到内网。这样不仅解决了网络问题还能提高后续部署的速度。Harbor是一个不错的私有仓库解决方案支持镜像复制和同步功能。6.3 安全考量从第三方镜像源拉取镜像时理论上存在被篡改的风险。对于安全性要求高的场景建议拉取镜像后校验其sha256摘要确保与官方镜像完全一致。Kubernetes官方博客会发布每个版本组件的标准摘要值可以作为比对的依据。