Technische diepte-inzicht: GitLab Runners op Kubernetes, Operator-installatie, Helm-waarden, autoscaling en het FinOps-kostenmodel. Voor de korte versie, leesStop betalen voor inactieve CI.
De meeste teams betalen voor continue integratie alsof elke nacht en elk weekend nog steeds maandagochtend is. Servers staan warm. Schijfruimte blijft toegewezen. Niemand merge code — en de rekening merkt het niet op. Die zin is geen slogan; het is de standaardvorm van een vaste runner-fleet.
Dit lange artikel is het technische vervolg bij een hands-on walkthrough vanGitLab Server en GitLab Runner op Kubernetes: hoe de Kubernetes-executor elke CI-job omzet in een ephemere pod, hoe dat dynamische provision en deprijsing van capaciteit mogelijk maakt, en hoe dat ontwerpenorme kostenbesparingenmogelijk maakt door CPU, RAM en opslag terug te winnen wanneer de vraag 's nachts en in het weekend ineenstort.
Bekijk beide sessies eerst, en gebruik deze pagina daarna als geschreven architectuur en kostenmodel.
1. Runners & pipelines— autoscaling GitLab Runner-workloads met Kubernetes.
Bekijk: Complete GitLab Runners en CI/CD op Kubernetes· Eenvoudige versie:Stop betalen voor inactieve CI
2. GitLab Server op HA Kubernetes— deploy GitLab met de Operator in enkele minuten.
Bekijk: GitLab deployen in een HA Kubernetes cluster met behulp van de Operator· Docs:GitLab Operator installatie
1. Thesis
GitLab op Kubernetes + de Kubernetes executorverandert de eenheid van CI-capaciteit van "een machine die we de hele maand bezitten" naar "pods (en nodes) die we huren voor de taak". De runner manager blijft klein en altijd aan. Job-pods verschijnen voor een build en verdwijnen daarna. Met cluster autoscaling volgen werknodes dezelfde curve. Zo bescherm je de doorvoer op maandagmorgen en betaal je maandagmorgenprijzen niet voor dinsdag om 03:00 en voor rustige zaterdagen.
In één zin — dezelfde zin als de layman-gids:provisioneer voor het piek, de-provisioneer voor de dal.
2. De dure gewoonte, uitgedrukt als een architectuursmell
Traditionele CI lijkt vaak op een permanente vloot: een vaste set bouwmachines die blijven staan "net op het geval". Dat werkt wanneer het verkeer stabiel is. Het verspilt geld wanneer de vraag piekerig is.
- Dag:ontwikkelaars duwen branches, openen merge requests, voeren tests uit — de vraag piekt.
- Avonden en nachten:de activiteit daalt; machines verbranden nog steeds CPU en RAM.
- Weekenden:vaak bijna stil — maar opslagvolumes en cloudnodes kunnen nog steeds gereserveerd en gefactureerd worden.
Je betaalt niet voor "uitgevoerde builds". Je betaalt voor capaciteit die bestaat, ongeacht of iemand die gebruikt of niet. Vaste vlootten accumuleren ook plakkerige staat: "werkt op runner 3", gedriftte pakketten, caches die nooit vervallen. Elastische pods lossen discipline niet vanzelf op, maar ze maken een schone start de standaard.
3. Systeemkaart
| Layer | Rol | Typische plaatsing |
|---|---|---|
| GitLab Server | SCM, CI-coördinatie, registry, UI/API | Kubernetes via GitLab Operator / Helm chart (bijv. k3s lab) |
| Runner manager | Geregistreerde agent die op taken wacht | Helm release in een afzonderlijke namespace (bijv.gitlab-runner) |
| Taken-pods | Eigenlijke build-/test-/verpakkingsstappen | Per taak aangemaakt door de Kubernetes executor, daarna verwijderd |
| Optionele DinD-service | Docker-bouws binnen de taak | Privilegieerde service-container naast de taak |
| Cluster-/node-autoscaler | Toevoegen/verwijderen van worker-nodes bij pod-druk | Cloud ASG, Cluster Autoscaler, Karpenter of equivalent |
De analogie uit de basisgids blijft op deze laag gelden: GitLab Runner is de werker; Kubernetes is de dispatcher die werkers alleen aanroept wanneer pakketten (taken) aankomen, waarna deze weer naar huis worden gestuurd.
4. GitLab op de cluster installeren (operator-pad)
De Day 1-training pad installeert GitLab met de officiële operator, zodat de server dezelfde Kubernetes-fundatie deelt als de runners. Het bijbehorende videoGitLab in HA Kubernetes-cluster deployen met de Operatorleidt je in een paar minuten door die installatie. Voorwaarde: een cluster met ingress, Helm,kubectl, en cert-manager wanneer de chart TLS beheert.
helm repo add gitlab https://charts.gitlab.io
helm repo update
helm install gitlab-operator gitlab/gitlab-operator \
--create-namespace \
--namespace gitlab-system
kubectl -n gitlab-system get deployment gitlab-controller-manager
# Apply the GitLab custom resource (pin chart version in the manifest)
kubectl -n gitlab-system apply -f deploy_gitlab_server.yaml
Voorbeeld CR-vorm (pas domein en issuer-e-mail aan voor jouw omgeving):
apiVersion: apps.gitlab.com/v1beta1
kind: GitLab
metadata:
name: gitlab
spec:
chart:
version: "9.2.2"
values:
global:
hosts:
domain: "example.com"
ingress:
configureCertmanager: true
certmanager-issuer:
email: you@example.com
De eerste installatie duurt doorgaans ongeveer 10–15 minuten terwijl de webservice, Sidekiq, data-opslag en gerelateerde componenten zich stabiliseren. Haal het initiële root-wachtwoord op uit het cluster-secret:
kubectl get secret gitlab-gitlab-initial-root-password -n gitlab-system \
-o jsonpath='{.data.password}' | base64 -d
Referentie:GitLab Operator installatie(Helm-tabblad op die pagina). Chart-overzicht:docs.gitlab.com/charts· installatiegids:charts installatie.
5. GitLab Runner met de Kubernetes-executor
Een GitLab Runner is de applicatie die samenwerkt met GitLab CI/CD om taken uit te voeren in een pipeline. Met deKubernetes-executorcompileert de manager niet op zichzelf. Voor elke taak:
- Maakt een pod aan (plus helper-/servicecontainers zoals geconfigureerd).
- Stroomt logs terug naar GitLab.
- Verzamelt artefacten en exit-status.
- Verwijdert de pod — geeft CPU en RAM terug aan de cluster.
Die aanmaken/uitvoeren/verwijderen-loop is het eerste kostenlever. Afgewerkt werk moet geen warme machine achterlaten die de hele nacht is toegewezen.
5.1 Helm installpatroon
Trainingscripts maken een namespace aan, passen een registratietoken toe en kunnen meer dan één release installeren (bijvoorbeeld alpine-gebaseerde en ubuntu-gebaseerde runners) zodat taken verschillende omgevingen kunnen selecteren. Officiële procedure:GitLab Runner installeren met de Helm chart; waardenreferentie:De GitLab Runner Helm chartconfigureren.
helm upgrade --install --namespace gitlab-runner gitlab-runner-alpine \
-f config-runner-alpine.yaml \
--set serviceAccount.create=true \
gitlab/gitlab-runner \
--create-namespace
Tokens ophalen vanuit de GitLab-UI (instance / groep / project runners) of vanuit operator-beheerde secrets. Geef de voorkeur aan moderne runner-authenticatietokens; registratietokens worden afgevoerd richting GitLab 18.Geef live tokens nooit door— lab-scripts bevatten soms placeholders die lokaal vervangen moeten worden.
5.2 Waarden die ertoe doen voor schaal en isolatie
Uit de Workstation sjablonen (gitlab-runner-values-template.yaml/ gegenereerdconfig-runner-*.yaml):
| Instelling | Waarom het ertoe doet |
|---|---|
concurrent | Maximal aantal taken dat deze manager tegelijk draait. Verhoog voor pieken overdag (trainingsnotities noemen tientallen, bijv. 20–40, in drukke laboratoria). Zacht throttle voordat clusterlimieten worden bereikt. |
runners.privileged/ executorprivileged | Vaak vereist voor Docker-in-Docker; aanscherpen als je DinD niet nodig hebt. |
[runners.kubernetes].namespace | Waar job-pods landen — houd dit gescheiden van GitLab-systeemcomponenten. |
Standaardimage/ helper-image | Vaste tags voor reproduceerbaarheid over alpine/ubuntu-pools heen. |
[[runners.kubernetes.services]]DinD | Sidecardocker:dindvoor image-builds; configureer registry-mirrors / onveilige registries alleen indien nodig. |
RBACclusterWideAccess | Alleen als taken clusterwijde resources moeten beheren; in productie liever het principe van minst privilege. |
| host-aliases / DNS-config | Labgemak voor in-cluster GitLab- en registry-hostnamen. |
gitlabUrl: http://gitlab-webservice-default.gitlab-system.svc.cluster.local:8080/
concurrent: 2
rbac:
create: true
clusterWideAccess: true
runners:
privileged: true
config: |
[[runners]]
environment = ["GIT_SSL_NO_VERIFY=1"]
[runners.kubernetes]
namespace = "gitlab-runner"
image = "alpine/git:latest"
service_account = "gitlab-runner"
privileged = true
Concurrentie zonder CPU verlengt alleen de wachtrij. Combineerconcurrentmet echte node-capaciteit of node-autoscaling.
6. Autoscaling op twee (echt vier) niveaus
"Autoscaling GitLab Runners on Kubernetes" is niet één schakelaar. Stapel deze hendels:
- Job-pod-elasticiteit— ingebouwd in de Kubernetes executor. Geen jobs → geen job-pods. Dit alleen al elimineert de meeste per-job-afval op een gedeelde cluster.
- Runner
concurrenten meerdere runner Deployments— aparte alpine versus ubuntu (of CPU versus grotere builders) zodat gespecialiseerde capaciteit niet onbenut blijft voor het verkeerde mix. - Cluster-/node-autoscaling— pending pods voegen nodes toe; lege nodes vertrekken na de avondspits.
- Optioneel schema-gevoelig beleid— lagere gelijktijdige limieten of schaal node-pools in op een kalender voor nachten/weekenden als gordel-en-broek bovenop natuurlijke vraagkollaps.
Hyperscale is hetzelfde verhaal met scherpe amplitude: verspreid voor diepe wachtrijen, en deprovision dan agressief zodat de rustige helft van de week niet lijkt op de drukke helft op de factuur.
6.1 Een opmerking over "idle" in de GitLab Runner-sense
Sommige executors houden een klein aantal lege machines warm om de volgende job op te vangen zonder cold-start-latentie. Bij Kubernetes is cold start meestal het maken van een pod (seconden), niet het opstarten van een VM (minuten). Laat pods liever naar nul gaan en accepteer een korte planningstraging in plaats van een nachtdienst van lege nodes "netter geval" te houden. Als je toch een klein vloer wilt warmen, dimensioneer die vloer naar on-call-realistiek — niet naar de merge-storm van maandag.
6.2 Dynamische provisionering en de-provisionering end-to-end
Trace één pipeline-job:
- De ontwikkelaar duwt; GitLab creëert een job in de pending-wachtrij.
- De runner-manager claimt de job en vraagt de API om een pod.
- Als de cluster tekort schiet aan CPU/RAM, voegt de autoscaler een node toe (provisionering).
- De pod voert het script uit, uploadt artefacten en stopt.
- De pod wordt verwijderd; resources keren terug naar de pool (de-provisionering op job-niveau).
- Wanneer veel nodes leeg blijven boven de scale-down drempel — typisch na de avond en het hele weekend — vertrekken de nodes (de-provisionering op infrastructuurniveau).
Dat volledige lus is wat de video bedoelt met GitLab Runners op hyperschaal voor kostenoptimalisatie: geen enkele ingewikkelde vlag, maar job-lifecycle en cluster-elasticiteit die samenwerken.
7. Kostenmodel: waar enorme besparingen in dollars ontstaan
Wees precies. Autoscaling maakt builds niet gratis. Het voorkomt dat je piektarieven betaalt voor off-peak uren. Besparingen ontstaan door uitgaven aan te passen aan de echte vraag — de vier punten uit de eenvoudige gids, uitgebreid voor operators.
7.1 Schaal alleen op als mensen (of bots) aan het werk zijn
Wanneer een drukke ochtend tientallen pipelines oplevert, plakt Kubernetes vele job-pods parallel in tot de concurrentie- en clusterlimieten. Doorvoer verschijnt wanneer merge-druk echt is.
7.2 Schaal hard af wanneer de vraag verdwijnt
Wanneer taken afgerond zijn, verdwijnen pods. Met cluster-autoscaling (of een goed afgestelde knooppuntpool) verlaten ongebruikte cloudknooppunten de pool. Avonden en weekends — doorgaans de rustigste vensters voor productteams — zijn de eerste capaciteit die je moet stoppen met betalen.
7.3 Stop met het verspillen van CPU, RAM en opslag
| Resource | Altijd-aan runner-VM's | Kubernetes taakpods + knooppunten-autoscaling |
|---|---|---|
| CPU | Gereserveerde cores staan slap terwijl de wachtrij leeg is | Vrijgemaakt wanneer pods vertrekken; knooppunten kunnen in schaal |
| RAM | Agent-besturingssysteem + slapende uitvoerders aanwezig 24×7 | Geheugengegevens worden teruggegeven bij elke pod-verwijdering |
| Opslag | Warme schijven en afbeeldingslagen op elke VM | Tijdelijke schetsruimte standaard; gedeelde caches worden een expliciete, afgebakende keuze |
Gedurende een maand domineren rustige uren de klok. Het terugwinnen van avonden en weekends is waarbesparingen samenvoegen.
7.4 Betaal voor resultaten, niet voor meubilair
Je betaalt nog steeds voor GitLab en voor een dun bestuursvlak (runnerbeheerder + clusteressentiële componenten). Wat je stopt met betalen, is een magazijn van lege stoelen.
7.5 Gewerkte intuïtie (geen gefabriceerde benchmark)
Stel dat dagelijkse werklast duurzaam de equivalentie van 20 drukke executor-slots vereist, terwijl nachten en weekends er slechts 2 nodig hebben. Een vaste vloot die is ingeschat op 20 betaalt 20 rond de klok. Een elastische pool betaalt ~20 overdag en ~2 (plus control plane) wanneer het rustig is. Voor veel productteams zijn rustige uren een groot deel van de maand — dus het herwinnen daarvan is hoe besparingenenormworden zonder een marketingpercentage uit te vinden. Finance vermenigvuldigt lokale node-uurprijzen; de taak van architectuur is om lege uren daadwerkelijk leeg te maken in het factureringsaccount.
Enorme kostenbesparingen komen naar voren wanneer de piek van maandag de rekening van dinsdag om 3 uur niet meer bepaalt — en wanneer de stilte van zaterdag eindelijk ook rustig oogt op de factuur.
7.6 Wat je doelbewust nog steeds betaalt
- GitLab Server-componenten — maatwerk voor gebruikers en CI-coördinatie, niet voor de compile-farm.
- Runner manager Deployment(s) — klein ten opzichte van job-farms.
- Deliberate caches (dependency proxy, PVCs) — nuttig, maar van maat; caches zijn geen gratis opslag.
- Privileged DinD — handig maar zwaarder; overweeg Kaniko/BuildKit wanneer dichtheid en isolatie belangrijker zijn dan bekendheid.
8. CI/CD pipelines in practice
Met runners online,.gitlab-ci.ymldefinieert stages en jobs. GitLab plakt ze vast; de Kubernetes executor materialiseert pods. Houd pipelines eerlijk over kosten:
- Faal snel bij lint/unit voordat zware image-builds beginnen.
- Gebruik
rules/workflowzodat draft-branches geen volledige matrices uitspreiden. - Geef de voorkeur aan gedeelde caches met duidelijke keys boven onbeperkte per-VM disk-groei.
- Tag jobs naar het juiste runner-pool (alpine vs ubuntu, small vs large builders).
stages: [lint, test, build]
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
lint:
stage: lint
image: alpine:3.19
script:
- echo "cheap checks first"
test:
stage: test
tags: [kubernetes, alpine]
script:
- echo "unit tests"
build:
stage: build
tags: [kubernetes, dind]
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
- echo "heavy image build only on default branch"
Het economische idee is hetzelfde als het platform-idee: plan geen duur werk in als een goedkope check het zou hebben mislukt, en houd gespecialiseerde runners niet warm voor jobs die nooit op zaterdag arriveren.
9. Security en tenancy-notities
Ephemere pods verbeteren hygiëne (minder stickige state) maar geprivilegieerde DinD en cluster-wide RBAC kunnen de blast radius vergroten. Praktische defaults voor de meeste teams:
- Voer job-pods uit in een dedicated namespace met ResourceQuotas en LimitRanges.
- Geef niet-geprivilegieerde builds de voorkeur waar mogelijk; isoleer DinD-runners achter specifieke tags.
- Monteer geen langlevende cloud-credentials in elke job; injecteer korte-levensduur tokens per pipeline.
- Behandel runner-registratietokens als secrets — draai ze om wanneer mensen vertrekken of labs worden gedeeld.
- Als meerdere teams een cluster delen, scheid runner-managers (en optioneel node pools) zodat één lawaaierige buur de hele farm niet warm houdt — en houd het kostenverhaal per team toerekenbaar.
10. Waarnembaarheid die de besparingen bewijst
Je kunt geen nachtelijke- en weekendbesparingen claimen zonder te kijken. Controleer ten minste:
| Signaal | Wat "goed" eruit ziet |
|---|---|
| Taak-pod-aantal per uur | Pieken op werkdagwerkuren; bijna-vloerniveau 's nachts en in het weekend |
| Uitstaande pods | Pieken slechts kortstondig op piekmomenten; aanhoudend uitstaand betekent onvoldoende concurrentie/nodes |
| Node CPU / node-aantal | Volgt pod-vraag; lege nodes blijven niet urenlang staan |
| Runner manager CPU/RAM | Stabiel en klein ten opzichte van de taakboerderij |
| Cloud-factuur per uur van de week | Rustige periodes zichtbaar goedkoper na de overstap |
Als pod-aantallen 's nachts dalen maar de node-factuur niet, zijn de schaalverkleiningsinstellingen — niet GitLab — de volgende knop.
11. Vaste VM's versus Kubernetes-executors (besluitentabel)
| Vaste runner-VM's | Kubernetes-executor + autoscaling | |
|---|---|---|
| Eenheid van capaciteit | Hele machine, altijd toegewezen | Pod (en optioneel node) per taak |
| Maandag pieken | Wachten op of VM's overkopen | Concurrentie verhogen + nodes schalen |
| Avonden / weekends | Nog steeds gefactureerd als VM's blijven staan | Pods verdwenen; nodes kunnen vertrekken |
| CPU / RAM / opslag verspilling | Structureel bij inactiviteit | Standaard heringevoerd |
| Drift / "werkt op runner 3" | Vaak voorkomend | Verminderd (effemereerbaar standaard) |
| Operationele complexiteit | Lager aanvankelijk | Hoger (clusterkennis vereist) |
Kies vaste VM's alleen als je echt een vlakke 24×7-vraag hebt of beperkingen die een cluster verbieden. Iedereen anders met piekerige menselijk gedreven pipelines betaalt de meubelbelasting.
12. Wat je niet opgeeft
Autoscaling betekent niet "geen controle". Je stelt nog steeds concurrentie, toegestane afbeeldingen, DinD-rechten, netwerkbeleid en registratiebereik in. Het doel is die controles behouden terwijl ongebruikte capaciteit verdampt — dezelfde geruststelling als in het stuk in eenvoudige taal, nu afgedwongen met RBAC, namespaces en aparte runner-releases.
13. Operationele checklist
- Pin operator/chart-versies; upgrade doelbewust.
- Draai runner-tokens; schrob lab-tokens uit elk script voordat je publiceert.
- Gescheiden namespaces: GitLab-systeem versus runner-taken.
- Houdpendingpods in de gaten — stijgende pending betekent dat concurrentie of knooppuntcapaciteit op piekmoment tekort schiet.
- Houdlege knooppunt-uurin de gaten — knooppunten die overdag leeg blijven, wijzen op vertraging bij schaalverkleining of dat het poolbeleid bijgesteld moet worden.
- Beperk geverifieerde runners tot taken die ze nodig hebben.
- Maak een back-up van GitLab onafhankelijk van runner-elasticiteit.
- Beoordeel de rekening per uur van de week zodra elastische CI live is — nachten en weekends moeten duidelijk dalen.
14. Waar dit voor is
- Platform-engineers en SREs die GitLab CI implementeren op Kubernetes.
- DevOps-leiders die bestaande runner-VM's vervangen door executor-pods.
- Engineering- en financiële partners die nodig hebben dat CI zich gedraagt als een usage-based utility, niet als meubel.
15. Officiële GitLab-documentatie
Deze pagina's zijn de canonieke referenties voor de Helm-deploymenten en schaalgedrag die hierboven worden beschreven. Gebruik ze liever dan blogberichten wanneer versies veranderen.
GitLab Server op Kubernetes
- Installeer de GitLab Operator— Operator + Helm installatiepad gebruikt in de training walkthrough.
- GitLab Helm diagrammen— paraplu-diagram documentatie.
- Installeer GitLab met het Helm diagram— wanneer je GitLab via diagrammen deployt in plaats van Operator.
- gitlab-runner subdiagram (GitLab diagram)— runner ingebund naast GitLab in het hoofd-diagram (afgezet van het standalone runner-diagram).
GitLab Runner Helm diagram
- Installeer GitLab Runner met het Helm diagram—
helm repo add gitlab, installeren/upgraden, OCI diagramnotities. - Configureer de GitLab Runner Helm diagram—
concurrent, configuratiesjablonen, RBAC, caches, afbeeldingskeuzes. - gitlab-runner diagram
values.yaml— volledige standaardwaarden (inclusief optionele HPA stubs).
Kubernetes executor en autoscaling
- Kubernetes executor— job pods, helpers, services (bijv. DinD), resource requests, RBAC werkwoorden.
- Configure autoscaling (Kubernetes executor / chart)— pauzeer pods,
[runners.kubernetes.autoscaler], periodieke beleid (slaap overdag/wekelijks). - Autoscaling GitLab Runner— algemeen autoscaling model (omvat ook gedistribueerde caching).
- Plan en beheer een GitLab Runner-fleet— fleet-level schaling en operaties.
- Geavanceerde configuratie (
config.toml)— globaleconcurrenten executor secties ingebed in Helmrunners.config.
CI-taken, builds en runner-instellingen in GitLab
- Configureer runners in GitLab— registratie, tags, run-untagged, beveiligde runners.
- Gebruik Docker om images te bouwen in CI— DinD en alternatieven (relevant wanneer
privileged/ Docker service is ingeschakeld in runner-waarden).
Voor kostencontrole overdag en in het weekend, combineer: (1) Kubernetes executor job pods die naar nul gaan, (2) chartconcurrenten autoscalerbeleidmet off-peakidle_count = 0, en (3) cluster/knooppunt-autoscaling zodat lege knooppunten de pool verlaten — zoals beschreven in secties 6–7.
16. Terug naar de video en het repo
De YouTube-sessie —GitLab in ~20 minuten opzetten. Autoscaling van GitLab Runner-workloads met Kubernetes— toont GitLab op Kubernetes, runners via Helm, en het hyperscale-cost verhaal: dynamisch infrastructuur provisioneren en de-provisioneren zodat je niet betaalt voor piektarieven tijdens lege nachten en weekends. Gebruik de course-build-promptgitlab-runners-k3s-hyperscale-course.prompt.mdin dit repo, met de officiële documentatie hierboven als de versieerde bron van waarheid. Voor de niet-technische formulering van dezelfde ideeën, zieStop betalen voor idle CI.
Afsluiting
Kubernetes is niet alleen een host voor GitLab Runners. Bij correct gebruik verandert het de economie van CI:provisioneren op aanvraag, de-provisioneren bij inactiviteit, CPU/RAM/opslag herwinnen wanneer mensen naar huis gaan. Dat is het hyperscale-patroon — beschikbaar voor elk team dat bereid is een vaste vloot in te ruilen voor een wachtrij van pods.
Begin met de video, zet operator + runner Helm op in een lab, schakel node-autoscaling in, en controleer of zaterdag eindelijk rustig is op de factuur.
Gepubliceerd doorWorkstation.