本质是gitlab runner派生的job容器dns配置不当,导致无法解析私有仓库域名;需通过config.toml设置dns_policy与dns_config,或配置coredns转发规则,并验证resolv.conf及corefile。

这个问题本质是 GitLab Runner 在 Kubernetes 执行器模式下,派生的作业容器(job pod)继承了错误或不完整的 DNS 配置,导致无法解析集群内或 VPC 内的私有镜像仓库(如 harbor.yourcompany.local、registry.internal 或自建 Nexus/Artifactory 域名)。关键不在 Runner 本身,而在于它启动的每个 job 容器的 dnsPolicy 和 dnsConfig 设置是否适配你的网络环境。
确认 job 容器实际使用的 DNS 策略
GitLab Runner 的 Kubernetes 执行器会为每个 CI 任务创建一个独立 Pod。该 Pod 的 DNS 行为由其自身的 dnsPolicy 控制,与 Runner Pod 无关。默认是 ClusterFirst,但若私有仓库域名不属于 .svc.cluster.local 或集群 DNS 未配置转发规则,就会失败。
- 进入一个失败的 job 容器(或用
kubectl describe pod <job-pod-name></job-pod-name>),检查dnsPolicy字段是否为ClusterFirst(这是常规起点) - 运行
kubectl exec -it <job-pod> -- cat /etc/resolv.conf</job-pod>,观察 nameserver 是否指向 CoreDNS IP(如10.96.0.10),search 域是否包含你期望的内部后缀(如your-namespace.svc.cluster.local svc.cluster.local your-domain.internal) - 如果 nameserver 是空的、指向
127.0.0.11(Docker Desktop 内置 DNS)或公网地址(如8.8.8.8),说明配置被覆盖或继承异常
在 Runner 配置中显式设置 job pod 的 DNS 参数
GitLab Runner 的 config.toml 中,Kubernetes 执行器支持通过 [[runners.kubernetes]] 下的 dns_policy 和 dns_config 字段,直接控制派生 job pod 的 DNS 行为。
- 将
dns_policy = "ClusterFirstWithHostNet"改为更可控的"ClusterFirst"(除非你明确需要 hostNetwork) - 添加
dns_config显式指定内部 DNS 服务器和搜索域:
[[runners.kubernetes]]
dns_policy = "ClusterFirst"
dns_config = [
{ name = "nameservers", value = ["10.96.0.10", "172.16.10.5"] },
{ name = "searches", value = ["your-namespace.svc.cluster.local", "svc.cluster.local", "your-domain.internal"] }
]
- 其中
172.16.10.5应替换为你私有镜像仓库所在网络的真实 DNS 服务器(如企业内网 DNS 或 VPC 内自建 DNS) - 确保该 DNS 服务器能递归解析
your-domain.internal并正确返回私有仓库的 A 记录
验证私有仓库域名是否被 CoreDNS 正确转发
即使 job 容器用了 ClusterFirst,若 CoreDNS 没配置对私有域名的转发,依然会超时。需检查 CoreDNS ConfigMap 是否包含对应 stanza:
- 运行
kubectl -n kube-system get cm coredns -o yaml - 在
Corefile区域中,确认存在类似以下转发规则:
<pre class="brush:php;toolbar:false;">your-domain.internal:53 {
forward . 172.16.10.5
cache 30
}
- 修改后执行
kubectl -n kube-system rollout restart deploy coredns 重启生效 - 用临时调试 pod 测试:
kubectl run -it --rm debug --image=nicolaka/netshoot -- nslookup harbor.yourcompany.local
绕过 DNS:在 job 中使用 IP + hosts 注入(临时应急)
若短期无法调整 DNS 配置,可在 .gitlab-ci.yml 中为关键 job 注入 hosts 映射:
- 在 job 的
before_script中添加:
before_script: - echo "172.16.20.100 harbor.yourcompany.local" >> /etc/hosts
- 注意:该方式仅对当前 job 容器生效;IP 必须是私有仓库服务的稳定 ClusterIP 或 NodePort 后端 IP;不适用于 TLS 证书校验(因 SNI 仍发域名)
- 更稳妥的做法是配合
image:使用完整 registry 地址(如harbor.yourcompany.local/mygroup/myapp:latest),避免构建阶段再解析











