配置Kubernetes从集群内部镜像仓库拉取镜像失败,求解决方案
你已经完成了不少基础配置,但还是碰到了镜像拉取失败的坑,咱们一步步拆解排查:
1. 先从Pod内部验证Registry的可达性
节点上能解析服务名不代表Pod环境也能正常访问,先启动个临时Pod测试:
kubectl run -it --rm --image=busybox:1.34.0 test-dns -- nslookup <registry-service-name>.<namespace>.svc.cluster.local
- 如果解析失败:说明Pod的DNS配置有问题,得回头检查kubelet的
--cluster-dns参数是否正确应用,或者集群DNS组件是否正常运行 - 如果解析成功,再测试端口连通性:
要是连不上,得确认Registry的Service端口映射是否和Deployment容器的监听端口一致,容器本身是否正常运行。kubectl run -it --rm --image=busybox:1.34.0 test-connect -- wget --spider http://<registry-service-name>.<namespace>.svc.cluster.local:5000/v2/_catalog
2. 确认Docker daemon的DNS配置真的生效了
你给Docker加了--dns参数,但得验证配置是否落地:
docker run --rm busybox:1.34.0 nslookup <registry-service-name>.<namespace>.svc.cluster.local
如果解析失败,大概率是修改配置后没重启Docker服务,或者配置文件路径不对(比如Ubuntu是/etc/docker/daemon.json,CentOS可能在/etc/sysconfig/docker)。另外注意:如果集群用containerd当容器运行时,改Docker daemon配置完全没用,得去配置containerd的resolv.conf。
3. 检查Pod的镜像地址是否写全了
一定要在Pod的spec.containers.image里写完整的内部服务FQDN,比如:
image: <registry-service-name>.<namespace>.svc.cluster.local:5000/your-image:tag
只写服务名不带命名空间和集群域名后缀的话,Pod大概率解析不到正确地址。
4. 确认Registry的访问权限配置
如果你的Registry是私有仓库,必须给Pod配置imagePullSecrets才能正常拉取。可以先在节点上用Docker测试:
docker pull <registry-service-name>.<namespace>.svc.cluster.local:5000/your-image:tag
如果提示认证错误,就得创建对应的Secret,然后关联到Pod的ServiceAccount或者直接写在Pod的imagePullSecrets字段里。
5. 检查kubelet的DNS配置是否正确应用
你设置了--cluster-dns参数,但得确认Pod的DNS配置是否正常:
kubectl exec <your-failed-pod-name> -- cat /etc/resolv.conf
正常情况下,里面应该有nameserver <kube-dns-service-ip>这一行,如果没有,说明kubelet的配置没生效,得重启kubelet服务。
6. 排查网络策略或防火墙拦截
如果集群配置了NetworkPolicy,可能不小心阻止了Pod访问Registry的Service;另外节点上的防火墙、iptables规则也可能拦截流量。可以先临时禁用NetworkPolicy测试,或者检查节点的iptables规则是否允许Pod到Registry Service的流量。
内容的提问来源于stack exchange,提问作者Mad Wombat

