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.
Inhaltsverzeichnis
- 1. Warum statische Runner-Kapazitaet fast immer die falsche Groesse hat
- 2. Das Docker-Machine-Modell: Wie es historisch funktionierte
- 3. Warum Docker Machine nicht mehr die Zukunft ist
- 4. Fleeting: Das neue Plugin-basierte Autoscaling-Modell
- 5. Von Docker Machine zu Fleeting: Was sich konkret aendert
- 6. Kostenkontrolle ueber die richtigen Autoscaling-Parameter
- 7. Spot-Instances und weitere Kostenoptimierungen
- 8. Monitoring: Autoscaling-Verhalten sichtbar machen
- 9. Docker Machine oder Fleeting: Die Entscheidung im Ueberblick
- 10. Zusammenfassung
- 11. FAQ
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.