GitLab CI docker in docker (DIND)镜像拉取优化
使用 Gitlab Pipeline 进行代码编译时,有时候拉取的镜像特别大,能够达到20G的量级。如果每次都需要重新拉取,一个是浪费占用带宽,另一个是减慢了编译的速度,光镜像拉取就需要好几分钟的时间。
对于 job 使用的镜像,GitLab runner 可以直接复用宿主机的镜像,不需要特殊的配置。
对于使用 docker in docker的方式使用 dind 镜像通过 Dickerfile build 镜像,则需要额外的配置。
GitLab runner 配置
先看一下最后的配置,主要关注runner配置中的 builds_dir和 volumes 。volumes 必须配置 ["/var/run/docker.sock:/var/run/docker.sock","/tmp/builds:/tmp/builds"] 。
[[runners]]
name = "dind-arm64"
url = "https://gitlab.xxxx.com/"
token = "xxxxx"
executor = "docker"
builds_dir = "/tmp/builds" # 配置定义 build_dir
[runners.custom_build_dir]
enabled = true # 开启自定义 build_dir
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
[runners.cache.azure]
[runners.docker]
tls_verify = false
image = "docker:20.10.12-dind"
privileged = true
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache", "/tmp/builds:/tmp/builds", "/etc/localtime:/etc/localtime:ro","/var/run/docker.sock:/var/run/docker.sock"]
allowed_images = ["docker:20.10.12-dind"]
shm_size = 0
使用 dind 根据 dockerfile构建镜像
这种方式镜像只要映射了 "/var/run/docker.sock:/var/run/docker.sock",可以直接使用宿主机的镜像,缩短拉取镜像的时间。
build:
extends:
- .pipeline:docker:build
needs:
- prepare
stage: build
tags:
- test
image:
name: "docker:20.10.12-dind"
script:
- mkdir ~/.docker
- docker login -u $internal_registry_user -p $internal_registry_password $CI_REGISTRY
- docker pull $IMAGE_NAME
- docker build -t demo:latest .
使用 dind,镜像构建产物,用于后续job使用
对于通过 docker run,并且挂载 volume 到容器中时,必须配置自定义 builds_dir,并挂载"/tmp/builds:/tmp/builds"。原因是因为挂载了docker.sock之后,docker run 直接是在宿主机中启动,其中的路径也就是宿主机的路径。如果不配置自定义的build目录,volume的挂载则会不符合预期。
build:
extends:
- .pipeline:docker:build
needs:
- prepare
stage: build
tags:
- test
image:
name: "docker:20.10.12-dind"
script:
- mkdir ~/.docker
- docker login -u $internal_registry_user -p $internal_registry_password $CI_REGISTRY
- docker pull $IMAGE_NAME
- export
- |
docker run \
-e CICD_GIT_TAG=$CI_COMMIT_TAG \
-v $PWD/scripts:/home/xxx/scripts \
$IMAGE_NAME bash /home/xxx/scripts/build.sh