GNU/Linux >> Linux Esercitazione >  >> Panels >> Docker

Come creare immagini Docker in una pipeline CI GitLab

Un caso d'uso comune per le pipeline CI è la creazione delle immagini Docker che utilizzerai per distribuire la tua applicazione. GitLab CI è un'ottima scelta per questo in quanto supporta un servizio pull proxy integrato, il che significa pipeline più veloci e un registro integrato per archiviare le immagini create.

In questa guida, ti mostreremo come configurare build Docker che utilizzano entrambe le funzionalità di cui sopra. I passaggi che devi eseguire variano leggermente a seconda del tipo di executor di GitLab Runner che utilizzerai per la tua pipeline. Di seguito tratteremo gli esecutori Shell e Docker.

Creazione con l'esecutore della shell

Se stai utilizzando l'esecutore Shell, assicurati di avere Docker installato sulla macchina che ospita il tuo runner. L'esecutore funziona eseguendo i normali comandi della shell usando la docker binario sull'host del Runner.

Vai al repository Git per il progetto per il quale desideri creare immagini. Crea un .gitlab-ci.yml file nella radice del repository. Questo file definisce la pipeline CI GitLab che verrà eseguita quando esegui il push delle modifiche al tuo progetto.

Aggiungi il seguente contenuto al file:

stages:
  - build

docker_build:
  stage: build
  script:
    - docker build -t example.com/example-image:latest .
    - docker push example.com/example-image:latest

Questa configurazione semplicistica è sufficiente per dimostrare le basi delle build di immagini basate su pipeline. GitLab clona automaticamente il tuo repository Git nell'ambiente di build, quindi eseguendo docker build utilizzerà il Dockerfile del tuo progetto e rendere disponibile il contenuto del repository come contesto di compilazione.

Al termine della compilazione, puoi docker push l'immagine nel registro. Altrimenti sarebbe disponibile solo per l'installazione Docker locale che ha eseguito la build. Se stai utilizzando un registro privato, esegui docker login prima di fornire i dettagli di autenticazione corretti:

script:
  - docker login -u $DOCKER_REGISTRY_USER -p $DOCKER_REGISTRY_PASSWORD

Definisci i valori delle due variabili delle credenziali andando su Impostazioni> CI/CD> Variabili nell'interfaccia utente web di GitLab. Fare clic sul pulsante blu "Aggiungi variabile" per creare una nuova variabile e assegnare un valore. GitLab renderà disponibili queste variabili nell'ambiente shell utilizzato per eseguire il lavoro.

Creazione con Docker Executor

L'esecutore Docker di GitLab Runner è comunemente usato per fornire un ambiente completamente pulito per ogni lavoro. Il lavoro verrà eseguito in un contenitore isolato, quindi la docker binario sull'host Runner sarà inaccessibile.

L'esecutore Docker offre due possibili strategie per creare l'immagine:utilizzare Docker-in-Docker o collegare il socket Docker dell'host all'ambiente di compilazione del Runner. Quindi utilizzi l'immagine del contenitore Docker ufficiale come immagine del tuo lavoro, creando la docker comando disponibile nello script CI.

Docker-in-Docker

L'uso di Docker-in-Docker (DinD) per creare le tue immagini ti offre un ambiente completamente isolato per ogni lavoro. Il processo Docker che esegue la compilazione sarà un figlio del contenitore che GitLab Runner crea sull'host per eseguire il processo CI.

Devi registrare il tuo esecutore GitLab Runner Docker con la modalità privilegiata abilitata per usare DinD. Aggiungi il --docker-privileged segnala quando registri il tuo corridore:

sudo gitlab-runner register -n 
  --url https://example.com 
  --registration-token $GITLAB_REGISTRATION_TOKEN 
  --executor docker 
  --description "Docker Runner" 
  --docker-image "docker:20.10" 
  --docker-volumes "/certs/client" 
  --docker-privileged

All'interno della pipeline CI, aggiungi il docker:dind immagine come servizio. Ciò rende Docker disponibile come immagine separata collegata all'immagine del lavoro. Potrai utilizzare la docker comando per creare immagini utilizzando l'istanza Docker nella docker:dind contenitore.

services:
  - docker:dind

docker_build:
  stage: build
  image: docker:latest
  script:
    - docker build -t example-image:latest .

L'uso di DinD ti offre build completamente isolate che non possono influire l'una sull'altra o sul tuo host. Lo svantaggio principale è un comportamento di memorizzazione nella cache più complicato:ogni lavoro ottiene un nuovo ambiente in cui i livelli precedentemente creati non saranno accessibili. Puoi parzialmente risolvere questo problema provando a estrarre la versione precedente della tua immagine prima di creare, quindi utilizzando il --cache-from build flag per rendere disponibili i livelli dell'immagine estratta come origine cache:

docker_build:
  stage: build
  image: docker:latest
  script:
    - docker pull $CI_REGISTRY_IMAGE:latest || true
    - docker build --cache-from $CI_REGISTRY_IMAGE:latest -t $CI_REGISTRY_IMAGE:latest .

Socket Bind Mounts

Il montaggio del socket Docker del tuo host nell'ambiente del tuo lavoro è un'opzione alternativa quando utilizzi l'esecutore Docker. Ciò ti offre una memorizzazione nella cache senza interruzioni ed elimina la necessità di aggiungere la docker:dind servizio alla tua configurazione CI.

Per configurarlo, registra il tuo Runner con un docker-volumes flag che associa il socket Docker dell'host a /var/run/docker.sock all'interno dei contenitori di lavoro:

sudo gitlab-runner register -n 
  --url https://example.com 
  --registration-token $GITLAB_REGISTRATION_TOKEN 
  --executor docker 
  --description "Docker Runner" 
  --docker-image "docker:20.10" 
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock

Ora lavori che vengono eseguiti con la docker l'immagine potrà utilizzare la docker binario come di consueto. Le operazioni avverranno effettivamente sulla tua macchina host, diventando fratelli del contenitore del lavoro invece che figli.

Questo è effettivamente simile all'utilizzo dell'esecutore shell con l'installazione Docker del tuo host. Le immagini risiederanno sull'host, facilitando l'uso senza interruzioni della normale docker build memorizzazione nella cache dei livelli.

Sebbene questo approccio possa portare a prestazioni più elevate, meno configurazione e nessuno dei limiti di DinD, ha i suoi problemi unici. Le più importanti tra queste sono le implicazioni sulla sicurezza:i lavori potrebbero eseguire comandi Docker arbitrari sul tuo host Runner, quindi un progetto dannoso nella tua istanza GitLab potrebbe eseguire docker run -it malicious-image:latest o docker rm -f $(docker ps -a) con conseguenze devastanti.

GitLab avverte inoltre che l'associazione del socket può causare problemi quando i lavori vengono eseguiti contemporaneamente. Ciò si verifica quando si fa affidamento sulla creazione di contenitori con nomi specifici. Se due istanze di un lavoro vengono eseguite in parallelo, la seconda avrà esito negativo poiché il nome del contenitore esiste già sul tuo host.

Dovresti invece considerare l'utilizzo di DinD se ti aspetti che uno di questi problemi sia problematico. Sebbene DinD non sia più generalmente consigliato, può avere più senso per le istanze GitLab pubbliche che eseguono lavori CI simultanei.

Invio di immagini al registro di GitLab

I progetti GitLab hanno l'opzione di un registro integrato che puoi utilizzare per archiviare le tue immagini. Puoi visualizzare il contenuto del registro andando su Pacchetti e registri> Registro contenitori nella barra laterale del tuo progetto. Se non vedi questo link, abilita il registro andando su Impostazioni> Generali> Visibilità, Progetto, Funzionalità e autorizzazioni e attivando l'interruttore "Registro contenitore".

GitLab imposta automaticamente le variabili di ambiente nei tuoi lavori CI che ti consentono di fare riferimento al registro dei contenitori del tuo progetto. Regola lo script sezione per accedere al registro ed eseguire il push della tua immagine:

script:
  - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
  - docker build -t $CI_REGISTRY_IMAGE:latest .
  - docker push $CI_REGISTRY_IMAGE:latest

GitLab genera un set sicuro di credenziali per ciascuno dei tuoi lavori CI. Il $CI_JOB_TOKEN la variabile di ambiente conterrà un token di accesso che il lavoro può utilizzare per connettersi al registro come gitlab-ci-token utente. L'URL del server di registro è disponibile come $CI_REGISTRY .

La variabile finale, $CI_REGISTRY_IMAGE , fornisce il percorso completo del registro dei contenitori del progetto. Questa è una base adatta per i tuoi tag immagine. Puoi estendere questa variabile per creare sottorepository, come $CI_REGISTRY_IMAGE/production/api:latest .

Altri client Docker possono estrarre immagini dal registro eseguendo l'autenticazione tramite un token di accesso. Puoi generarli nella schermata Impostazioni> Token di accesso del tuo progetto. Aggiungi il read_registry scope, quindi utilizzare le credenziali visualizzate per docker login nel registro del tuo progetto.

Utilizzo del proxy di dipendenza di GitLab

Il proxy di dipendenza di GitLab fornisce un livello di memorizzazione nella cache per le immagini a monte che estrai da Docker Hub. Ti aiuta a rimanere entro i limiti di velocità di Docker Hub estraendo il contenuto delle immagini solo quando sono state effettivamente modificate. Ciò migliorerà anche le prestazioni delle tue build.

Il proxy di dipendenza viene attivato a livello di gruppo GitLab andando su Impostazioni> Pacchetti e registri> Proxy di dipendenza. Una volta abilitato, anteponi i riferimenti alle immagini nel tuo .gitlab-ci.yml file con $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX per estrarli tramite il proxy:

docker_build:
  stage: build
  image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/docker:latest
  services:
    - name: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/docker:dind
      alias: docker

Questo è tutto quello che c'è da fare! GitLab Runner accede automaticamente al registro del proxy di dipendenza, quindi non è necessario fornire manualmente le credenziali.

GitLab ora memorizza nella cache le tue immagini, offrendoti prestazioni migliorate e resilienza alle interruzioni di rete. Nota che i services anche la definizione ha dovuto essere modificata:le variabili di ambiente non funzionano con il modulo inline utilizzato in precedenza, quindi l'immagine completa name deve essere specificato, quindi un comando alias a cui fare riferimento nel tuo script sezione.

Anche se ora abbiamo impostato il proxy per le immagini utilizzate direttamente dalle nostre fasi di lavoro, è necessario altro lavoro per aggiungere il supporto per l'immagine di base nel Dockerfile costruire. Un'istruzione regolare come questa non passerà attraverso il proxy:

FROM ubuntu:latest

Per aggiungere quest'ultimo pezzo, usa gli argomenti di build di Docker per rendere disponibile l'URL del proxy di dipendenza quando scorri il Dockerfile:

ARG GITLAB_DEPENDENCY_PROXY
FROM ${GITLAB_DEPENDENCY_PROXY}/ubuntu:latest

Quindi modifica il tuo docker build comando per definire il valore della variabile:

script:
  >
    - docker build 
        --build-arg GITLAB_DEPENDENCY_PROXY=${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX} 
        -t example-image:latest .

Ora anche la tua immagine di base verrà trascinata attraverso il proxy di dipendenza.

Riepilogo

Le build di immagini Docker sono facilmente integrate nelle pipeline CI di GitLab. Dopo la configurazione iniziale di Runner, docker build e docker push comandi nello script del tuo lavoro sono sufficienti per creare un'immagine con il Dockerfile nel tuo repository. Il registro dei contenitori integrato di GitLab ti offre uno spazio di archiviazione privato per le immagini del tuo progetto.

Oltre alle build di base, vale la pena integrare il proxy di dipendenza di GitLab per accelerare le prestazioni ed evitare di raggiungere i limiti di velocità di Docker Hub. Dovresti anche verificare la sicurezza della tua installazione valutando se il metodo selezionato consente a progetti non attendibili di eseguire comandi sul tuo host Runner. Sebbene abbia i suoi problemi, Docker-in-Docker è l'approccio più sicuro quando la tua istanza GitLab è pubblicamente accessibile o accessibile da una vasta base di utenti.


Docker
  1. Come cercare, estrarre, elencare ed eliminare immagini Docker su Linux

  2. Come utilizzare un Dockerfile per creare un'immagine Docker

  3. Introduzione alle immagini Docker

  4. Come creare e configurare automaticamente immagini Docker personalizzate con Dockerfile – Parte 3

  5. Come utilizzare le immagini docker locali con Minikube?

Come utilizzare Rsync e SSH in una pipeline CI GitLab Dockerized

Come ripulire ed eliminare le immagini Docker

Come creare una pipeline CI/CD per le immagini Docker CircleCI

Come aggiornare le immagini Docker all'ultima versione

Come utilizzare Docker Commit per modificare le immagini del contenitore

Come elencare / cercare / estrarre le immagini della finestra mobile su Linux