首页 文章

我怎样才能让gitlab-ci-runner的DinD图像缓存中间图像?

提问于
浏览
33

我有一个Dockerfile,从安装texlive-full软件包开始,这是一个巨大的,需要很长时间 . 如果我在本地使用它,则会缓存安装后创建的中间映像,后续构建很快 .

但是,如果我推送到我自己的GitLab安装并且GitLab-CI构建运行器启动,这似乎总是从头开始,重新加载 FROM 图像,并再次执行apt-get安装 . 这对我来说似乎是一个巨大的浪费,所以我想弄清楚如何让GitLab DinD图像在构建之间缓存中间图像,到目前为止没有运气 .

我已经尝试使用 --cache-dir--docker-cache-dir 作为 gitlab-runner register 命令,但无济于事 .

这甚至是gitlab-runner DinD图像能够做到的吗?

我的 .gitlab-ci.yml

build_job:
    script:
    - docker build --tag=example/foo .

我的 Dockerfile

FROM php:5.6-fpm
MAINTAINER Roel Harbers <roel.harbers@example.com>
RUN apt-get update && apt-get install -qq -y --fix-missing --no-install-recommends texlive-full
RUN echo Do other stuff that has to be done every build.

我使用GitLab CE 8.4.0和gitlab / gitlab-runner:latest作为跑步者

docker run -d --name gitlab-runner --restart always \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /usr/local/gitlab-ci-runner/config:/etc/gitlab-runner \
    gitlab/gitlab-runner:latest \
; \

跑步者使用以下方式注册:

docker exec -it gitlab-runner gitlab-runner register \
    --name foo.example.com \
    --url https://gitlab.example.com/ci \
    --cache-dir /cache/build/ \
    --executor docker \
    --docker-image gitlab/dind:latest \
    --docker-privileged \
    --docker-disable-cache false \
    --docker-cache-dir /cache/docker/ \
; \

这将创建以下 config.toml

concurrent = 1
[[runners]]
    name = "foo.example.com"
    url = "https://gitlab.example.com/ci"
    token = "foobarsldkflkdsjfkldsj"
    tls-ca-file = ""
    executor = "docker"
    cache_dir = "/cache/build/"
    [runners.docker]
        image = "gitlab/dind:latest"
        privileged = true
        disable_cache = false
        volumes = ["/cache"]
        cache_dir = "/cache/docker/"

(我已经尝试了 cache_dirdocker_cache_dirdisable_cache 的不同值,所有这些都有相同的结果:没有任何缓存)

3 回答

  • 3

    对于不会因此而改变的构建依赖项,您可以使用gitlab图像注册表进行手动缓存 . 在CI脚本中,您没有明确地调用 docker build ,而是将其包装在shell脚本中

    # cat build_dependencies.sh
    registry=registry.example.com
    project=group/project
    imagebase=$registry/$project/linux
    
    docker pull $imagebase/devbase:1.0
    if [ $? -ne 0 ]; then
       docker build -f devbase.dockerfile -t $imagebase/devbase:1.0 .
       docker push $imagebase/devbase:1.0
    fi
    ...
    

    并在您的CI中调用该脚本

    ...
      script:
        - ./build_dependencies.sh
    

    这样做的缺点是,当你的 devbase.dockerfile 更新时,CI会忽略这一点,因此你需要强制构建和推送新图像 . 因此,对于动态更改图像,这不能很好地工作,但对于您的用例,这似乎是一种可行的方法 .

  • 13

    目前,您无法在GitLab Docker-in-Docker中缓存中间层 . Altough计划添加(在下面的链接中提到) . 今天你可以做些什么来加速你的DinD构建是使用覆盖文件系统 . 为此,您需要运行liunx内核> = 3.18,并确保加载覆盖内核模块 . 然后在gitlab-ci.yml中设置此变量:

    variables:
      DOCKER_DRIVER: overlay
    

    有关更多信息,请参阅此问题,特别是关于“优化Docker Builds的状态!”的评论,请参阅“使用docker executor with dind”部分 .

    https://gitlab.com/gitlab-org/gitlab-ce/issues/17861#note_12991518

  • 0

    我想你的问题没有简单的答案 . 在添加一些细节之前,我强烈建议从DinD的维护者处读取this blog article,该维护者最初名为"do not use Docker in Docker for CI" .

    您可能会尝试将 /var/lib/docker 声明为GitLab跑步者的音量 . 但要注意,根据您的文件系统驱动程序,您可以在主机上的AUFS文件系统上的容器中使用AUFS,这很可能会导致问题 .

    我建议你创建一个单独的Docker-VM,仅用于跑步者,并将VM从绑定装载 docker.sock 到你的跑步者容器中 . 我们正在使用GitLab的这种设置取得了巨大成功(大约12个月内大于27.000次构建) .

    你可以看看我们的runner with docker-compose support,它实际上是基于GitLab的跑步者的shell-executor .

相关问题