CI/CD-Optimierung beginnt mit Transparenz. Eine erfolgreiche DevOps-Plattform im Unternehmensmaßstab umfasst das Verständnis von Pipeline-Performance, Job-Ausführungsmustern und quantifizierbaren operationalen Insights – insbesondere für Unternehmen, die GitLab Self-Managed betreiben.
Um GitLab-Kund(inn)en dabei zu helfen, den vollen Nutzen ihrer Plattform auszuschöpfen, haben wir die GitLab CI/CD Observability-Lösung als Teil unseres Platform Excellence-Programms entwickelt. Sie verwandelt rohe Pipeline-Metriken in handlungsrelevante operationale Erkenntnisse.
Ein führendes Finanzdienstleistungsunternehmen hat gemeinsam mit GitLabs Customer Success Architect Transparenz über seine GitLab Self-Managed-Deployments gewonnen. Gemeinsam haben wir eine containerisierte Observability-Lösung implementiert, die den Open-Source-gitlab-ci-pipelines-exporter mit unternehmensgerechter Prometheus- und Grafana-Infrastruktur kombiniert.
In diesem Artikel werden die Herausforderungen beim Pipeline-Management im Unternehmensmaßstab erläutert – und wie GitLab CI/CD Observability diese mit einer praxisnahen End-to-End-Implementierung adressiert.
Die Herausforderung: CI/CD-Performance messen
Vor der Implementierung einer Observability-Lösung sollte die Messdimension klar definiert sein:
- Welche Metriken sind relevant? Pipeline-Dauer, Job-Erfolgsraten, Queue-Zeiten, Runner-Auslastung
- Wer braucht Transparenz? Entwickler(innen), DevOps-Engineers, Plattformteams, Führungsebene
- Welche Entscheidungen werden damit getroffen? Infrastrukturinvestitionen, Engpass-Behebung, Kapazitätsplanung
Lösungsarchitektur: Ein vollständiges Dashboard-Set für Observability
Nach dem Deployment stellt der Observability-Stack ein Set von Grafana-Dashboards bereit, das Echtzeit- und historische Transparenz über die CI/CD-Plattform bietet. Ein typisches Deployment umfasst:
- Pipeline Overview Dashboard: Eine übergeordnete Ansicht mit Gesamtzahl der Pipeline-Läufe, Erfolgs-/Fehlerquoten über die Zeit (als gestapelte Balken- oder Zeitreihencharts) und Trends bei der durchschnittlichen Pipeline-Dauer. Panels verwenden farbcodierte Statusindikatoren (Grün für Erfolg, Rot für Fehler, Gelb für Abbruch), damit Plattformteams Verschlechterungen auf einen Blick erkennen.
- Job Performance Dashboard: Drill-down-Panels mit Verteilungen der einzelnen Job-Dauern (Histogramm), den 10 langsamsten Jobs nach Durchschnittsdauer und Job-Fehler-Heatmaps nach Projekt und Stage. Hier identifizieren Teams konkrete Engpass-Jobs, die sich zu optimieren lohnen.
- Runner & Infrastructure Dashboard: Kombiniert Node-Exporter-Host-Metriken (CPU, Arbeitsspeicher, Disk) mit Pipeline-Queue-Zeit-Daten, um Infrastruktur-Sättigung mit Pipeline-Wartezeiten zu korrelieren. Nützlich für Kapazitätsplanungsentscheidungen wie die Skalierung von Runner-Pools oder das Upgrade von Instanzgrößen.
- Deployment Frequency Dashboard: Verfolgt Deployment-Anzahl und -Dauer über die Zeit pro Umgebung, abgestimmt auf DORA-Metriken. Hilft der Engineering-Führungsebene, Lieferdurchsatz und Environment-Drift (Commits hinter main) zu bewerten.
Jedes Dashboard wird automatisch über Grafanas dateibasiertes Provisioning bereitgestellt, sodass es konsistent über alle Umgebungen hinweg deployed wird. Die Dashboards lassen sich über Grafana-Variablen weiter anpassen, um nach Projekt, Ref/Branch oder Zeitraum zu filtern.

Die Lösung benötigt zwei Exporter:
- Pipeline Exporter: Erfasst CI/CD-Metriken über die GitLab API (Pipeline-Dauer, Job-Status, Deployments)
- Node Exporter: Erfasst Host-Metriken (CPU, Arbeitsspeicher, Disk) für die Infrastruktur-Korrelation
Voraussetzungen:
- GitLab Self-Managed Version 18.1+
- Container-Orchestrierungsplattform: Ein Kubernetes-Cluster (empfohlen für Unternehmens-Deployments) oder eine Container-Runtime wie Docker/Podman für kleinere Umgebungen oder Proof-of-Concept-Deployments. Die primäre Deployment-Anleitung unten zielt auf Kubernetes; eine Docker-Compose-Alternative ist im Anhang für lokales Testen und Evaluation verfügbar
- GitLab Personal Access Token (Scope read_api)
Die vollständige Implementierungsanleitung mit allen Kubernetes-Manifesten folgt direkt im Anschluss.
Kubernetes-Deployment (empfohlen)
Für Unternehmensumgebungen wird jede Komponente als separates Deployment in einem dedizierten Namespace deployed. Dieser Ansatz integriert sich in bestehende Cluster-Infrastruktur, Secrets-Management und Network-Policies.
1. Namespace und Secret erstellen
kubectl create namespace gitlab-observability
# GitLab-Token-Secret erstellen (siehe Abschnitt Secrets-Management
# für unternehmensgerechte Ansätze mit externen Secret-Operatoren)
kubectl create secret generic gitlab-token \
--from-literal=token=glpat-xxxxxxxxxxxx \
-n gitlab-observability
2. Pipeline Exporter deployen
# exporter-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitlab-ci-pipelines-exporter
namespace: gitlab-observability
spec:
replicas: 1
selector:
matchLabels:
app: gitlab-ci-pipelines-exporter
template:
metadata:
labels:
app: gitlab-ci-pipelines-exporter
spec:
containers:
- name: exporter
image: mvisonneau/gitlab-ci-pipelines-exporter:latest
ports:
- containerPort: 8080
env:
- name: GCPE_GITLAB_TOKEN
valueFrom:
secretKeyRef:
name: gitlab-token
key: token
- name: GCPE_CONFIG
value: /etc/gcpe/config.yml
volumeMounts:
- name: config
mountPath: /etc/gcpe
volumes:
- name: config
configMap:
name: gcpe-config
---
apiVersion: v1
kind: Service
metadata:
name: gitlab-ci-pipelines-exporter
namespace: gitlab-observability
spec:
selector:
app: gitlab-ci-pipelines-exporter
ports:
- port: 8080
targetPort: 8080
3. Node Exporter deployen (DaemonSet)
# node-exporter-daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: gitlab-observability
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
containers:
- name: node-exporter
image: prom/node-exporter:latest
ports:
- containerPort: 9100
---
apiVersion: v1
kind: Service
metadata:
name: node-exporter
namespace: gitlab-observability
spec:
selector:
app: node-exporter
ports:
- port: 9100
targetPort: 9100
4. Prometheus deployen
# prometheus-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
namespace: gitlab-observability
spec:
replicas: 1
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
containers:
- name: prometheus
image: prom/prometheus:latest
ports:
- containerPort: 9090
volumeMounts:
- name: config
mountPath: /etc/prometheus
volumes:
- name: config
configMap:
name: prometheus-config
---
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: gitlab-observability
spec:
selector:
app: prometheus
ports:
- port: 9090
targetPort: 9090
5. Grafana deployen
Das folgende Grafana-Deployment startet mit deaktivierter Authentifizierung
(GF_AUTH_ANONYMOUS_ENABLED: true) für den einfachen Einstieg.
Diese Einstellung erlaubt jedem mit Netzwerkzugang, alle Dashboards ohne Anmeldung einzusehen. Für Produktions-Deployments diese Variable entfernen oder auf false setzen und einen geeigneten Authentifizierungs-Provider (LDAP, SAML/SSO oder OAuth) konfigurieren, um den Zugriff auf autorisierte Nutzende zu beschränken.
# grafana-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana
namespace: gitlab-observability
spec:
replicas: 1
selector:
matchLabels:
app: grafana
template:
metadata:
labels:
app: grafana
spec:
containers:
- name: grafana
image: grafana/grafana:10.0.0
ports:
- containerPort: 3000
env:
# Für Produktion ENTFERNEN oder auf 'false' setzen.
# Bei 'true' können alle Nutzenden mit Netzwerkzugang
# Dashboards ohne Authentifizierung einsehen.
- name: GF_AUTH_ANONYMOUS_ENABLED
value: 'true'
volumeMounts:
- name: dashboards-provider
mountPath: /etc/grafana/provisioning/dashboards
- name: datasources
mountPath: /etc/grafana/provisioning/datasources
- name: dashboards
mountPath: /var/lib/grafana/dashboards
volumes:
- name: dashboards-provider
configMap:
name: grafana-dashboards-provider
- name: datasources
configMap:
name: grafana-datasources
- name: dashboards
configMap:
name: grafana-dashboards
---
apiVersion: v1
kind: Service
metadata:
name: grafana
namespace: gitlab-observability
spec:
selector:
app: grafana
ports:
- port: 3000
targetPort: 3000
6. Network Policy setzen
Den Inter-Pod-Traffic auf die erforderlichen Kommunikationspfade beschränken:
# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: observability-policy
namespace: gitlab-observability
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
# Prometheus scrapt Exporter und Node-Exporter
- from:
- podSelector:
matchLabels:
app: prometheus
ports:
- port: 8080
- port: 9100
# Grafana fragt Prometheus ab
- from:
- podSelector:
matchLabels:
app: grafana
ports:
- port: 9090
7. Validieren
kubectl get pods -n gitlab-observability
kubectl port-forward svc/grafana 3000:3000 -n gitlab-observability
curl http://localhost:3000/api/health
Konfigurationsreferenz
Exporter-Konfiguration
# gitlab-ci-pipelines-exporter.yml (ConfigMap: gcpe-config)
log:
level: info
gitlab:
url: https://gitlab.your-domain.com
maximum_requests_per_second: 10
project_defaults:
pull:
pipeline:
jobs:
enabled: true
wildcards:
- owner:
name: your-group-name
kind: group
archived: false
Prometheus-Konfiguration
# prometheus.yml (ConfigMap: prometheus-config)
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'gitlab-ci-pipelines-exporter'
static_configs:
- targets: ['gitlab-ci-pipelines-exporter:8080']
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
Grafana-Datenquellen
# datasources.yml (ConfigMap: grafana-datasources)
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
# dashboards.yml (ConfigMap: grafana-dashboards-provider)
apiVersion: 1
providers:
- name: 'default'
folder: 'GitLab CI/CD'
type: file
options:
path: /var/lib/grafana/dashboards
Wichtige Metriken
Pipeline-Exporter-Metriken
| Metrik | Beschreibung |
|---|---|
gitlab_ci_pipeline_duration_seconds | Pipeline-Ausführungszeit |
gitlab_ci_pipeline_status | Pipeline-Erfolg/-Fehler nach Projekt |
gitlab_ci_pipeline_job_duration_seconds | Einzelne Job-Ausführungszeit |
gitlab_ci_pipeline_job_status | Job-Erfolgs-/-Fehlerstatus |
gitlab_ci_pipeline_job_artifact_size_bytes | Artifact-Speicherverbrauch |
gitlab_ci_pipeline_coverage | Code-Coverage-Prozentsatz |
gitlab_ci_environment_deployment_count | Deployment-Häufigkeit |
gitlab_ci_environment_deployment_duration_seconds | Deployment-Ausführungszeit |
gitlab_ci_environment_behind_commits_count | Environment-Drift gegenüber main |
Node-Exporter-Metriken
| Metrik | Beschreibung |
|---|---|
node_cpu_seconds_total | CPU-Auslastung |
node_memory_MemAvailable_bytes | Verfügbarer Arbeitsspeicher |
node_filesystem_avail_bytes | Verfügbarer Festplattenspeicher |
node_load1 | 1-Minuten-Lastdurchschnitt |
Fehlerbehebung
Grafana-Plugin-Installation in Air-gapped-Umgebungen
Für Offline-Umgebungen Plugins manuell installieren. Beispiel für Kubernetes:
# Plugin-ZIP in den Grafana-Pod kopieren
kubectl cp grafana-polystat-panel-2.1.16.zip \
gitlab-observability/grafana-<pod-id>:/tmp/
# Plugin entpacken
kubectl exec -it -n gitlab-observability deploy/grafana -- \
sh -c "unzip /tmp/grafana-polystat-panel-2.1.16.zip -d /var/lib/grafana/plugins/"
# Grafana-Pod neu starten
kubectl rollout restart deployment/grafana -n gitlab-observability
# Installation prüfen
kubectl exec -it -n gitlab-observability deploy/grafana -- \
ls -al /var/lib/grafana/plugins/
Unternehmensaspekte
Für regulierte Branchen gilt:
- Token-Sicherheit: GitLab Personal Access Tokens in einem dedizierten Secrets-Manager speichern, nicht hartcodiert in ConfigMaps. Token-Rotation durchsetzen und den Scope auf read_api beschränken.
- Netzwerksegmentierung: Hinter einem Reverse Proxy mit TLS-Terminierung deployen. In Kubernetes einen Ingress-Controller mit automatisierter Zertifikatsbereitstellung verwenden.
- Authentifizierung: Grafana mit dem Identity Provider der Organisation konfigurieren (SAML, LDAP oder OAuth/OIDC), um rollenbasierte Zugriffskontrolle auf Dashboards durchzusetzen.
Warum GitLab?
GitLabs API-First-Design ermöglicht individuelle Observability-Lösungen, die native Funktionen wie Value Stream Analytics und DORA-Metriken ergänzen. Die offene Architektur erlaubt es Unternehmen, bewährte Open-Source-Werkzeuge – wie den gitlab-ci-pipelines-exporter – direkt in bestehende Unternehmensinfrastruktur zu integrieren, ohne etablierte Workflows zu unterbrechen.
Mit wachsender Observability-Reife bieten GitLabs eingebaute Observability-Funktionen einen natürlichen nächsten Schritt – tiefere, integrierte Transparenz ohne zusätzliche Werkzeuge. Mehr zu den nativen Plattformfunktionen unter GitLab Observability.




