GNU/Linux >> LINUX-Kenntnisse >  >> Panels >> Docker

So erstellen Sie Docker-Images in einer GitLab-CI-Pipeline

Ein häufiger Anwendungsfall für CI-Pipelines ist das Erstellen der Docker-Images, die Sie zum Bereitstellen Ihrer Anwendung verwenden. GitLab CI ist dafür eine gute Wahl, da es einen integrierten Pull-Proxy-Dienst unterstützt, was schnellere Pipelines und eine integrierte Registrierung zum Speichern Ihrer erstellten Images bedeutet.

In diesem Leitfaden zeigen wir Ihnen, wie Sie Docker-Builds einrichten, die beide oben genannten Funktionen verwenden. Die Schritte, die Sie ausführen müssen, variieren leicht, je nachdem, welchen GitLab Runner-Executor-Typ Sie für Ihre Pipeline verwenden werden. Wir werden die Shell- und Docker-Executoren unten behandeln.

Bauen mit dem Shell-Executor

Wenn Sie den Shell-Executor verwenden, stellen Sie sicher, dass Docker auf dem Computer installiert ist, der Ihren Runner hostet. Der Executor funktioniert, indem er reguläre Shell-Befehle mit dem docker ausführt binär auf dem Host des Runners.

Gehen Sie zum Git-Repository für das Projekt, für das Sie Images erstellen möchten. Erstellen Sie eine .gitlab-ci.yml Datei im Stammverzeichnis des Repositorys. Diese Datei definiert die GitLab CI-Pipeline, die ausgeführt wird, wenn Sie Änderungen an Ihr Projekt übertragen.

Fügen Sie der Datei folgenden Inhalt hinzu:

stages:
  - build

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

Diese vereinfachte Konfiguration reicht aus, um die Grundlagen von Pipeline-gestützten Image-Builds zu demonstrieren. GitLab klont Ihr Git-Repository automatisch in die Build-Umgebung und führt so docker build aus verwendet das Dockerfile Ihres Projekts und stellen Sie den Inhalt des Repositorys als Build-Kontext zur Verfügung.

Nachdem der Build abgeschlossen ist, können Sie docker push das Image in Ihre Registrierung. Andernfalls wäre es nur für die lokale Docker-Installation verfügbar, die den Build ausgeführt hat. Wenn Sie eine private Registrierung verwenden, führen Sie docker login aus Geben Sie zuerst die richtigen Authentifizierungsdetails ein:

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

Definieren Sie die Werte der beiden Credential-Variablen, indem Sie in der GitLab-Webbenutzeroberfläche zu Einstellungen> CI/CD> Variablen gehen. Klicken Sie auf die blaue Schaltfläche „Variable hinzufügen“, um eine neue Variable zu erstellen und einen Wert zuzuweisen. GitLab stellt diese Variablen in der Shell-Umgebung zur Verfügung, die zum Ausführen Ihres Jobs verwendet wird.

Building with the Docker Executor

Der Docker-Executor von GitLab Runner wird häufig verwendet, um eine vollständig saubere Umgebung für jeden Job bereitzustellen. Der Job wird in einem isolierten Container ausgeführt, also dem docker Binärdatei auf dem Runner-Host ist unzugänglich.

Der Docker-Executor bietet Ihnen zwei mögliche Strategien zum Erstellen Ihres Images:Verwenden Sie entweder Docker-in-Docker oder binden Sie den Docker-Socket des Hosts in die Build-Umgebung des Runners ein. Anschließend verwenden Sie das offizielle Docker-Container-Image als Image Ihres Jobs und erstellen so den docker Befehl, der in Ihrem CI-Skript verfügbar ist.

Docker-in-Docker

Durch die Verwendung von Docker-in-Docker (DinD) zum Erstellen Ihrer Images erhalten Sie eine vollständig isolierte Umgebung für jeden Job. Der Docker-Prozess, der den Build durchführt, ist ein untergeordnetes Element des Containers, den GitLab Runner auf dem Host erstellt, um den CI-Job auszuführen.

Sie müssen Ihren GitLab Runner Docker-Executor mit aktiviertem privilegiertem Modus registrieren, um DinD verwenden zu können. Fügen Sie --docker-privileged hinzu Flagge, wenn Sie Ihren Läufer registrieren:

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

Fügen Sie in Ihrer CI-Pipeline den docker:dind hinzu Bild als Dienstleistung. Dadurch wird Docker als separates Image verfügbar, das mit dem Job-Image verknüpft ist. Sie können den docker verwenden Befehl zum Erstellen von Images mithilfe der Docker-Instanz im docker:dind Behälter.

services:
  - docker:dind

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

Durch die Verwendung von DinD erhalten Sie vollständig isolierte Builds, die sich gegenseitig oder Ihren Host nicht beeinflussen können. Der größte Nachteil ist das kompliziertere Caching-Verhalten:Jeder Job erhält eine neue Umgebung, in der zuvor erstellte Layer nicht zugänglich sind. Sie können dies teilweise beheben, indem Sie versuchen, die vorherige Version Ihres Images vor dem Erstellen abzurufen, und dann --cache-from verwenden build-Flag, um die Ebenen des gezogenen Bildes als Cache-Quelle verfügbar zu machen:

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-Halterungen

Das Mounten des Docker-Sockets Ihres Hosts in die Umgebung Ihres Jobs ist eine alternative Option, wenn Sie den Docker-Executor verwenden. Dies ermöglicht ein nahtloses Caching und macht das Hinzufügen von docker:dind überflüssig Service zu Ihrer CI-Konfiguration.

Um dies einzurichten, registrieren Sie Ihren Runner mit einem docker-volumes -Flag, das den Docker-Socket des Hosts an /var/run/docker.sock bindet innerhalb von Jobcontainern:

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

Jetzt Jobs, die mit dem docker ausgeführt werden image kann den docker verwenden Binär wie gewohnt. Vorgänge werden tatsächlich auf Ihrem Hostcomputer ausgeführt und werden zu Geschwistern des Containers des Jobs statt zu Kindern.

Dies ähnelt effektiv der Verwendung des Shell-Executors mit der Docker-Installation Ihres Hosts. Bilder werden auf dem Host gespeichert, was die nahtlose Verwendung des regulären docker build erleichtert Layer-Caching.

Während dieser Ansatz zu höherer Leistung, weniger Konfiguration und keiner der Einschränkungen von DinD führen kann, bringt er seine eigenen einzigartigen Probleme mit sich. Am wichtigsten sind die Auswirkungen auf die Sicherheit:Jobs könnten beliebige Docker-Befehle auf Ihrem Runner-Host ausführen, sodass ein bösartiges Projekt in Ihrer GitLab-Instanz möglicherweise docker run -it malicious-image:latest ausführt oder docker rm -f $(docker ps -a) mit verheerenden Folgen.

GitLab warnt auch davor, dass die Socket-Bindung Probleme verursachen kann, wenn Jobs gleichzeitig ausgeführt werden. Dies tritt auf, wenn Sie sich darauf verlassen, dass Container mit bestimmten Namen erstellt werden. Wenn zwei Instanzen eines Jobs parallel ausgeführt werden, schlägt die zweite fehl, da der Containername bereits auf Ihrem Host vorhanden ist.

Sie sollten stattdessen DinD verwenden, wenn Sie erwarten, dass eines dieser Probleme Probleme bereiten wird. Obwohl DinD nicht mehr allgemein empfohlen wird, kann es für öffentlich zugängliche GitLab-Instanzen sinnvoller sein, die gleichzeitig CI-Jobs ausführen.

Pushing von Bildern in die Registrierung von GitLab

GitLab-Projekte verfügen optional über eine integrierte Registry, in der Sie Ihre Images speichern können. Sie können den Inhalt der Registrierung anzeigen, indem Sie in der Seitenleiste Ihres Projekts zu Pakete &Registrierungen> Container-Registrierung navigieren. Wenn Sie diesen Link nicht sehen, aktivieren Sie die Registrierung, indem Sie zu Einstellungen> Allgemein> Sichtbarkeit, Projekt, Funktionen und Berechtigungen gehen und den Schalter „Container-Registrierung“ aktivieren.

GitLab setzt automatisch Umgebungsvariablen in Ihren CI-Jobs, mit denen Sie auf die Containerregistrierung Ihres Projekts verweisen können. Passen Sie das script an Abschnitt, um sich bei der Registrierung anzumelden und Ihr Image zu übertragen:

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 generiert einen sicheren Satz von Anmeldeinformationen für jeden Ihrer CI-Jobs. Der $CI_JOB_TOKEN Die Umgebungsvariable enthält ein Zugriffstoken, das der Job verwenden kann, um sich mit der Registrierung als gitlab-ci-token zu verbinden Benutzer. Die Registrierungsserver-URL ist als $CI_REGISTRY verfügbar .

Die letzte Variable, $CI_REGISTRY_IMAGE , stellt den vollständigen Pfad zur Containerregistrierung Ihres Projekts bereit. Dies ist eine geeignete Basis für Ihre Image-Tags. Sie können diese Variable erweitern, um Unterrepositorys zu erstellen, z. B. $CI_REGISTRY_IMAGE/production/api:latest .

Andere Docker-Clients können Images aus der Registrierung abrufen, indem sie sich mit einem Zugriffstoken authentifizieren. Sie können diese auf dem Bildschirm Einstellungen> Zugriffstoken Ihres Projekts generieren. Fügen Sie die read_registry hinzu Bereich, und verwenden Sie dann die angezeigten Anmeldeinformationen für die docker login in die Registrierung Ihres Projekts.

Verwenden des Abhängigkeitsproxys von GitLab

Der Dependency Proxy von GitLab bietet eine Caching-Schicht für die Upstream-Images, die Sie aus Docker Hub abrufen. Es hilft Ihnen, innerhalb der Ratenbegrenzungen von Docker Hub zu bleiben, indem es nur den Inhalt von Bildern abruft, wenn sie sich tatsächlich geändert haben. Dadurch wird auch die Leistung Ihrer Builds verbessert.

Der Abhängigkeits-Proxy wird auf der GitLab-Gruppenebene aktiviert, indem Sie zu Einstellungen> Pakete &Registrierungen> Abhängigkeits-Proxy gehen. Sobald es aktiviert ist, stellen Sie Bildreferenzen in Ihrer .gitlab-ci.yml voran Datei mit $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX um sie durch den Proxy zu ziehen:

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

Das ist alles dazu! GitLab Runner meldet sich automatisch bei der Dependency-Proxy-Registrierung an, sodass Sie Ihre Anmeldeinformationen nicht manuell eingeben müssen.

GitLab speichert Ihre Bilder jetzt im Cache, was Ihnen eine verbesserte Leistung sowie Ausfallsicherheit bei Netzwerkausfällen bietet. Beachten Sie, dass die services Definition musste auch angepasst werden – Umgebungsvariablen funktionieren nicht mit dem früher verwendeten Inline-Formular, also das vollständige Bild name angegeben werden muss, dann ein Befehl alias in Ihrem script zu referenzieren Abschnitt.

Während wir jetzt den Proxy für Bilder eingerichtet haben, die direkt von unseren Jobphasen verwendet werden, ist mehr Arbeit erforderlich, um Unterstützung für das Basisbild in der Dockerfile hinzuzufügen bauen. Eine normale Anweisung wie diese geht nicht über den Proxy:

FROM ubuntu:latest

Um diesen letzten Teil hinzuzufügen, verwenden Sie die Build-Argumente von Docker, um die Abhängigkeits-Proxy-URL verfügbar zu machen, wenn Sie die Docker-Datei schrittweise durchlaufen:

ARG GITLAB_DEPENDENCY_PROXY
FROM ${GITLAB_DEPENDENCY_PROXY}/ubuntu:latest

Ändern Sie dann Ihren docker build Befehl, um den Wert der Variablen zu definieren:

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

Jetzt wird auch Ihr Basis-Image durch den Abhängigkeits-Proxy gezogen.

Zusammenfassung

Docker-Image-Builds lassen sich einfach in Ihre GitLab-CI-Pipelines integrieren. Nach der anfänglichen Runner-Konfiguration docker build und docker push Befehle im script Ihres Jobs Abschnitt sind alles, was Sie brauchen, um ein Image mit dem Dockerfile zu erstellen in Ihrem Depot. Die integrierte Containerregistrierung von GitLab bietet Ihnen privaten Speicherplatz für die Bilder Ihres Projekts.

Über grundlegende Builds hinaus lohnt es sich, den Abhängigkeits-Proxy von GitLab zu integrieren, um die Leistung zu beschleunigen und zu vermeiden, dass Docker Hub-Ratenbegrenzungen erreicht werden. Sie sollten auch die Sicherheit Ihrer Installation überprüfen, indem Sie prüfen, ob Ihre ausgewählte Methode nicht vertrauenswürdigen Projekten erlaubt, Befehle auf Ihrem Runner-Host auszuführen. Obwohl es seine eigenen Probleme mit sich bringt, ist Docker-in-Docker der sicherste Ansatz, wenn Ihre GitLab-Instanz öffentlich zugänglich ist oder von einer großen Benutzerbasis aufgerufen wird.


Docker
  1. So suchen, ziehen, listen und löschen Sie Docker-Images unter Linux

  2. So ändern Sie Docker-Images

  3. Einführung in Docker-Images

  4. Automatisches Erstellen und Konfigurieren benutzerdefinierter Docker-Images mit Dockerfile – Teil 3

  5. Wie verwende ich lokale Docker-Images mit Minikube?

So verwenden Sie Rsync und SSH in einer Docker-basierten GitLab-CI-Pipeline

So bereinigen und löschen Sie Docker-Images

So erstellen Sie eine CI/CD-Pipeline für CircleCI-Docker-Images

So aktualisieren Sie Docker-Images auf die neueste Version

So verwenden Sie Docker Commit zum Ändern von Container-Images

So listen / suchen / ziehen Sie Docker-Images unter Linux