Kubernetes+Docker-in-Docker+自定义网络下docker push至gcr.io失败
解决Drone + Dind在Kubernetes环境下推送镜像至GCR失败的问题
我之前在K8s集群里用Drone搭配dind边车做CI/CD时,碰到过几乎一模一样的镜像推送失败问题,给你几个实际可行的排查和解决方向:
1. 调整Dind的网络子网,避免和K8s Pod网络冲突
Drone启动dind后,Docker默认会创建自己的bridge网络,如果这个子网和你的K8s集群Pod子网重叠,就会导致路由异常,无法正常访问外部的gcr.io。
解决办法是在Drone pipeline的dind服务配置里,指定一个和K8s Pod子网不重叠的网段:
services: - name: docker image: docker:dind privileged: true environment: - DOCKER_DRIVER=overlay2 # 这里选一个和你K8s Pod子网不冲突的网段,比如K8s默认用10.244.0.0/16的话,就用172.18.0.1/16 - DOCKER_OPTS=--bip=172.18.0.1/16
2. 强制指定DNS服务器,确保GCR域名解析正常
有时候dind容器会继承K8s Pod的DNS配置,但可能存在解析异常的情况。可以手动给Docker指定公共DNS服务器,保证能正确解析us.gcr.io:
services: - name: docker image: docker:dind privileged: true environment: - DOCKER_DRIVER=overlay2 - DOCKER_OPTS=--bip=172.18.0.1/16 --dns=8.8.8.8 --dns=8.8.4.4
3. 确认GCR的认证配置正确
推送失败也可能是认证环节出了问题,哪怕你能正常构建镜像,也要确保Drone已经正确配置了GCR的凭据:
- 如果用Drone官方的Docker插件,配置应该类似这样:
steps: - name: push-image image: plugins/docker settings: repo: us.gcr.io/your-project-id/your-image-name tags: latest username: _json_key password: from_secret: GCR_JSON_KEY registry: us.gcr.io
- 如果是手动执行
docker push,要先完成登录操作:
echo "$GCR_JSON_KEY" | docker login -u _json_key --password-stdin us.gcr.io
4. 检查K8s的网络策略限制
确保运行Drone Runner的Pod所在的Namespace,没有限制出站访问的网络策略。比如要允许Pod访问us.gcr.io的443端口,否则会被拦截。
5. 添加调试步骤定位问题
如果上面的方法都没解决,可以在推送步骤前加一个调试步骤,验证网络连通性:
steps: - name: debug-network image: alpine commands: - apk add --no-cache curl bind-tools - # 测试能否访问GCR的端点 - curl -v https://us.gcr.io - # 测试域名解析 - nslookup us.gcr.io
通过这些输出,你可以快速判断是DNS问题还是网络连通问题。
我当时的问题就是dind的默认bridge子网和K8s Pod子网重叠,调整--bip参数后就顺利推送镜像了,希望这些方法能帮到你。
内容的提问来源于stack exchange,提问作者Kevin Minehart
相关产品推荐
相关产品推荐

