web-dev-qa-db-fra.com

Comment laisser les images intermédiaires du cache d'image DinD gitlab-ci-runner?

J'ai un Dockerfile qui commence par l'installation du package texlive-full, qui est énorme et prend beaucoup de temps. Si je docker build Localement, l'image intermédiaire créée après l'installation est mise en cache et les versions suivantes sont rapides.

Cependant, si je pousse vers ma propre installation GitLab et que le runner de build GitLab-CI démarre, cela semble toujours recommencer à zéro, en retéléchargeant l'image FROM et en effectuant à nouveau l'installation apt-get. Cela semble être un énorme gaspillage pour moi, donc j'essaie de comprendre comment obtenir l'image GitLab DinD pour mettre en cache les images intermédiaires entre les builds, sans succès jusqu'à présent.

J'ai essayé d'utiliser les commandes --cache-dir Et --docker-cache-dir Pour la commande gitlab-runner register, En vain.

Est-ce même quelque chose que l'image DinD de gitlab-runner est censée être capable de faire?

Mon .gitlab-ci.yml:

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

Mon Dockerfile:

FROM php:5.6-fpm
MAINTAINER Roel Harbers <[email protected]>
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.

J'utilise GitLab CE 8.4.0 et gitlab/gitlab-runner: dernier en tant que coureur, démarré en tant que

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 \
; \

Le coureur est inscrit en utilisant:

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/ \
; \

Cela crée le config.toml Suivant:

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/"

(J'ai expérimenté différentes valeurs pour cache_dir, docker_cache_dir Et disable_cache, Le tout avec le même résultat: pas de mise en cache du tout)

35
Roel Harbers

Je suppose qu'il n'y a pas de réponse simple à votre question. Avant d'ajouter quelques détails, je suggère fortement de lire cet article de blog du mainteneur de DinD, qui était à l'origine nommé "ne pas utiliser Docker dans Docker pour CI".

Vous pourriez essayer de déclarer /var/lib/docker comme volume pour votre runner GitLab. Mais soyez averti, en fonction de vos pilotes de système de fichiers, vous pouvez utiliser AUFS dans le conteneur sur un système de fichiers AUFS sur votre hôte, ce qui est très susceptible de causer des problèmes.

Ce que je vous suggère, c'est de créer un Docker-VM séparé , uniquement pour le (s) runner (s), et bind-mount docker.sock depuis le VM dans votre runner-container. Nous utilisons cette configuration avec GitLab avec un grand succès (> 27.000 builds en environ 12 mois).

Vous pouvez jeter un oeil à notre coureur avec docker-compose support qui est en fait basé sur le Shell-executor du runner de GitLab.

14
schmunk

Actuellement, vous ne pouvez pas mettre en cache les couches intermédiaires dans GitLab Docker-in-Docker. Bien qu'il soit prévu d'ajouter cela (qui sont mentionnés dans le lien ci-dessous). Ce que vous pouvez faire aujourd'hui pour accélérer votre build DinD est d'utiliser le système de fichiers de superposition. Pour ce faire, vous devez exécuter un noyau liunx> = 3.18 et assurez-vous de charger le module du noyau de superposition. Ensuite, vous définissez cette variable dans votre gitlab-ci.yml:

variables:
  DOCKER_DRIVER: overlay

Pour plus d'informations, consultez ce problème et en particulier ce commentaire sur "L'état de l'optimisation des builds Docker!", Consultez la section "Utilisation de l'exécuteur Docker avec dind".

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

3
Jonas Kello

Pour les dépendances de construction qui ne changent pas aussi souvent, vous pouvez faire un peu de mise en cache manuelle avec le registre d'images gitlab. Dans le script CI, vous n'appelez pas explicitement docker build mais plutôt envelopper dans un script 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
...

et appelez ce script dans votre CI

  ...
  script:
    - ./build_dependencies.sh

L'inconvénient est que lorsque votre devbase.dockerfile est mis à jour, cela passerait inaperçu par CI, vous devez donc forcer la création et la transmission d'une nouvelle image. Donc, pour les images à changement dynamique, cela ne fonctionne pas bien, mais pour votre cas d'utilisation, cela semble être une solution possible.

0
Slava