Tutorials  /  Kubernetes

GitLab Runner auf Kubernetes installieren: Helm-Chart, Token-Secret und erste Pipeline

Ccentron Redaktion · Oktober 2026 ·29 Min. Lesezeit ·Kubernetes, Tutorial

Mit dem offiziellen Helm-Chart gitlab/gitlab-runner installierst du einen GitLab Runner in einem eigenen Namespace deines Kubernetes-Clusters. Das Token des Runners liegt dabei in einem Kubernetes-Secret, und jeder CI-Job startet als eigener Pod. Am Ende hast du einen Projekt-Runner mit eng gefassten Rechten und eine erste Pipeline, deren Job im Cluster lief.

Die Anleitung nutzt Chart 0.93.0 mit GitLab Runner 19.4.0 (Stand 1. Oktober 2026). Der Ablauf gilt laut GitLab-Dokumentation für jeden Kubernetes-Cluster, zum Beispiel für einen Managed Kubernetes Cluster von centron. Statt auf geteilten Runnern laufen deine Jobs dann auf Nodes, die du selbst dimensionierst. Dieser Beitrag ist der erste Teil einer geplanten Serie zu CI/CD auf Kubernetes. Wie du in der Pipeline Container-Images baust, ist Thema eines der folgenden Teile.

Was ist ein GitLab Runner mit Kubernetes-Executor?

Ein GitLab Runner mit Kubernetes-Executor ist ein Dienst im Cluster, der bei GitLab nach neuen CI-Jobs fragt und für jeden Job über die Kubernetes-API einen eigenen Pod startet, der nach dem Job wieder entfernt wird.

Das Helm-Chart installiert dazu ein Deployment mit einem Manager-Pod. Dieser Pod holt Jobs aktiv bei der GitLab-API ab. GitLab muss den Cluster also nicht erreichen können, umgekehrt braucht der Cluster aber ausgehenden Zugriff auf deine GitLab-Instanz. Für jeden Job legt der Manager-Pod über die Kubernetes-API einen Job-Pod an. Darin laufen mindestens zwei Container:

Container Aufgabe
build führt das script deines Jobs im angegebenen Image aus
helper klont das Repository, stellt Cache und Artefakte bereit und lädt Artefakte nach dem Job zu GitLab hoch
Service-Container nur wenn der Job oder die Runner-Konfiguration services definiert, etwa eine Datenbank für Tests
graph LR
  R["Runner-Manager-Pod im Namespace ci-runner"] -->|"fragt Jobs ab (ausgehend)"| G["GitLab-Instanz"]
  R -->|"legt Job-Pod an"| K["Kubernetes-API"]
  K --> J["Job-Pod mit den Containern build und helper"]
  J -->|"Job-Log und Artefakte"| G

Voraussetzungen

  • Kubernetes-Cluster mit Version 1.33.1 oder 1.32.4. Das sind laut centron-Docs die Versionen, die du beim centron Managed Kubernetes aktuell wählen kannst, 1.33.1 ist die empfohlene (abgerufen am 1. Oktober 2026). Maßgeblich ist laut centron die Auswahl im Erstellungsdialog.
  • kubectl mit höchstens einer Minor-Version Abstand zum Cluster, bei einem 1.33-Cluster also 1.32 bis 1.34. kubectl muss mit dem Cluster verbunden sein. Bei centron lädst du die kubeconfig in der Cluster-Ansicht über „Download Config File“ herunter, setzt die Dateirechte mit chmod 600 und verweist mit export KUBECONFIG=... darauf. Die Schritte stehen unter Mit dem Cluster verbinden. Wenn kubectl noch fehlt, hilft das Tutorial kubectl installieren und Kubernetes-Cluster verwalten.
  • Helm 3. Die GitLab-Dokumentation für Runner 19.4.0 beschreibt die Befehle für Helm 3. Helm 3 bekommt laut Helm-Projekt nur noch bis 10. Februar 2027 Sicherheitsupdates, aktuelle Hauptversion ist Helm 4.
  • GitLab 19.4 (Self-Managed) oder gitlab.com, und ein Projekt, in dem du die Rolle Maintainer hast. gitlab.com wird laufend aktualisiert, dort empfiehlt GitLab die jeweils neueste Runner-Version. Die Version major.minor des Runners sollte laut GitLab zur Version von GitLab passen. Ältere oder neuere Runner können funktionieren, einzelne Funktionen stehen dann aber unter Umständen nicht oder nicht korrekt zur Verfügung. Läuft deine Instanz mit einer anderen Version, wählst du im Abschnitt zur Installation eine passende Chart-Version.
  • Ausgehender HTTPS-Zugriff vom Cluster auf deine GitLab-Instanz und auf die Registries der verwendeten Images. Das Runner-Image kommt laut values.yaml des Charts von registry.gitlab.com, das Job-Image alpine:3.24 von Docker Hub. Der Tag 3.24 zeigt auf Alpine 3.24.2 (Docker Hub, Stand 18. September 2026).

Zur Abgrenzung beim centron Managed Kubernetes: Laut centron-Docs betreibt centron Control Plane, Cluster-Netzwerk und Cluster Autoscaler. Namespaces, RBAC-Regeln, Secrets und selbst installierte Software wie den GitLab Runner verantwortest du selbst.

K8

Passende Infrastruktur bei centron

Vom Container zum Cluster: Managed Kubernetes von centron mit Control Plane und Traffic inklusive. Managed Kubernetes ansehen →

Projekt-Runner in GitLab anlegen

Den Runner legst du zuerst in GitLab an, denn erst dabei entsteht das Runner-Authentifizierungstoken, mit dem sich der Runner im Cluster später bei GitLab anmeldet.

  1. Öffne dein Projekt in GitLab und wähle in der linken Seitenleiste Settings > CI/CD.
  2. Klappe den Abschnitt Runners auf und wähle Create project runner.
  3. Wähle als Betriebssystem Linux.
  4. Trage im Feld Tags den Tag kubernetes ein. Lass Run untagged ausgeschaltet. Dann übernimmt der Runner nur Jobs, die diesen Tag ausdrücklich anfordern.
  5. Optional: Gib im Feld Runner description eine Beschreibung ein, zum Beispiel k8s-ci-runner.
  6. Wähle Create runner.

GitLab zeigt dir danach das Runner-Authentifizierungstoken. Es beginnt mit glrt-. Kopiere es sofort, denn GitLab zeigt es nur kurz an. Die weiteren Installationshinweise auf der Seite brauchst du nicht, denn die Registrierung übernimmt später das Helm-Chart.

Tags, „Run untagged“, die Sperre für andere Projekte („locked“), geschützte Branches („protected“) und das maximale Job-Timeout stellst du ab jetzt nur noch in GitLab ein. Mit einem Authentifizierungstoken wirken diese Werte in der values.yaml laut GitLab-Dokumentation nicht. Setzt du sie trotzdem, verwirft das Startskript von Chart 0.93.0 Tags, „Run untagged“, locked und protected stillschweigend. Ein gesetztes runners.maximumTimeout lässt die Registrierung dagegen mit der Meldung Runner configuration ... is reserved abbrechen.

Zwei Varianten zur Einordnung: Soll der Runner allen Projekten einer Gruppe zur Verfügung stehen, legst du einen Gruppen-Runner unter Build > Runners > Create group runner an. Dafür brauchst du die Rolle Owner in der Gruppe, der restliche Ablauf bleibt gleich. Der ältere Weg über ein Registrierungstoken gilt laut GitLab als Legacy und wird nicht empfohlen. Seit GitLab 17.0 können Administratoren und Gruppen-Owner ihn abschalten.

Namespace und Token-Secret anlegen

Für den Runner legst du einen eigenen Namespace an und speicherst das Token dort in einem Kubernetes-Secret, statt es im Klartext in die values.yaml zu schreiben.

Konsole
$ kubectl create namespace ci-runner
$ read -rs RUNNER_TOKEN
$ kubectl create secret generic runner-auth \
    --namespace ci-runner \
    --from-literal=runner-registration-token="" \
    --from-literal=runner-token="$RUNNER_TOKEN"
$ unset RUNNER_TOKEN

Was die Befehle tun:

  • read -rs RUNNER_TOKEN wartet auf deine Eingabe. Füge das Token ein und bestätige mit Enter. Die Eingabe erscheint nicht auf dem Bildschirm, und weil das Token nicht im Befehl selbst steht, landet es auch nicht in der Shell-Historie.
  • Das Secret runner-auth braucht genau zwei Schlüssel. Das Chart liest beide aus dem Secret und übergibt runner-token beim Start als Token an den Runner. runner-registration-token bleibt laut GitLab-Dokumentation aus Kompatibilitätsgründen ein leerer String. Erlaubt dein Werkzeug zur Secret-Verwaltung keinen leeren Wert, darfst du einen beliebigen Text eintragen. Er wird ignoriert, solange runner-token gesetzt ist.
  • unset RUNNER_TOKEN entfernt das Token wieder aus deiner Shell.

Legst du das Secret stattdessen als YAML-Manifest mit Base64-Werten an, achte darauf, dass am Token kein Zeilenumbruch hängt, also echo -n beim Kodieren. Sonst meldet der Runner den Fehler invalid header field for "Private-Token".

Ein Kubernetes-Secret ist nur Base64-kodiert, nicht verschlüsselt. Wer im Namespace ci-runner Secrets lesen darf, kann das Token auslesen. Deshalb bekommt der Runner einen eigenen Namespace, in dem außer dem Runner und seinen Job-Pods nichts anderes läuft.

Welche Rechte braucht der GitLab Runner im Cluster?

Der GitLab Runner braucht im eigenen Namespace nur Rechte auf Pods, deren Unterressourcen attach, exec und log sowie auf Secrets, Services, Service Accounts und Events, aber keine clusterweiten Rechte.

Am einfachsten wäre es, im Chart nur rbac.create: true zu setzen. Ohne eigene Regeln unter rbac.rules erzeugt das Chart dann aber eine Role mit allen Verben auf allen Ressourcen der Core-API-Gruppe im Namespace. Der Runner dürfte damit zum Beispiel jedes Secret und jede ConfigMap im Namespace lesen und ändern. Die Executor-Dokumentation nennt stattdessen eine Liste der nötigen Rechte. Für diese Anleitung reicht dieser Ausschnitt:

Ressource Verben Wofür
pods create, delete, get, list, watch Job-Pods anlegen und entfernen. list und watch braucht der Informer, mit dem der Runner ab Version 17.9 Änderungen am Job-Pod schneller erkennt
pods/attach create, delete, get, patch Befehle per attach ausführen. Das ist der Standard, weil das Feature-Flag FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY standardmäßig auf false steht
pods/exec create, delete, get, patch laut Rechtetabelle ohne Bedingung nötig
pods/log get, list laut Rechtetabelle bei der attach-Strategie nötig
secrets create, delete, get, update laut Rechtetabelle ohne Bedingung nötig
serviceaccounts get laut Rechtetabelle ohne Bedingung nötig
services create, get laut Rechtetabelle ohne Bedingung nötig
events list Kubernetes-Warnungen zum Job-Pod ins Job-Log schreiben (print_pod_warning_events, standardmäßig an)

Fehlen list oder watch auf Pods, schreibt der Runner eine Warnung ins Log und verfolgt den Job-Pod auf dem älteren Weg weiter. watch auf Events brauchst du nur, wenn du das Feature-Flag FF_PRINT_POD_EVENTS einschaltest. Weitere Rechte aus der Tabelle, etwa auf Namespaces, ConfigMaps oder PersistentVolumeClaims, gehören zu optionalen Funktionen wie einem eigenen Namespace je Job und sind hier nicht nötig. Die vollständige Tabelle steht in der Dokumentation zum Kubernetes-Executor für Runner 19.4.0.

Den Schalter rbac.clusterWideAccess lässt du auf dem Standardwert false. Dann legt das Chart eine Role im Namespace an und keine ClusterRole. Der Runner darf Job-Pods damit nur in diesem Namespace anlegen, und genau dorthin schickt sie die Zeile namespace in der Runner-Konfiguration.

Auch mit engen Rechten bleibt eine Angriffsfläche, denn der Runner soll ja Pods mit dem Image starten, das ein Job verlangt. Laut GitLab kann jede Person mit der Rolle Developer im Projekt über eine Pipeline die Umgebung des Runners gefährden, ob absichtlich oder nicht. Gib deshalb nur Personen Schreibzugriff auf die Pipeline, denen du Code im Cluster anvertraust. Forks bekommen Projekt-Runner laut GitLab nicht automatisch. Mit allowed_images in der Runner-Konfiguration kannst du die erlaubten Images zusätzlich einschränken.

values.yaml schreiben

In der Datei runner-values.yaml legst du fest, mit welcher GitLab-Instanz sich der Runner verbindet, welche Rechte er im Namespace bekommt und mit welchen Ressourcen die Job-Pods starten.

yaml
gitlabUrl: "<gitlab-url>"
concurrent: 4
rbac:
  create: true
  rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["create", "delete", "get", "list", "watch"]
    - apiGroups: [""]
      resources: ["pods/attach", "pods/exec"]
      verbs: ["create", "delete", "get", "patch"]
    - apiGroups: [""]
      resources: ["pods/log"]
      verbs: ["get", "list"]
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["create", "delete", "get", "update"]
    - apiGroups: [""]
      resources: ["serviceaccounts"]
      verbs: ["get"]
    - apiGroups: [""]
      resources: ["services"]
      verbs: ["create", "get"]
    - apiGroups: [""]
      resources: ["events"]
      verbs: ["list"]
serviceAccount:
  create: true
runners:
  secret: runner-auth
  config: |
    [[runners]]
      [runners.kubernetes]
        namespace = "{{ default .Release.Namespace .Values.runners.jobNamespace }}"
        image = "alpine:3.24"
        cpu_request = "500m"
        memory_request = "512Mi"
        cpu_limit = "1"
        memory_limit = "1Gi"
        helper_cpu_request = "100m"
        helper_memory_request = "128Mi"

Die Schlüssel im Einzelnen:

  • gitlabUrl: Ersetze <gitlab-url> durch die vollständige URL deiner GitLab-Instanz mit Protokoll, also https://gitlab.com oder zum Beispiel https://gitlab.example.com bei Self-Managed.
  • concurrent: Wie viele Jobs der Runner höchstens gleichzeitig ausführt. Der Standardwert des Charts ist 10. Mehr dazu im Abschnitt zu gleichzeitigen Jobs.
  • rbac.create und rbac.rules: Das Chart legt eine Role mit genau diesen Regeln und ein RoleBinding an. Die Regeln entsprechen der Tabelle im vorigen Abschnitt.
  • serviceAccount.create: Das Chart legt einen eigenen ServiceAccount an, an den die Role gebunden wird. Setzt du rbac.create ohne diesen Schlüssel, warnt das Chart bei der Installation.
  • runners.secret: Name des Secrets mit dem Token. Das Token steht damit nicht in der values.yaml. Den Schlüssel runnerToken lässt du deshalb weg, und runnerRegistrationToken gehört zum Legacy-Weg.
  • runners.config: Die eigentliche Runner-Konfiguration im TOML-Format. Das Chart wertet den Text als Helm-Template aus. Die Zeile namespace übernimmt den Release-Namespace, die Job-Pods laufen also in ci-runner.
  • image: Standard-Image für Jobs, die selbst kein image angeben. Ein fester Tag statt alpine ohne Tag hält nachvollziehbar, womit ein Job lief.
  • cpu_request, memory_request, cpu_limit, memory_limit: Requests und Limits für den Container build. helper_cpu_request und helper_memory_request gelten für den Container helper. Die Werte sind Beispiele, passe sie an deine Jobs an.

Den Schalter privileged setzt du nicht. Privilegierte Container braucht man zum Beispiel für Image-Builds mit Docker-in-Docker. Laut GitLab kann ein Job damit vollen Root-Zugriff auf den Host erlangen. Image-Builds sind deshalb Thema eines folgenden Teils dieser Serie.

GitLab Runner mit Helm installieren

Mit Helm fügst du das Chart-Repository von GitLab hinzu, prüfst die verfügbaren Chart-Versionen und installierst den Runner mit fest angegebener Version in den Namespace ci-runner.

Konsole
$ helm repo add gitlab https://charts.gitlab.io
$ helm repo update gitlab
$ helm search repo -l gitlab/gitlab-runner

Chart und Runner haben getrennte Versionsnummern. Die Liste zeigt deshalb zwei Spalten: CHART VERSION ist die Version des Helm-Charts, APP VERSION die Version des Runners. Für diese Anleitung suchst du die Zeile mit Chart 0.93.0 und App-Version 19.4.0. Läuft deine GitLab-Instanz mit einer anderen Version, wählst du die Chart-Version, deren App-Version zu major.minor deiner GitLab-Version passt.

Wenn du vorher sehen willst, welche Manifeste Helm erzeugt, hängst du an den folgenden Befehl --dry-run --debug an. Dann ändert Helm nichts im Cluster. Installiert wird so:

Konsole
$ helm install --namespace ci-runner gitlab-runner \
    -f runner-values.yaml \
    gitlab/gitlab-runner \
    --version 0.93.0

gitlab-runner ist der Name des Releases. Unter diesem Namen aktualisierst und entfernst du die Installation später. Weil der Release-Name mit dem Chart-Namen beginnt, heißt auch das Deployment gitlab-runner. Nach der Installation gibt Helm die Hinweise des Charts aus. Darin steht die GitLab-URL, gegen die sich der Runner registriert. Fehlt gitlabUrl, warnt das Chart an dieser Stelle.

Prüfen, ob der Runner online ist

Ob die Installation geklappt hat, erkennst du an drei Stellen, nämlich am Pod-Status im Cluster, am Log des Runners und am Status des Runners in GitLab.

Konsole
$ kubectl get pods --namespace ci-runner
$ kubectl logs deployment/gitlab-runner --namespace ci-runner

Woran du den Erfolg erkennst:

  • Pod: Im Namespace läuft ein Pod des Deployments gitlab-runner mit Status Running. Bis er als bereit gilt, kann gut eine Minute vergehen, weil die Readiness-Probe des Charts standardmäßig erst nach 60 Sekunden startet.
  • Log: Das Startskript des Charts registriert den Runner mit dem Token und schreibt dabei Zeilen wie Registration attempt 1 of 30. Es versucht es bis zu 30-mal im Abstand von 5 Sekunden. Danach startet der Runner und fragt GitLab nach Jobs. Meldungen mit forbidden oder reserved führen dich zur Fehlerbehebung weiter unten.
  • GitLab: Unter Settings > CI/CD > Runners steht dein Runner unter den zugewiesenen Projekt-Runnern. Der Status online bedeutet, dass der Runner in den letzten zwei Stunden Kontakt zu GitLab hatte. never_contacted heißt, dass er sich noch nie gemeldet hat.

Den Namen des Pods zeigt GitLab in der Detailansicht des Runners nicht an. Das ist laut GitLab ein bekanntes Problem des neuen Registrierungswegs mit dem Helm-Chart (Issue 423523).

Erste Pipeline auf dem Cluster ausführen

Eine minimale .gitlab-ci.yml mit einem einzigen Job reicht, um zu prüfen, ob GitLab den Job an deinen Runner gibt und der Runner dafür einen Pod im Cluster startet.

Lege im Wurzelverzeichnis deines Repositorys die Datei .gitlab-ci.yml mit diesem Inhalt an:

yaml
cluster-check:
  tags:
    - kubernetes
  image: alpine:3.24
  script:
    - cat /etc/os-release
    - uname -a

tags wählt den Runner aus. Ein Runner übernimmt einen Job nur, wenn er jeden Tag hat, den der Job verlangt. Tags unterscheiden Groß- und Kleinschreibung. image legt das Image für den Container build fest, script die Befehle. Weil keine stage angegeben ist, läuft der Job in der Standard-Stage test.

Öffne vor dem Commit ein zweites Terminal und beobachte den Namespace:

Konsole
$ kubectl get pods --namespace ci-runner --watch

Committe und pushe die Datei. GitLab startet die Pipeline, du findest sie unter Build > Pipelines. Im Terminal erscheint neben dem Runner-Pod ein neuer Pod für den Job. Er läuft, solange der Job läuft, und verschwindet danach wieder. Im Job-Log in GitLab siehst du die Ausgabe der beiden Befehle, darunter die Alpine-Version aus /etc/os-release. Mit Strg+C beendest du --watch.

Wie viele Jobs laufen gleichzeitig?

Wie viele Jobs gleichzeitig laufen, begrenzt der Wert concurrent in der values.yaml, und ob die Job-Pods dafür Platz finden, entscheiden ihre Ressourcen-Requests und die freie Kapazität der Nodes.

concurrent ist eine Obergrenze für alle Jobs dieses Runners zusammen. Der Chart-Standard ist 10, in dieser Anleitung steht der Wert auf 4. Wie oft der Runner GitLab nach neuen Jobs fragt, regelt checkInterval, der Standard sind 3 Sekunden.

Jeder Job-Pod fordert die Requests von build und helper zusammen an. Mit den Beispielwerten sind das 600m CPU und 640Mi Arbeitsspeicher je Job. Bei 4 gleichzeitigen Jobs reserviert der Runner also bis zu 2,4 CPU und 2560Mi (2,5 GiB) Arbeitsspeicher. Findet ein Job-Pod keinen Node mit genug freier Kapazität, bleibt er im Status Pending.

Beim centron Managed Kubernetes kannst du dafür den Cluster Autoscaler je Node Pool einschalten. Können Pods mangels Kapazität nicht platziert werden, stellt er laut centron-Docs zusätzliche Nodes bereit. Dauerhaft wenig ausgelastete Nodes entfernt er wieder. Er entscheidet anhand der Requests und nicht anhand der tatsächlichen Auslastung. Ohne Requests in der Runner-Konfiguration kann er den Bedarf deiner Jobs deshalb nicht richtig einschätzen. Das Maximum des Node Pools begrenzt die Kosten nach oben. Wie du Minimum und Maximum festlegst, steht unter Autoscaling aktivieren.

Ein neuer Node braucht laut centron-Docs einige Minuten. Der Runner wartet standardmäßig 180 Sekunden darauf, dass er den Job-Pod erreicht (poll_timeout). Rechnest du damit, dass Jobs öfter auf neue Nodes warten, erhöhst du den Wert unter [runners.kubernetes], zum Beispiel auf poll_timeout = 600.

Fehlerbehebung

Runner bleibt bei never_contacted

Lies zuerst das Log mit kubectl logs deployment/gitlab-runner --namespace ci-runner. Typische Ursachen:

  • Token falsch oder nicht vollständig kopiert. Das Token muss mit glrt- beginnen. Lösche das Secret mit kubectl delete secret runner-auth --namespace ci-runner, lege es wie oben mit dem richtigen Token neu an und starte den Runner danach neu, zum Beispiel mit kubectl rollout restart deployment/gitlab-runner --namespace ci-runner.
  • Schlüssel im Secret fehlen. Fehlt runner-token oder runner-registration-token, kann Kubernetes das Secret nicht einbinden. Der Pod bleibt dann in ContainerCreating, und kubectl describe pod zeigt unter Events eine Meldung FailedMount mit dem Hinweis references non-existent secret key. Prüfe die Schlüsselnamen im Secret runner-auth.
  • Zeilenumbruch am Token. Die Meldung invalid header field for "Private-Token" deutet auf ein Token mit angehängtem \n hin.
  • Reservierte Werte in der values.yaml. Runner configuration ... is reserved heißt, dass die Registrierung Einstellungen mitschickt, die bei einem Authentifizierungstoken nur GitLab festlegen darf. Bei Chart 0.93.0 ist das typischerweise runners.maximumTimeout in der values.yaml. Entferne den Wert und setze das Timeout in GitLab.
  • Falsche gitlabUrl oder kein Netzweg. Prüfe die URL mit Protokoll und ob der Cluster die GitLab-Instanz per HTTPS erreicht. Nutzt deine Self-Managed-Instanz ein selbst signiertes Zertifikat, übergibst du es dem Chart als Secret über certsSecretName.

Job startet nicht und wartet auf einen Runner

  • Der Job verlangt einen Tag, den der Runner nicht hat, oder er hat gar keine tags und „Run untagged“ ist aus. Gleiche die Tags in der .gitlab-ci.yml und in den Runner-Einstellungen ab.
  • Der Runner ist pausiert. Setze ihn unter Settings > CI/CD > Runners mit Resume fort.
  • Die Pipeline läuft in einem Fork. Projekt-Runner sind dort nicht automatisch aktiviert.

forbidden im Job-Log oder Runner-Log

Eine Meldung wie secrets is forbidden: User "system:serviceaccount:..." cannot create resource "secrets" zeigt eine fehlende Regel in der Role. Vergleiche rbac.rules mit der Tabelle oben, korrigiere die values.yaml und spiele sie mit helm upgrade ein (siehe unten). Schaltest du Feature-Flags oder optionale Funktionen ein, prüfe in der Rechtetabelle der Executor-Dokumentation, welche Rechte dafür dazukommen.

Job-Pod bleibt im Status Pending

Konsole
$ kubectl get pods --namespace ci-runner --field-selector status.phase=Pending
$ kubectl describe pod "<pod-name>" --namespace ci-runner

Ersetze <pod-name> durch den Namen aus der ersten Ausgabe. Im Abschnitt Events steht der Grund. Eine Meldung wie Insufficient cpu bedeutet, dass kein Node genug freie Kapazität hat. Mit aktivem Autoscaler sollte dann ein Node dazukommen. Bleibt das aus, ist laut centron-Docs das Maximum des Node Pools erreicht. Prüfe außerdem, ob ein einzelner Job-Pod mehr anfordert, als ein Node überhaupt hat. Dann hilft nur, die Requests zu senken oder größere Nodes zu wählen.

Runner aktualisieren und entfernen

Vor jedem Update und vor dem Entfernen pausierst du den Runner in GitLab und wartest, bis laufende Jobs fertig sind. Laut GitLab-Dokumentation vermeidest du so Autorisierungsfehler, wenn Jobs abgeschlossen werden. Pausieren kannst du unter Settings > CI/CD > Runners im Bereich Assigned project runners mit Pause.

Runner aktualisieren

Konsole
$ helm repo update gitlab
$ helm search repo -l gitlab/gitlab-runner
$ helm upgrade --namespace ci-runner \
    -f runner-values.yaml \
    gitlab-runner gitlab/gitlab-runner \
    --version "<chart-version>"

Ersetze <chart-version> durch die neue Chart-Version aus der Liste. Wähle sie wieder so, dass die App-Version zu deiner GitLab-Version passt. Gib die values.yaml bei jedem Upgrade mit an. Ohne -f übernimmt Helm zwar die Werte des letzten Releases, änderst du aber einzelne Werte nur mit --set, fallen alle übrigen eigenen Werte auf die Standardwerte des Charts zurück. Derselbe Befehl mit unveränderter Version spielt geänderte Werte ein, etwa neue Rechte oder Requests. Beim Neustart gibt Kubernetes dem alten Runner-Pod laut Chart-Standard bis zu 3.600 Sekunden, um laufende Jobs zu beenden. Danach setzt du den Runner in GitLab mit Resume fort.

Runner vollständig entfernen

  1. Pausiere den Runner in GitLab und warte, bis keine Jobs mehr laufen.
  2. Entferne das Helm-Release:
Konsole
$ helm uninstall gitlab-runner --namespace ci-runner
  1. Lösche den Namespace. Damit verschwinden auch das Secret runner-auth mit dem Token und eventuell übrig gebliebene Job-Pods:
Konsole
$ kubectl delete namespace ci-runner
  1. Lösche den Runner in GitLab unter Settings > CI/CD > Runners im Bereich Assigned project runners mit Remove runner und bestätige mit Remove.

Schritt 4 ist nötig, obwohl das Chart beim Beenden des Pods unregister aufruft (unregisterRunners: true ist Standard). Bei Tokens mit dem Präfix glrt- entfernt das laut Chart nur den Runner-Manager, nicht den Runner selbst.

Was bestehen bleibt: deine Datei runner-values.yaml, der Eintrag gitlab in deiner lokalen Helm-Repository-Liste und die .gitlab-ci.yml im Projekt. Jobs mit dem Tag kubernetes finden ohne Runner keinen Abnehmer mehr. Entferne den Job oder ändere die Tags, wenn du die Pipeline weiter nutzen willst.

Nächste Schritte

  • Container-Images bauen: In einem folgenden Teil der Serie geht es darum, in der Pipeline Images zu bauen, ohne dem Runner privilegierte Container zu erlauben.
  • Private Registry anbinden: Jobs, die Images aus einer privaten Registry ziehen, brauchen ein Pull-Secret. Für centron Managed Kubernetes beschreiben die Docs das unter Container Registry anbinden. In der Runner-Konfiguration verweist du mit image_pull_secrets darauf.
  • Cache einrichten: Ohne verteilten Cache startet jeder Job-Pod ohne Abhängigkeits-Cache. Das Chart kann einen S3-kompatiblen Cache einbinden. Die Zugangsdaten liegen in einem Secret, das du unter runners.cache.secretName angibst, die Einstellungen selbst stehen im Abschnitt [runners.cache] von runners.config. Die Optionen stehen in der values.yaml von Chart 0.93.0.
  • Deployen per GitOps: Wie eine Pipeline Änderungen über Git in den Cluster bringt, zeigt das Tutorial GitOps-basiertes CI/CD auf Kubernetes.
  • Überblick: Wie CI/CD-Pipelines auf centron-Infrastruktur zusammenspielen, beschreibt die Seite CI/CD-Pipelines.
Jetzt 200 € Guthaben sichern

Testen Sie Ihr Setup auf ccloud³

Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.

centron Redaktion Technische Redaktion

Das Redaktionsteam von centron schreibt Anleitungen aus dem Betriebsalltag: getestet auf unserer eigenen Plattform, betrieben im Rechenzentrum in Hallstadt bei Bamberg.

Kategorie Kubernetes
Teilen
Noch offene Fragen?

Unser Team hilft Ihnen bei Ihrem konkreten Setup weiter – von Menschen, die die Plattform selbst betreiben.

War dieses Tutorial hilfreich?

Ihre Antwort wird anonym gespeichert und hilft uns, die Tutorials zu verbessern.

Kommentare

Noch keine Kommentare – stellen Sie die erste Frage zu diesem Tutorial.

Zum Kommentieren anmelden

Kommentare stehen centron-Kunden offen. Melden Sie sich in Ihrem Konto an, um eine Frage zu diesem Tutorial zu stellen.

Jetzt kostenlos anfangen

Melden Sie sich an und erhalten Sie in den ersten 60 Tagen ein Guthaben von 200 € bei centron.

Dieses Werbeangebot gilt nur für neue Konten. Angebot ausschließlich für Gewerbetreibende.