CI/CD-Pipelines mit GitLab auf CODE-DE Kubernetes - Erstellung eines Docker-Images

GitLab bietet ein isoliertes, privates Code-Register und einen Raum für die Zusammenarbeit von Teams an Software-Codes. Außerdem bietet es eine breite Palette von Funktionen zur Automatisierung der Codebereitstellung. In diesem Artikel erklären wir, wie Sie die Erstellung eines Docker-Images Ihrer Anwendung automatisieren können.

Was wir behandeln werden

  • Fügen Sie Ihren öffentlichen Schlüssel zu GitLab hinzu und greifen Sie über Ihre Befehlszeile auf GitLab zu.

  • Erstellen Sie ein Projekt in GitLab und fügen Sie einen Beispielanwendungscode hinzu.

  • Definieren Sie Umgebungsvariablen in Ihrem DockerHub-Zugang in GitLab.

  • Erstellen Sie eine Pipeline, um das Docker-Image Ihrer Anwendung mit Kaniko zu erstellen.

  • Pipeline-Build auslösen

Voraussetzungen

Nr. 1 Konto

Sie benötigen ein CODE-DE Konto mit Zugriff auf die Horizon-Schnittstelle: https://cloud.fra1-1.cloudferro.com/auth/login/?next=/.

No. 2 Kubernetes Cluster

Erstellen eines Kubernetes-Clusters mit CODE-DE OpenStack Magnum

Nr. 3 Lokale Version von GitLab verfügbar

GitLab muss lokal installiert sein und Sie können mit Ihrem GitLab-Benutzerkonto ordnungsgemäß darauf zugreifen.

In diesem Artikel gehen wir von der Einrichtung gemäß diesem Artikel aus Install GitLab on CODE-DE Kubernetes. Wenn Sie eine andere Instanz von GitLab verwenden, kann es einige Unterschiede geben, z. B. wo bestimmte Funktionen in der GUI zu finden sind.

In diesem Artikel werden wir gitlab.mysampledomain.info als Gitlab-Instanz verwenden. Ersetzen Sie diese durch Ihre eigene Domäne.

Nr. 4 Git-CLI einsatzbereit

Das git Command Line Interface ist lokal installiert. Sie installieren Git-CLI z.B. über GitHub, GitLab oder über andere auf git basierende Versionskontrollplattformen.

Nr. 5 Konto auf DockerHub

Sie benötigen Zugang zu Ihrem DockerHub (oder eine andere Container-Image-Registry).

Nr. 6 Verwendung von Kaniko

kaniko ist ein Werkzeug zum Erstellen von Container-Images auf der Grundlage einer bereitgestellten Docker-Datei. Einen ausführlicheren Überblick über kaniko finden Sie in seiner Dokumentation.

Nr. 7 Privater und öffentlicher Schlüssel verfügbar

Um eine Verbindung zu unserer GitLab-Instanz herzustellen, benötigen wir eine Kombination aus einem privaten und einem öffentlichen Schlüssel. Sie können ein beliebiges Schlüsselpaar verwenden. Eine Option ist die Verwendung von OpenStack Horizon zur Erstellung eines solchen. Als Referenz siehe:

Wie erstellt man ein Schlüsselpaar im OpenStack Dashboard?

Hier benötigen wir ein solches Schlüsselpaar, um eine Verbindung zur GitLab-Instanz herzustellen, die wir zuvor in Voraussetzung Nr. 3 aufgesetzt haben.

Schritt 1 Fügen Sie Ihren öffentlichen Schlüssel zu GitLab hinzu und greifen Sie über Ihre Befehlszeile auf GitLab zu

Für den Zugriff auf Ihre GitLab-Instanz über die Befehlszeile verwendet GitLab eine SSH-basierte Authentifizierung. Um sicherzustellen, dass Ihre Konsole standardmäßig diese Schlüssel zur Authentifizierung verwendet, stellen Sie sicher, dass Ihre Schlüssel im Ordner ~/.ssh gespeichert sind und die Namen id_rsa (privater Schlüssel) und id_rsa.pub (öffentlicher Schlüssel) tragen.

Der öffentliche Schlüssel sollte dann zu den autorisierten Schlüsseln in der GUI von GitLab hinzugefügt werden. Um den öffentlichen Schlüssel hinzuzufügen, klicken Sie auf Ihr Avatar-Symbol:

../_images/image-2024-5-10_16-28-4.png

Scrollen Sie dann zu „Preferences“, wählen Sie „SSH Keys“ aus dem linken Menü und fügen Sie den Inhalt Ihres öffentlichen Schlüssels in das Feld „Key“ ein.

../_images/image-2024-4-26_15-4-3.png

Wenn die von Ihnen verwendete GitLab-Instanz z. B. auf der Domain mysampledomain.info gehostet wird, können Sie einen Befehl wie den folgenden verwenden

um zu überprüfen, ob Sie über die CLI-Schnittstelle Zugriff auf GitLab haben.

Sie sollten eine ähnliche Ausgabe wie die folgende sehen:

../_images/image-2024-5-10_16-30-8.png

Schritt 2 Projekt in GitLab erstellen und Beispielanwendungscode hinzufügen

Wir werden zunächst eine Beispielanwendung in GitLab hinzufügen. Dies ist eine minimale Python-Flask-Anwendung, deren Code vom GitHub Repository dieser Knowledge Base heruntergeladen werden kann.

Als ersten Schritt richten wir ein neues Projekt auf GitLab ein. Melden Sie sich bei der GitLab-Benutzeroberfläche an, öffnen Sie den Standardbildschirm und klicken Sie auf die Schaltfläche „New Project“ und dann auf „Create blank project“. Sie werden zur folgenden Ansicht weitergeleitet.

../_images/image-2024-4-26_16-58-33.png

In dieser Ansicht ist die Projekt-URL bereits ausgefüllt und entspricht der URL Ihrer GitLab-Instanz. An der mit einem roten Rechteck gekennzeichneten Stelle geben Sie Ihren Benutzernamen ein; in der Regel ist dies root, Sie können aber auch einen anderen Namen eingeben. Wenn bereits Benutzer in GitLab definiert sind, werden deren Namen in einem Dropdown-Menü angezeigt.

../_images/drop-down-menu.png

Geben Sie Ihren bevorzugten Projektnamen und Kurzbezeichnung ein, in unserem Fall „GitLabCI Sample“ bzw. „GitLabCI-sample“. Wählen Sie die Sichtbarkeitsstufe nach Ihren Wünschen. Deaktivieren Sie das Kontrollkästchen „Initialize repository with a README“ (Repository mit einer README initialisieren), da wir das Repository aus dem vorhandenen Code initiieren werden. (Wir initialisieren das Repository in diesem Schritt nicht, sondern legen nur das Projekt an).

Nachdem Sie das Formular “ Create project “ abgeschickt haben, erhalten Sie eine Liste von Befehlen für die Arbeit mit Ihrem Repository. Überprüfen Sie diese und wechseln Sie zur CLI. Klonen Sie das gesamte CloudFerro K8s Samples Repo und extrahieren Sie dann den Unterordner mit dem Namen HelloWorld-Docker-image-Flask. Der Übersichtlichkeit halber benennen wir den Inhalt in einen neuen Ordner namens GitLabCI-sample um. Erstellen Sie den Ordner mit

mkdir ~/GitLabCI-sample

falls Sie diesen Artikel zum ersten Mal durcharbeiten, damit der Ordner für die folgenden Befehle bereit ist:

git clone https://github.com/CloudFerro/K8s-samples
mv ~/K8s-samples/HelloWorld-Docker-image-Flask/* ~/GitLabCI-sample
rm K8s-samples/ -rf

Nach der obigen Abfolge von Schritten erhalten wir den Ordner GitLabCI-sample mit den drei Dateien:

  • app.py, also den Code unserer Python-Flask-Anwendung,

  • ein Dockerfile und

  • die Datei mit den Abhängigkeiten requirements.txt.

Wir können dann in diesen Ordner wechseln, das git-Repository initialisieren, lokal committen und mit den folgenden Befehlen (ersetzen Sie Domain und Benutzername) an die Gegenstelle übertragen:

cd GitLabCI-sample
git init
git remote add origin [email protected]:myusername/GitLabCI-sample.git
git add .
git commit -m "First commit"
git push origin master

In den meisten Fällen wird der Benutzername myusername hier einfach root sein..

Wenn wir die GitLab-Benutzeroberfläche aufrufen, sehen wir, dass unsere Änderungen übertragen wurden:

../_images/image-2024-4-26_17-57-57.png

Schritt 3 Definieren Sie Umgebungsvariablen in Ihrem DockerHub-Konto auf GitLab

Wir möchten eine CI/CD-Pipeline erstellen, die bei einem neuen Commit ein Docker-Image unserer Anwendung erstellt und es an die Docker Hub Container-Registry sendet. Wir verwenden Umgebungsvariablen in GitLab, um die Verbindung mit der Docker-Registry zu ermöglichen. Verwenden Sie die folgenden Keys und Werte:

CI_COMMIT_REF_SLUG=latest
CI_REGISTRY=https://index.docker.io/v1/
CI_REGISTRY_IMAGE=index.docker.io/yourdockerhubuser/gitlabci-sample
CI_REGISTRY_USER=yourdockerhubuser
CI_REGISTRY_PASSWORD=yourdockerhubrepo

Die ersten beiden, CI_COMMIT_REF_SLUG und CI_REGISTRY sind für DockerHub fest codiert. Die anderen drei sind:

CI_REGISTRY_IMAGE

Der Name des zu erstellenden Docker-Images. Geben Sie Ihren Benutzernamen für die Docker Hub-Seite ein (yourdockerhubuser). Wenn der Benutzername beispielsweise paultur ist, lautet das Image in der Docker-Registrierung /paultur/gitlabci-sample, wie am Ende dieses Artikels zu sehen ist.

CI_REGISTRY_USER

Geben Sie yourdockerhubuser ein, was wiederum Ihr Benutzername in Docker Hub ist..

CI_REGISTRY_PASSWORD

Geben Sie * yourdockerhubrepo ein, was Ihr Kontopasswort oder ein speziell erstelltes Zugangs-Token sein kann. Um ein solches Token zu erstellen, siehe Option Account-Settings –> Security auf der Docker-Website:

../_images/new_access_token.png

Zurück zu GitLab UI, aus dem Menü Settings in der Projektansicht, gehen Sie zum Untermenü CI/CD.:

../_images/select_ci_cd_option.png

Blättern Sie nach unten zum Abschnitt „Variables“ und füllen Sie die entsprechenden Formulare aus. In der grafischen Benutzeroberfläche sieht das ähnlich aus wie hier:

../_images/image-2024-4-29_12-56-40.png

Sobald die Werte der Variablen eingerichtet sind, können wir sie in unserer CI/CD-Pipeline verwenden.

Schritt 4 Erstellen einer Pipeline zum Aufbau des Docker-Images Ihrer Anwendung mit Kaniko

Die CI/CD-Pipeline, die wir hier in GitLab erstellen, hat nur den Auftrag,

  • ein Image zu erstellt und

  • es an die Docker-Image-Registry zu senden.

In realen Szenarien würden Pipelines auch zusätzliche Aufgaben enthalten, z.B. Unit- oder Integrationstests.

GitLab erkennt, dass ein Repository/Projekt für die Implementierung einer CI/CD-Pipeline konfiguriert ist, wenn die Datei .gitlab-ci.yml im Stammverzeichnis des Projekts vorhanden ist. Man könnte CI/CD auch über die GitLab-Benutzeroberfläche (Menüeintrag CI/CD → Pipelines) auf das Projekt anwenden, indem man eine der mitgelieferten Standardvorlagen verwendet. Das Ergebnis ist jedoch ebenfalls das Hinzufügen einer speziell konfigurierten .gitlab-ci.yml-Datei zum Stamm des Projekts.

Erstellen Sie nun eine Datei .gitlab-ci.yml mit dem unten angegebenen Inhalt und legen Sie sie in den Ordner GitLabCI-sample. Die Datei enthält die Konfiguration unserer Pipeline und definiert einen einzelnen Job namens docker_image_build.

.gitlab-ci.yml

docker_image_build:
  image:
    name: gcr.io/kaniko-project/executor:v1.14.0-debug
    entrypoint: [""]
  script:
    - echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\" }}}" > /kaniko/.docker/config.json
    - >-
      /kaniko/executor
      --context "${CI_PROJECT_DIR}"
      --cache=false
      --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
      --destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}"

Sobald Änderungen an unserem Projekt an GitLab übertragen werden, wird die CI/CD-Pipeline automatisch gestartet.

Die Aufträge werden vom GitLab-Runner ausgeführt. Wenn Sie eine GitLab-Instanz unter der Voraussetzung Nr. 3 Lokale Version von GitLab verfügbar verwenden, wurde der Standard-Runner bereits im Cluster bereitgestellt. In diesem Fall stellt der Runner einen kurzlebigen Pod bereit, der für die Ausführung dieser speziellen Pipeline bestimmt ist. Einer der im Pod ausgeführten Container basiert auf dem Kaniko-Image und wird zum Erstellen des Docker-Images unserer Anwendung verwendet.

Es gibt zwei Schlüsselbefehle im script-key, die beim Start des Kaniko-Containers ausgeführt werden. Beide übernehmen Werte aus den Umgebungsvariablen, die wir zuvor in GitLab eingegeben haben.

Ausfüllen und Speichern des Inhalts einer standardisierten Konfigurationsdatei

Der erste Befehl füllt den Inhalt von config.json aus und speichert ihn. Dabei handelt es sich um eine standardisierte Konfigurationsdatei, die für die Authentifizierung bei DockerHub verwendet wird.

Erstellen und veröffentlichen des Container-Image auf DockerHub

Mit dem zweiten Befehl wird das Container-Image erstellt und auf DockerHub veröffentlicht.

Step 5 Auslösen der Pipeline zum Aufbau des Docker-Image

Ein Commit löst die Ausführung der Pipeline aus. Nachdem Sie die Datei hinzugefügt haben, veröffentlichen Sie die Änderungen im Repository mit den folgenden Befehlen:

git add .
git commit -m "Add .gitlab-ci.yml"
git push origin master

Wenn wir nach diesem Push zum CI/CD-Bildschirm unseres Projekts wechseln, sollten wir sehen, dass die Pipeline zunächst in Betrieb ist und anschließend abgeschlossen wird:

../_images/image-2024-4-29_14-13-1.png

Auch in unserer Docker-Registry sehen wir, dass das Image veröffentlicht wurde:

../_images/image-2024-4-29_14-16-12.png

Was als nächstes zu tun ist

Fügen Sie z.B. Ihre Unit- und Integrationstests zu dieser Pipeline hinzu. Sie können als zusätzliche Schritte in der Datei gitlab-ci.yml definiert werden. Eine vollständige Referenz finden Sie hier: https://docs.gitlab.com/ee/ci/yaml/