GitLab Runner Autoscaling mit Docker Machine und Fleeting
AI generated
CI/CD
.yml
GitLab · CI/CD · Infrastruktur
Runner-Autoscaling mit
Docker Machine und Fleeting

Schwankende Build-Last ist der Normalfall: nachts kaum Pipelines, am Nachmittag ein Ansturm von Merge-Request-Pipelines. Statischtes Runner-Provisioning verschwendet entweder Geld oder produziert Wartezeiten, Autoscaling loest beides.

18 Min. Lesezeit Docker Machine Fleeting Autoscaling Kostenkontrolle

1. Warum statische Runner-Kapazitaet fast immer die falsche Groesse hat

Ein fest dimensionierter Pool von Runner-Maschinen muss zwangslaeufig fuer die Spitzenlast ausgelegt sein, sonst warten Entwickler in stark frequentierten Stunden lange in der Job-Queue. Genau diese Spitzenlast tritt aber typischerweise nur wenige Stunden am Tag auf, etwa wenn viele Teams gleichzeitig Merge-Request-Pipelines ausloesen. Ausserhalb dieser Fenster, nachts oder am Wochenende, laufen dieselben Maschinen weitgehend im Leerlauf und verursachen trotzdem die vollen Infrastrukturkosten.

Autoscaling durchbricht dieses Dilemma, indem Runner-Maschinen erst bei tatsaechlichem Bedarf hochgefahren und nach einer Leerlaufzeit automatisch wieder abgebaut werden. Statt eine feste Anzahl Maschinen dauerhaft vorzuhalten, existiert nur eine kleine Basiskapazitaet permanent, waehrend zusaetzliche Kapazitaet elastisch je nach Pipeline-Aufkommen dazugeschaltet wird. Fuer Cloud-basierte Runner uebersetzt sich das direkt in Kosteneinsparungen, da nur tatsaechlich genutzte Rechenzeit bezahlt wird.

2. Das Docker-Machine-Modell: Wie es historisch funktionierte

Der Docker-Machine-Executor war ueber viele Jahre der Standardweg fuer GitLab-Runner-Autoscaling. Er nutzte das mittlerweile von Docker selbst eingestellte Docker-Machine-Tool, um bei Bedarf neue virtuelle Maschinen bei einem Cloud-Provider wie AWS, GCP oder Azure zu provisionieren, auf denen anschliessend Docker installiert und ein Job-Container gestartet wurde. Der Runner selbst lief dabei als eine Art Manager-Prozess, der basierend auf der Job-Queue entschied, wann neue Maschinen erzeugt und wann bestehende, nicht mehr benoetigte Maschinen wieder abgebaut werden sollten.

Die Konfiguration erfolgte ueber den Abschnitt runners.machine in der config.toml, in dem unter anderem IdleCount die Zahl der permanent vorgehaltenen Leerlauf-Maschinen festlegte und IdleTime bestimmte, wie lange eine ungenutzte Maschine vor dem Abbau noch bereitstehen sollte. MaxBuilds begrenzte zusaetzlich, wie viele Jobs eine einzelne Maschine ausfuehren durfte, bevor sie aus Sicherheits- und Sauberkeitsgruenden durch eine frische Instanz ersetzt wurde.


# Auszug aus /etc/gitlab-runner/config.toml (Docker Machine, historisch)
[[runners]]
  name = "autoscale-runner"
  executor = "docker+machine"
  [runners.machine]
    IdleCount = 2
    IdleTime = 600
    MaxBuilds = 20
    MachineDriver = "amazonec2"
    MachineName = "gitlab-runner-%s"
    MachineOptions = [
      "amazonec2-instance-type=t3.medium",
      "amazonec2-region=eu-central-1"
    ]

3. Warum Docker Machine nicht mehr die Zukunft ist

Docker selbst hat die Weiterentwicklung von Docker Machine schon vor Jahren eingestellt, das Tool erhaelt seitdem keine neuen Cloud-Provider-Treiber und keine sicherheitsrelevanten Updates mehr. GitLab hat lange trotzdem daran festgehalten, weil kein direkter Ersatz existierte, doch das Fehlen aktiver Wartung wurde mit der Zeit zu einem echten Betriebsrisiko, insbesondere bei aelteren, nicht mehr gepflegten Cloud-API-Versionen, gegen die die vorhandenen Treiber noch programmiert waren.

Als Reaktion darauf hat GitLab mit Fleeting ein eigenes, aktiv gepflegtes Plugin-System entwickelt, das Docker Machine als empfohlenen Autoscaling-Mechanismus ablösen soll. Fuer bestehende Setups bedeutet das nicht, dass Docker Machine von einem Tag auf den anderen aufhoert zu funktionieren, wohl aber, dass neue Projekte und Migrationen auf Fleeting statt auf den absehbar auslaufenden Docker-Machine-Weg ausgelegt werden sollten.

4. Fleeting: Das neue Plugin-basierte Autoscaling-Modell

Fleeting abstrahiert das Provisionieren und Abbauen von Maschinen ueber eine klar definierte Plugin-Schnittstelle, fuer die es separate Plugins je Cloud-Provider gibt, etwa fleeting-plugin-aws fuer AWS Auto Scaling Groups oder fleeting-plugin-googlecompute fuer Google Cloud. Statt wie Docker Machine eine monolithische Abstraktion ueber viele Provider hinweg zu versuchen, delegiert Fleeting die eigentliche Provider-Kommunikation an dedizierte, unabhaengig gepflegte Plugins, die sich naeher an den nativen Autoscaling-Mechanismen des jeweiligen Cloud-Anbieters orientieren.

Konkret nutzt der AWS-Fleeting-Plugin beispielsweise eine echte AWS Auto Scaling Group als Backend, statt wie Docker Machine jede Instanz einzeln per API-Aufruf zu erzeugen. Das bedeutet, dass viele bewaehrte Cloud-native Mechanismen wie Spot-Instance-Unterstuetzung, Lifecycle-Hooks und Health-Checks direkt vom Cloud-Provider selbst kommen, statt vom Runner nachgebildet werden zu muessen, was die Zuverlaessigkeit gegenueber dem aelteren Modell deutlich erhoeht.


# Auszug aus /etc/gitlab-runner/config.toml (Fleeting, aktuell)
[[runners]]
  name = "fleeting-runner"
  executor = "docker-autoscaler"
  [runners.autoscaler]
    plugin = "fleeting-plugin-aws"
    capacity_per_instance = 1
    max_use_count = 20
    max_instances = 10
    [runners.autoscaler.plugin_config]
      name = "gitlab-runner-asg"
      profile = "default"
    [runners.autoscaler.connector_config]
      username = "ec2-user"
      use_external_addr = true
    [[runners.autoscaler.policy]]
      idle_count = 2
      idle_time = "10m"

5. Von Docker Machine zu Fleeting: Was sich konkret aendert

Der Executor-Name wechselt von docker+machine zu docker-autoscaler, und die frueher zentrale Konfiguration im runners.machine-Block wandert in einen neuen runners.autoscaler-Block mit Plugin-spezifischen Unterabschnitten. Wer bereits eine funktionierende Docker-Machine-Konfiguration betreibt, kann nicht einfach die alten Werte eins zu eins uebertragen, da Fleeting-Plugins teils andere Konzepte verwenden, etwa Auto Scaling Groups statt individueller Instanzerzeugung, was auch eine Anpassung der zugrundeliegenden Cloud-Infrastruktur noetig macht.

In der Praxis empfiehlt sich eine schrittweise Migration: Ein neuer Fleeting-basierter Runner wird parallel zum bestehenden Docker-Machine-Runner aufgesetzt und zunaechst nur fuer einen Teil der Projekte oder ueber Tags gezielt angesteuert. Nach einer Beobachtungsphase, in der sich Zuverlaessigkeit und Kostenverhalten mit dem neuen Modell bestaetigen, kann der alte Docker-Machine-Runner schrittweise abgebaut werden, ohne dass eine harte Umschaltung an einem einzigen Tag noetig ist.

6. Kostenkontrolle ueber die richtigen Autoscaling-Parameter

Die wichtigsten Stellschrauben fuer Kosten sind idle_count, idle_time und max_instances. Ein zu hoher idle_count haelt dauerhaft mehr Maschinen bereit als noetig und produziert damit unnoetige Grundkosten, waehrend ein zu niedriger Wert dazu fuehrt, dass fast jeder Job eine frische Maschine hochfahren muss, was durch die Boot-Zeit der Instanz spuerbare Verzoegerung in jede Pipeline einbringt. Der richtige Wert haengt stark vom typischen Pipeline-Muster ab und sollte anhand echter Nutzungsdaten austariert werden, nicht nach Bauchgefuehl.

max_instances begrenzt die absolute Obergrenze der gleichzeitig laufenden Maschinen und ist die wichtigste Absicherung gegen Kostenexplosionen, etwa wenn durch einen fehlerhaften Trigger ploetzlich hunderte Pipelines gleichzeitig ausgeloest werden. Ohne diese Obergrenze wuerde ein Autoscaler theoretisch versuchen, fuer jeden wartenden Job eine neue Maschine zu erzeugen, was bei Cloud-Anbietern mit nutzungsbasierter Abrechnung schnell zu einer unangenehmen Ueberraschung auf der naechsten Rechnung fuehren kann.


# Kostenbewusste Autoscaling-Policy in config.toml
[runners.autoscaler]
  max_instances = 15
  max_use_count = 30
  [[runners.autoscaler.policy]]
    idle_count = 1
    idle_time = "5m"
    scale_factor = 0.0
    scale_factor_limit = 5

7. Spot-Instances und weitere Kostenoptimierungen

Fuer nicht zeitkritische Jobs wie Lint-Checks oder nicht-produktive Test-Suites lohnt sich der Einsatz von Spot-Instances, die Cloud-Anbieter zu deutlich reduzierten Preisen anbieten, im Gegenzug aber jederzeit mit kurzer Vorwarnzeit zurueckfordern koennen. Fleeting-Plugins wie fleeting-plugin-aws unterstuetzen Spot-Instances nativ ueber die zugrundeliegende Auto Scaling Group, was die Integration deutlich einfacher macht als eine manuelle Spot-Instance-Verwaltung auf Docker-Machine-Basis.

Ergaenzend lohnt sich eine bewusste Trennung nach Job-Kritikalitaet: Produktions-Deploy-Jobs laufen auf regulaeren, garantiert verfuegbaren On-Demand-Instanzen ueber einen eigenen Runner mit entsprechenden Tags, waehrend die Masse an Build- und Test-Jobs ueber einen separaten, spot-basierten Runner abgewickelt wird. Faellt dabei eine Spot-Instance mitten in einem Job weg, wiederholt GitLab den Job in der Regel automatisch auf einer neuen Maschine, was fuer nicht-kritische Jobs ein akzeptabler Kompromiss zwischen Kosten und Zuverlaessigkeit ist.

8. Monitoring: Autoscaling-Verhalten sichtbar machen

Ohne Monitoring bleibt Autoscaling ein Blackbox-Mechanismus, bei dem weder klar ist, ob die gewaehlten idle_count- und idle_time-Werte tatsaechlich passen, noch ob unerwartete Kostenspitzen entstehen. GitLab Runner exponiert Prometheus-Metriken, unter anderem zur Zahl aktiver, im Aufbau befindlicher und im Abbau befindlicher Maschinen, die sich in einem Grafana-Dashboard zusammen mit den Cloud-Provider-eigenen Kostenmetriken visualisieren lassen.

Ein sinnvolles Alerting reagiert auf zwei Extremsituationen: eine dauerhaft hohe Job-Queue-Laenge, die auf zu restriktive max_instances-Werte hindeutet, und eine unerwartet hohe Zahl gleichzeitig laufender Instanzen, die auf einen moeglichen Trigger-Fehler oder Missbrauch hindeuten koennte. Beide Signale zusammen erlauben es, die Autoscaling-Parameter iterativ nachzuschaerfen, statt sie einmal zu setzen und nie wieder anzufassen.

9. Docker Machine oder Fleeting: Die Entscheidung im Ueberblick

Fuer neue Runner-Setups gibt es kaum noch einen guten Grund, mit Docker Machine zu starten, da das Tool nicht mehr aktiv weiterentwickelt wird und Fleeting inzwischen fuer die gaengigen Cloud-Provider ausgereifte Plugins bereitstellt. Bestehende Docker-Machine-Runner muessen nicht zwingend sofort abgeloest werden, sollten aber mittelfristig auf eine Migration vorbereitet werden, bevor Kompatibilitaetsprobleme mit neueren Cloud-APIs oder GitLab-Runner-Versionen auftreten.

Die folgende Tabelle fasst die wichtigsten Unterschiede zwischen beiden Modellen zusammen und zeigt, worauf bei der Migrationsplanung besonders zu achten ist.

Kriterium Docker Machine Fleeting Konsequenz
Wartungsstatus Eingestellt seit Jahren Aktiv von GitLab gepflegt Fleeting fuer neue Setups bevorzugen
Provider-Anbindung Generische API-Aufrufe Native Mechanismen (z.B. ASG) Bessere Zuverlaessigkeit bei Fleeting
Spot-Instance-Support Manuell nachgeruestet Nativ ueber Cloud-Backend Einfachere Kostenoptimierung
Executor-Name docker+machine docker-autoscaler Migration erfordert Config-Umbau

Mironsoft

CI/CD-Pipelines, Zero-Downtime-Deployments und Release-Automatisierung

Deployments, die ohne Ausfallzeit und ohne Nervenkitzel laufen?

Wir prüfen bestehende GitLab-Pipelines auf fragile Deployment-Schritte und fehlende Absicherung und bauen daraus einen Release-Prozess mit Zero-Downtime-Deployments, automatisierten Checks und einem Rollback, dem ihr im Ernstfall vertrauen könnt.

Pipeline-Review

Bestehende .gitlab-ci.yml auf Fragilität, fehlende Stages und Sicherheitslücken prüfen.

Zero-Downtime-Deployment

Symlink-Releases, Health-Checks und Rollback-Strategien für Magento-Shops aufbauen.

CI/CD-Automatisierung

Tests, Security-Scans und Deployments zu einer zuverlässigen Pipeline verbinden.

10. Zusammenfassung

Runner-Autoscaling: Das Wichtigste auf einen Blick

Autoscaling-Ziel

Nur bei tatsaechlichem Bedarf Maschinen erzeugen statt dauerhaft ueberdimensioniert vorzuhalten.

Docker Machine

Aeltere, nicht mehr aktiv gepflegte Basis fuer Autoscaling, weiterhin lauffaehig.

Fleeting

Neues, plugin-basiertes Modell mit nativen Cloud-Mechanismen wie Auto Scaling Groups.

Kostenkontrolle

idle_count, idle_time, max_instances und Spot-Instances gezielt kombinieren.

11. FAQ: Runner-Autoscaling: Das Wichtigste auf einen Blick

1Funktioniert Docker Machine als GitLab-Runner-Executor noch?
Technisch ja, bestehende Konfigurationen laufen weiter, aber das zugrundeliegende Docker-Machine-Tool erhaelt keine aktive Weiterentwicklung mehr, weshalb GitLab fuer neue Setups Fleeting empfiehlt.
2Muss ich sofort auf Fleeting migrieren?
Nicht zwingend sofort, aber eine mittelfristige Migrationsplanung ist sinnvoll, da Docker Machine keine neuen Cloud-API-Versionen oder Sicherheitsupdates mehr erhaelt.
3Was ist der grundlegende Unterschied zwischen beiden Modellen?
Docker Machine provisioniert Instanzen einzeln ueber generische API-Aufrufe, Fleeting delegiert das Provisionieren an providerspezifische Plugins, die native Cloud-Mechanismen wie Auto Scaling Groups nutzen.
4Unterstuetzt Fleeting alle Cloud-Provider, die Docker Machine unterstuetzt hat?
Nein, aktuell existieren offizielle Plugins fuer die grossen Cloud-Provider wie AWS und Google Cloud, fuer weniger verbreitete Provider kann die Plugin-Verfuegbarkeit eingeschraenkt sein.
5Wie verhindere ich, dass Autoscaling die Cloud-Rechnung explodieren laesst?
Der wichtigste Schutzmechanismus ist max_instances als harte Obergrenze, kombiniert mit Monitoring der tatsaechlich laufenden Instanzen und Alerting bei ungewoehnlichen Spitzen.
6Was passiert, wenn eine Spot-Instance mitten in einem Job zurueckgefordert wird?
GitLab erkennt den Abbruch und wiederholt den Job in der Regel automatisch auf einer neuen Maschine, was fuer nicht-kritische Jobs wie Tests akzeptabel ist, fuer Produktions-Deploys aber vermieden werden sollte.
7Was bewirkt idle_time konkret?
idle_time bestimmt, wie lange eine ungenutzte Maschine nach ihrem letzten Job noch bereitgehalten wird, bevor sie automatisch abgebaut wird. Ein hoeherer Wert reduziert Wartezeit fuer den naechsten Job, erhoeht aber die Kosten.
8Kann ich Docker Machine und Fleeting parallel betreiben?
Ja, das ist sogar der empfohlene Weg fuer eine schrittweise Migration: Ein neuer Fleeting-Runner laeuft parallel zum bestehenden Docker-Machine-Runner, bis er sich bewaehrt hat.
9Braucht Fleeting eine andere Cloud-Infrastruktur als Docker Machine?
Teilweise ja, da manche Fleeting-Plugins auf Cloud-native Konzepte wie Auto Scaling Groups aufsetzen, die separat in der Cloud-Umgebung eingerichtet werden muessen, waehrend Docker Machine Instanzen direkt einzeln erzeugte.
10Lohnt sich Autoscaling ueberhaupt fuer kleine Teams mit wenigen Pipelines?
Bei sehr geringem und konstantem Pipeline-Aufkommen ist der Nutzen begrenzt, sobald aber deutliche Lastspitzen zu bestimmten Tageszeiten auftreten, ueberwiegt der Kostenvorteil meist schon bei mittelgrossen Teams.