web-dev-qa-db-fra.com

Concourse CI: exploitez le cache d'image Docker

Je comprends parfaitement que Concourse est censé être apatride, mais existe-t-il néanmoins un moyen de réutiliser des images docker déjà extraites? Dans mon cas, je crée ~ 10 images docker qui ont la même image de base, mais chaque fois que la génération est déclenchée, Concourse tire 10 fois l'image de base.

Est-il possible d'extraire cette image une fois et de la réutiliser plus tard (au moins dans le cadre de la même version) en utilisant une ressource docker standard?

Oui, il devrait être possible de le faire en utilisant une image personnalisée et de la coder dans le script sh, mais je n'aime pas inviter les vélos.

Si la ressource docker standard ne permet pas cela, est-il possible de l'étendre d'une manière ou d'une autre pour permettre un tel comportement?

--cache-from n'est pas utile, car CI passe la plupart de son temps à extraire l'image, sans construire de nouveaux calques.

22
Max Romanovsky

Théorie

Tout d'abord, une théorie de Concourse (au moins à partir de la v3.3.1):

Les gens parlent souvent de Concourse ayant une "cache", mais interprètent mal ce que cela signifie. Chaque employé du concours dispose d'un ensemble de volumes sur le disque qui sont laissés autour, formant un cache de volume. Ce cache de volumes contient des volumes qui ont été remplis par la ressource get et put et la tâche outputs.

Les gens comprennent souvent mal comment le docker-image-resource utilise Docker. Il n'y a pas de serveur Docker global en cours d'exécution avec votre installation Concourse, en fait les conteneurs Concourse ne sont pas des conteneurs Docker, ce sont des conteneurs runC. Chaque docker-image-resource le processus (check, get, put) est exécuté à l'intérieur de son propre conteneur runC, à l'intérieur duquel se trouve un serveur docker local. Cela signifie qu'il n'y a pas de serveur Docker global qui extrait des images Docker et met en cache les couches pour une utilisation ultérieure.

Cela implique que lorsque nous parlons de mise en cache avec la ressource d'image docker, cela signifie charger ou pré-extraire des images dans le serveur docker local.


Entraine toi

Maintenant, pour les options d'optimisation des temps de construction:

load_base

Contexte

Le load_base param dans votre docker-image-resourceput indique à la ressource d'abord docker load une image (récupérée via un get) dans son serveur docker local, avant de construire l'image spécifiée via votre put params.

Ceci est utile lorsque vous devez pré-remplir une image dans votre "cache Docker". Dans votre cas, vous voudrez précharger l'image utilisée dans la directive FROM. Ceci est plus efficace car il utilise la mise en cache du volume de Concourse pour extraire une seule fois la "base", la mettant à la disposition du serveur docker lors de l'exécution de la commande FROM.

Usage

Vous pouvez utiliser load_base comme suit:

Supposons que vous souhaitiez créer une image python personnalisée, et que vous ayez un référentiel git avec un fichier ci/Dockerfile comme suit:

FROM ubuntu

RUN apt-get update
RUN apt-get install -y python python-pip

Si vous vouliez automatiser la construction/pousser de cette image tout en profitant de mise en cache du volume Concourse ainsi que mise en cache de la couche d'image Docker:

resources:
- name: ubuntu
  type: docker-image
  source:
    repository: ubuntu

- name: python-image
  type: docker-image
  source:
    repository: mydocker/python

- name: repo
  type: git
  source:
    uri: ...

jobs:
- name: build-image-from-base
  plan:
  - get: repo
  - get: ubuntu
    params: {save: true}
  - put: python-image
    params:
      load_base: ubuntu
      dockerfile: repo/ci/Dockerfile

cache & cache_tag

Contexte

Les cache et cache_tag params dans votre docker-image-resourceput indique à la ressource de tirer d'abord une image + une balise particulière de votre source distante, avant de construire l'image spécifiée via vos paramètres de vente.

Ceci est utile lorsqu'il est plus facile de dérouler l'image que de la construire à partir de zéro, par ex. vous avez un processus de construction très très long , comme des compilations coûteuses

Ceci NE PAS utilise la mise en cache du volume de Concourse et utilise le Docker --cache-from (qui court le risque de devoir d'abord effectuer une docker pull) pendant chaque put.

Usage

Vous pouvez utiliser cache et cache_tag comme suit:

Supposons que vous vouliez construire une image Ruby personnalisée, où vous compilez Ruby à partir de la source, et vous avez un référentiel git avec un fichier ci/Dockerfile comme suit:

FROM ubuntu

# Install Ruby
RUN mkdir /tmp/Ruby;\
  cd /tmp/Ruby;\
  curl ftp://ftp.Ruby-lang.org/pub/Ruby/2.0/Ruby-2.0.0-p247.tar.gz | tar xz;\
  cd Ruby-2.0.0-p247;\
  chmod +x configure;\
  ./configure --disable-install-rdoc;\
  make;\
  make install;\
  gem install bundler --no-ri --no-rdoc

RUN gem install nokogiri

Si vous vouliez automatiser la construction/pousser de cette image tout en profitant seulement de mise en cache de la couche d'image Docker:

resources: 
- name: compiled-Ruby-image
  type: docker-image
  source:
    repository: mydocker/Ruby
    tag: 2.0.0-compiled

- name: repo
  type: git
  source:
    uri: ...

jobs:
- name: build-image-from-cache
  plan:
  - get: repo
  - put: compiled-Ruby-image
    params:
      dockerfile: repo/ci/Dockerfile
      cache: mydocker/Ruby
      cache_tag: 2.0.0-compiled

Recommandation

Si vous souhaitez augmenter l'efficacité de la création d'images Docker, je pense personnellement que load_base devrait être utilisé dans la plupart des cas. Puisqu'il utilise une ressource get, il tire parti de la mise en cache du volume Concourse et évite d'avoir à faire docker pulls.

39
materialdesigner