theHacker's Blog
– It's just a glitch in the Matrix –

GitLab-Runner installieren

Neulich habe ich ein GitLab aufgesetzt. Um das CI-/CD-System von GitLab nutzen zu können, ist ein GitLab-Runner notwendig. Der Runner ist dafür zuständig, die Aufgaben (Jobs) abzuarbeiten und die Ergebnisse an das GitLab zurückzusenden.

Heute zeige ich euch, wie man einen GitLab-Runner installiert.

Der Einfachheit halber installiere ich den GitLab-Runner direkt auf derselben Maschine, wo das GitLab auch läuft. Prinzipiell kann (und wird für gewöhnlich) ein Runner auf einer beliebigen Maschine installiert werden. Dies ist dann notwendig, wenn mehr zu tun ist und somit mehrere Runner benötigt werden. Auch werden mehrere Runner benötigt, wenn man Jobs auf verschiedenen Plattformen aufführen möchte, z. B. eine Webseite einmal mit einem Edge-Browser unter Windows und einmal mit einem Firefox-Browser unter Linux zu testen.

Executors

Ein GitLab-Runner implementiert verschiedene Executors. Ein Executor bestimmt, wie der Runner seine Jobs ausführt. Eine Übersicht, welche Executors zur Auswahl standen, ist im GitLab-Handbuch aufgelistet.

In diesem Artikel verwende ich den Shell-Executor. Er führt seine Jobs einfach auf einer Shell aus. Dieser Executor ist der, der am einfachsten zu installieren ist, weil er sonst keine Konfiguration und keine extra Schritte benötigt. Wir müssen uns aber vor Augen halten, dass er entsprechend auch viele Nachteile hat.

Der Runner kann damit nur Tools nutzen, die auf der Maschine des Runners installiert sind. Es ist damit nicht möglich, weitere Software zu installieren. Wir werden das später im Beispiel sehen.

Runner installieren

Wir werden nun den GitLab-Runner installieren. Hierzu folgen wir der Anleitung im GitLab-Handbuch.

  • Installationsscript herunterladen und ausführen:
    • curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
    • Damit werden die Paketquellen für die Installation des GitLab-Runners eingerichtet.
  • GitLab-Runner-Paket installieren:
    • apt install gitlab-runner

Der Runner ist damit installiert.

Runner im GitLab registrieren

Der Runner muss nun im GitLab registriert werden, damit ihm Jobs zugewiesen werden können. Hierzu folgen wir der Anleitung im GitLab-Handbuch.

Im GitLab öffnen wir im Adminbereich die Unterseite „Übersicht / Runners“. Aktuell sind noch keine Runner definiert. Auf der rechten Seite sehen wir die Anweisungen und Informationen, die wir für die Registrierung unseres neuen Runners brauchen.

Auf dem GitLab-Server starten wir mit der Befehlszeile gitlab-runner register den Registrierungsprozess.

  • Zuerst werden wir nach der URL zum GitLab und dem Registrierungstoken gefragt. Diese Informationen finden wir auf der Adminseite.
  • Danach werden wir nach einer Beschreibung gefragt. Damit können wir unseren Runner identifizieren, wenn wir mehrere haben.
  • Anschließend können wir noch Tags vergeben. Mit Tags können wir später steuern, dass bestimmte Jobs nur auf bestimmten Runnern laufen können. Ein Beispiel könnte sein, dass wir auf einem bestimmten Runner ImageMagick installiert haben. Dann würde dieser Runner mit einem ImageMagick-Tag versehen. Jobs, die ImageMagick brauchen, würden das mit diesem Tag signalisieren und GitLab würde dann diesen speziellen Runner zuweisen.
    • In unserem Beispiel lassen wir das Feld leer.
    • Tipp: Beschreibung und Tags kann man im Nachhinein auch noch über die Admin-Oberfläche des GitLab ändern.
  • Zum Schluss müssen wir den Executor wählen. Wir wählen wie bereits erklärt den Shell-Executor.

Im GitLab können wir den Runner nun sehen. Damit sind wir startklar für eine erste kleine Aufgabe 🙂

Der Runner führt einen Job aus

Um den Runner zu testen, legen wir nun ein Projekt mit einer .gitlab-ci.yml-Konfigurationsdatei an. Damit bauen wir eine dreistufige Pipeline mit insgesamt drei Jobs. Mit den ersten beiden Jobs führen wir ein traditionelles „Hello World“ aus. Mit dem letzten Job sehen wir uns genauer an, was wir mit dem Runner alles tun können bzw. was nicht geht. Ich erkläre dies später genauer.

stages:
- step1
- step2
- step3

say-hello:
  stage: step1
  script: echo "Hello"

say-world:
  stage: step2
  script: echo "World"

list-files:
  stage: step3
  script:
  - pwd
  - ls
  - ls /opt/gitlab
  - whoami
  - apt install imagemagick
  allow_failure: true

Sofort nachdem wir die Datei eingecheckt haben, fängt GitLab sofort an, die Pipeline abzuarbeiten. Im Projekt finden wir alles unter „CI / CD / Pipelines“. Wir sehen, dass die ersten beiden Jobs say-hello und say-world erfolgreich durchgeführt wurden.

Die Schwächen des Shell-Executors

Sehen wir uns nun den dritten Job genauer an. Per Klick auf den Job sehen wir Details der Abarbeitung. GitLab hat unseren Runner benutzt (wir sehen die Runner-Beschreibung „Shell-Runner auf GitLab“). Der Runner checkt den Quellcode aus dem Git-Repository aus und arbeitet dann die Befehlszeilen ab, die wir unter script definiert haben.

Mit den ersten beiden Anweisungen pwd und ls zeigen wir an, in welchem Arbeitsverzeichnis wir uns befinden und die darin befindlichen Dateien. Wir sehen, dass der GitLab-Runner in einem Unterzeichnis von /home weitere Unterverzeichnisse für das jeweilige Projekt angelegt hat. Das Verzeichnis selber ist leer, weil wir außer der .gitlab-ci.yml, die im ls nicht sichtbar ist, keinen weiteren Code eingecheckt haben.

Mit ls /opt/gitlab sehen wir, dass unsere Jobs auf derselben Maschine ausgeführt werden, wie das GitLab selber. Das ist insofern gefährlich, weil wir keine Isolierung haben. Lediglich die Dateirechte schützen uns davor, böse Sachen anzustellen. Arbeiten mehrere Jobs parallel, können leicht Komplikationen auftreten.

Stellen wir uns einen Test vor, der ein temporäres Verzeichnis /tmp/demo-job anlegt, irgendeine Programmlogik ausführt, am Ende eine Ergebnisdatei results.txt erwartet und zum Aufräumen die Datei und das Verzeichnis wieder weglöscht. Sobald zwei dieser Jobs parallel ausgeführt werden, gibt es Testfehlschläge, weil z. B. Job 1 das Verzeichnis grade weggelöscht hat, während Job 2 es eben angelegt hatte und nun erwartet, dass es noch da ist, wenn die Ergebnisdatei erstellt wird. Eine mögliche Lösung könnte sein, dass jeder Job eine eindeutige ID im Verzeichnisnamen verwendet, um die Tests zu isolieren.

Schon dieses einfache Beispiel zeigt, dass wir mit dem Shell-Executor sehr aufpassen müssen, was wir tun.

Sehen wir uns nun die letzten beiden Anweisungen an. whoami verrät uns den UNIX-Nutzer, als der die Jobs ausgeführt werden. Wir sehen, dass wir ein spezieller gitlab-runner-Nutzer sind. Versuchen wir, mit apt weitere Software zu installieren, scheitert dies, weil nur root derartige Änderungen am System durchführen kann. In weiser Voraussicht habe ich für den Job allow_failure: true konfiguriert. Damit zeigt GitLab die Pipeline am Ende nicht als totalen Fehlschlag an.

Ausgabe von Job 3

Zusammenfassung

Nochmal zusammengefasst, was wir erreicht haben:

  • Wir haben einen GitLab-Runner installiert und ihn im GitLab bekannt gemacht.
  • Wir haben den einfachen Shell-Executor verwendet und die Schwächen von diesem Executor angesprochen.
  • Zum Schluss haben wir in einer Beispiel-Pipeline eben diese Schwächen direkt beobachten können.

In einem weiteren Artikel werde ich den Docker-Executor vorstellen, mit dem die angesprochenen Probleme umgangen werden.

22. Juni 2019

Schreib einen Kommentar hierzu

Deine eMail-Adresse wird nicht veröffentlicht.