You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes拉取私有镜像不读取服务器/etc/hosts问题求助

问题背景

在Ubuntu Server 22.04上用kubeadm搭建3节点Kubernetes集群(Flannel网络插件),部署Deployment时无法从内部GitLab私有镜像仓库拉取镜像。节点/etc/hosts已配置192.168.1.30 registry.example.com,服务器命令行docker pull可正常拉取,但Kubernetes部署时解析到公网IP导致超时。尝试过hostAliases(仅Pod内部生效)、修改CoreDNS配置均无效。

Deployment配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: platform-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: platform-service
  template:
    metadata:
      labels:
        app: platform-service
    spec:
      containers:
        - name: platform-service
          image: registry.example.com/demo/platform-service:latest

报错信息:

Failed to pull image "registry.example.com/demo/platform-service:latest": 
rpc error: code = Unknown desc = failed to pull and unpack image 
"registry.example.com/deni/platform-service:latest": failed to resolve reference 
"registry.example.com/demo/platform-service:latest": failed to do request: Head 
"https://registry.example.com/v2/demo/platform-service/manifests/latest": dial tcp 
xxx.xxx.xxx.xxx:443: i/o timeout
问题根源

Kubernetes拉取镜像由kubelet调用容器运行时(kubeadm默认用containerd)执行,这个阶段不依赖Pod的CoreDNS配置,且containerd的DNS解析逻辑不会直接读取节点/etc/hosts。而docker pull能成功是因为Docker的解析逻辑与containerd不同。

可行解决方法

方法一:配置containerd私有仓库映射(推荐)

直接给containerd添加私有仓库的IP映射,确保拉取时解析到内部地址:

  1. 编辑每个K8s节点的containerd配置文件:
    sudo nano /etc/containerd/config.toml
    
  2. 找到或新增[plugins."io.containerd.grpc.v1.cri".registry]区块,添加以下配置:
    [plugins."io.containerd.grpc.v1.cri".registry.configs]
      [plugins."io.containerd.grpc.v1.cri".registry.configs."registry.example.com".hosts]
        [plugins."io.containerd.grpc.v1.cri".registry.configs."registry.example.com".hosts."http://192.168.1.30"]
          capabilities = ["pull"]
          skip_verify = true # 私有仓库用自签证书时需添加,可信证书可删除此行
    

    提示:如果仓库用HTTPS且证书可信,将http://改为https://并移除skip_verify。

  3. 重启containerd服务:
    sudo systemctl restart containerd
    
  4. 删除失败Pod,触发重新拉取:
    kubectl delete pod -l app=platform-service
    

方法二:用dnsmasq配置节点本地DNS解析

通过本地DNS服务强制私有域名解析到内部IP,让containerd继承正确解析:

  1. 安装dnsmasq:
    sudo apt install dnsmasq -y
    
  2. 添加私有域名解析规则:
    echo "address=/registry.example.com/192.168.1.30" | sudo tee /etc/dnsmasq.d/registry.conf
    
  3. 修改节点resolv.conf,优先使用本地dnsmasq:
    sudo sed -i '1s/^/nameserver 127.0.0.1\n/' /etc/resolv.conf
    
  4. 重启服务:
    sudo systemctl restart dnsmasq
    sudo systemctl restart containerd
    
  5. 重新创建Pod验证结果。

方法三:临时方案——直接使用IP拉取镜像

若上述方法暂时无法生效,可直接用仓库IP替换域名,同时配置拉取凭证(如需认证):

  1. 修改Deployment YAML:
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: platform-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: platform-service
      template:
        metadata:
          labels:
            app: platform-service
        spec:
          containers:
            - name: platform-service
              image: 192.168.1.30/demo/platform-service:latest
          imagePullSecrets: # 仓库需认证时添加此部分
            - name: registry-secret
    
  2. 创建镜像拉取凭证(如需):
    kubectl create secret docker-registry registry-secret \
      --docker-server=192.168.1.30 \
      --docker-username=你的用户名 \
      --docker-password=你的密码
    
  3. 重新部署:
    kubectl apply -f deployment.yaml
    

内容的提问来源于stack exchange,提问作者Aaron Murray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 23:36:24