41

我有一个 Dockerfile,它从安装 texlive-full 包开始,它很大并且需要很长时间。如果我docker build在本地,安装后创建的中间映像会被缓存,后续构建速度很快。

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

我曾尝试使用--cache-dirand--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_dir(我已经对,docker_cache_dir和的不同值进行了实验,disable_cache结果都相同:没有任何缓存)

4

3 回答 3

19

我想你的问题没有简单的答案。在添加一些细节之前,我强烈建议阅读DinD 维护者的这篇博客文章,该文章最初命名为“Do not use Docker in Docker for CI”。

您可能会尝试将/var/lib/docker您的 GitLab 运行器声明为卷。但是请注意,根据您的文件系统驱动程序,您可能会在主机上的 AUFS 文件系统上的容器中使用 AUFS,这很可能会导致问题。

我建议您创建一个单独的Docker-VM,仅用于运行器,并将docker.sockVM 绑定安装到运行器容器中。我们在 GitLab 中使用此设置并取得了巨大成功(大约 12 个月内构建了 >27.000 个版本)。

你可以看看我们的runner with docker-composesupport,它实际上是基于 GitLab 的 runner 的 shell-executor。

于 2016-03-28T18:35:36.930 回答
3

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

variables:
  DOCKER_DRIVER: overlay

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

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

于 2016-08-29T21:26:37.493 回答
0

对于不经常更改的构建依赖项,您可以使用 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 不会注意到这一点,因此您需要强制构建和推送新图像。因此,对于动态更改的图像,这效果不佳,但对于您的用例,这似乎是一种可行的方法。

于 2018-06-27T09:33:11.583 回答