Failed to pull image with policy always

背景描述

之前一篇博客介绍了如何通过 DinD 的方案使用 docker 来作为 gitlab-runner,在平稳运行大半年后突然发现构建失败了。报错如下:

1
WARNING: Failed to pull image with policy "always": Error response from daemon: Head "https://registry-1.docker.io/v2/library/docker/manifests/20-dind": Get "https://auth.docker.io/token?scope=repository%3Alibrary%2Fdocker%3Apull&service=registry.docker.io": net/http: TLS handshake timeout (manager.go:203:11s)

从报错来看大概就是无法拉取到镜像了,从百度得知可能是 docker 官方仓库限制了拉取次数。百度到的解决方案是将镜像放到自己的镜像仓库中去,这可能是一个好方法,本来想选用阿里的镜像仓库的,于是就着手将这个镜像上传,于是就在机器上找之前下载下来的 20-dind 的镜像。

通过 docker images 命令确实找到了本地存在 20-dind 的镜像,正打算上传到阿里的镜像服务中去,突然仔细一想,如果我的机器本地已经有了镜像了,为什么每次还要从网上拉了,于是解决办法就变成了修改”always”的策略上。

解决方案

方案一

尝试修改 gitlab-ci,查看文档看下是否可以配置镜像的拉取策略:https://docs.gitlab.com/ee/ci/yaml/index.html#image 发现在 image 配置中确实可以设置拉取策略 image:pull_policy

1
2
3
image:
name: docker:20-dind
pull_policy: if-not-present

修改之后再次尝试,发现还是使用的是 always,仔细查看文档后才发现 SaaS 版本的 gitlab 还不支持这个特性,只有私有化部署的版本才可以。

方案二(最终方案)

继续查阅文档,发现 https://docs.gitlab.com/runner/executors/docker.html#how-pull-policies-work 中记载了可以通过修改 DinD 启动的配置来修改策略。

既然 DinD 是通过 docker 服务启动一个新的 docker 服务来作为 runner,那我们只需要修改启动 runner 的配置就可以了,在容器启动时,会读取gitlab-runner-docker/config/config.toml配置,只要修改这个文件的配置,应该就能修改策略。

相应的配置文档如下:https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersdocker-section

最终修改后的文件为:

1
2
3
4
5
6
7
8
9
10
[runners.docker]
tls_verify = false
image = "tico/docker:latest"
privileged = true
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache"]
shm_size = 0
pull_policy: if-not-present

保存后重新执行任务,发现能够成功构建了,问题解决!


Failed to pull image with policy always
https://www.wobushi.top/2022/Failed-to-pull-image-with-policy-always/
作者
Pride Su
发布于
2022年8月23日
许可协议