GitLab ist mehr als ein Git-Repository-Host – es ist eine vollständige DevOps-Plattform. Während Git selbst ein verteiltes Versionskontrollsystem ist, das lokal und auf jedem Server läuft, ist GitLab eine zentralisierte Plattform, die Git mit CI/CD, Security-Scanning, Package-Management, Monitoring und vielem mehr kombiniert.
Dieses Kapitel erklärt die technische Architektur von GitLab: Welche Komponenten existieren, wie sie zusammenspielen, und warum diese Architektur für skalierbare DevOps-Prozesse entscheidend ist. Das Verständnis der Architektur ist fundamental, um GitLab CI/CD effektiv zu nutzen, Performance-Probleme zu diagnostizieren, und Deployments zu planen.
Git ist ein Command-Line-Tool und eine
Bibliothek. Es läuft lokal, speichert Daten in
.git/, und kommuniziert mit Remote-Repositories über HTTP
oder SSH. Git kennt keine Weboberflächen, keine Pipelines, keine
Issue-Tracker.
GitLab transformiert Git in eine Multi-Komponenten-Plattform: - Web-Interface: Statt Command-Line eine grafische Oberfläche - API: Programmatischer Zugriff auf alle Features - CI/CD: Automatisierte Pipelines für Build, Test, Deploy - Runner: Verteilte Ausführungs-Agents - Datenbanken: PostgreSQL für persistente Daten, Redis für Caching - Spezialisierte Services: Gitaly für Git-Operations, Sidekiq für Background-Jobs
Diese Komponenten bilden ein verteiltes System, das horizontal skalieren kann – von Single-Server-Installationen für kleine Teams bis zu Multi-Node-Clustern für Enterprises mit tausenden Nutzern.
GitLab existiert in drei Varianten, die dieselbe Architektur nutzen:
Die von GitLab gehostete Cloud-Variante. Nutzer registrieren sich, erstellen Projekte, nutzen shared oder private Runners. GitLab managed die gesamte Infrastruktur.
Vorteile: Kein Maintenance, sofort nutzbar, integriert mit GitLab-Ökosystem. Nachteile: Daten bei Drittanbieter, eingeschränkte Kontrolle über Runner-Umgebungen.
GitLab auf eigenen Servern oder in eigener Cloud installiert. Volle Kontrolle über Infrastruktur, Daten, Konfiguration.
Installation-Optionen: - Omnibus Package: All-in-One-Package (empfohlen, einfach) - Docker: Container-basierte Deployment - Kubernetes (Helm Charts): Cloud-native, hochskalierbar - Source Installation: Manuelle Installation (komplex, für spezielle Anforderungen)
Vorteile: Volle Datenkontrolle, unbegrenzte Runner, custom Configuration. Nachteile: Maintenance-Aufwand, eigene Infrastruktur nötig.
GitLab-managed, aber in isolierter Infrastruktur (eigene Cloud, Datacenter). Kombination aus SaaS-Convenience und On-Premise-Kontrolle.
Im Folgenden fokussieren wir auf die generelle Architektur, die allen Modi zugrunde liegt.
Sprache: Ruby on Rails Webserver: Puma (Multi-Threaded Ruby Server)
Die Rails-Application ist das Herz von GitLab. Sie implementiert: - Weboberfläche: HTML, JavaScript (Vue.js), CSS - REST API: Programmatischer Zugriff auf alle Funktionen - GraphQL API: Moderne, flexible Datenabfrage - Business Logic: User-Management, Permissions, Merge Requests, Issues
Die Application läuft in Puma-Worker-Prozessen. Typischerweise 2-4 Workers pro CPU-Core. Jeder Worker kann mehrere Threads bedienen.
Skalierung: Horizontal – mehrere Application-Server hinter Load-Balancer.
Relevanz für CI/CD: Diese Komponente verarbeitet
.gitlab-ci.yml, erstellt Pipeline-Objekte in der Datenbank,
triggert Runner via API.
Rolle: Frontend-Webserver, SSL-Termination, Request-Routing
NGINX nimmt alle HTTP/HTTPS-Requests entgegen und routet sie: - Statische Assets (CSS, JS, Images) → Direkt ausgeliefert (gecached) - API/Web-Requests → Workhorse - Git HTTP Operations (clone, push) → Workhorse
NGINX handelt auch: - SSL/TLS: Zertifikate, Verschlüsselung - Rate Limiting: Schutz vor Abuse - Request Buffering: Verhindert Slow-Client-Probleme
Konfiguration: /etc/gitlab/nginx/ (bei
Omnibus) oder /var/opt/gitlab/nginx/conf/
Relevanz für CI/CD: NGINX routet Webhook-Requests (z.B. von Git Pushes), die Pipelines triggern.
Sprache: Go Rolle: Smart Reverse-Proxy, Application-Gateway
Workhorse sitzt zwischen NGINX und Rails. Es übernimmt rechenintensive Aufgaben, die Rails nicht effizient handeln kann:
Git HTTP Operations: - git clone,
git pull, git push über HTTP/HTTPS - Workhorse
streamt Daten direkt zu/von Gitaly, umgeht Rails
Large File Handling: - Artifact-Uploads (CI/CD Job Artifacts) - LFS (Large File Storage) Uploads - Container Image Uploads (Registry)
Authentisierung: Workhorse validiert Requests mit Rails, führt dann Operation selbst aus (effizient, kein Ruby-Overhead).
Interne API: Workhorse kommuniziert mit Rails über interne Socket-Verbindung.
Relevanz für CI/CD: Artifacts, Cache, Docker Images – alles läuft durch Workhorse. Ohne Workhorse würde Rails unter Last zusammenbrechen.
Sprache: Go Rolle: Zentrale Git-Repository-Verwaltung
Git-Operationen sind historisch problematisch in Rails: Ruby ist langsam für Git-interne Operations, NFS-Storage für Repositories skaliert schlecht.
Gitaly löst das: Es ist ein dedizierter Service für Git-Operationen, erreichbar via gRPC.
Funktionen: - Git Operations: Read, Write, Branch, Tag, Merge - Repository Maintenance: Garbage Collection, Repacking - Blob Analysis: Diff-Berechnung, File History - Access Control: Implementiert GitLab-Permissions für Git-Level
Architektur: Ein oder mehrere Gitaly-Nodes, jeder hostet Repositories auf lokalem Disk (nicht NFS).
Gitaly Cluster (Premium/Ultimate): High-Availability mit Replikation, automatischem Failover.
Relevanz für CI/CD: Jeder Pipeline-Job clont Code von Gitaly. Gitaly-Performance = CI/CD-Performance.
Sprache: Go Rolle: SSH-Gateway für Git-Operations
Wenn User git clone git@gitlab.com:user/project.git
ausführen: 1. SSH-Server nimmt Verbindung an 2. Ruft GitLab Shell auf
(via AuthorizedKeysCommand oder
authorized_keys) 3. GitLab Shell authentifiziert User (via
Rails API) 4. GitLab Shell führt Git-Command aus (via Gitaly)
SSH Key Management: GitLab Shell verwaltet SSH-Keys, die User in GitLab-UI hochladen.
Relevanz für CI/CD: Weniger direkt, aber wichtig für
Entwickler-Workflow (lokales git push triggert
Pipelines).
Sprache: Ruby (wie Rails) Rolle: Asynchrone Job-Verarbeitung
Nicht alle Tasks sollten synchron während HTTP-Request laufen. Sidekiq verarbeitet:
CI/CD Jobs: - Pipeline-Erstellung aus
.gitlab-ci.yml - Job-Scheduling an Runner -
Artifact-Processing nach Job-Completion
Andere Jobs: - Email-Versand - Webhook-Delivery - Repository-Maintenance - Notification-Dispatch - Import/Export von Projekten
Architektur: Multiple Sidekiq-Prozesse (Workers), jeder verarbeitet Jobs aus Redis-Queues.
Queues: Verschiedene Queues für verschiedene
Prioritäten: - pipeline: Hohe Priorität,
Pipeline-Processing - default: Standard-Aufgaben -
mailers: Email-Versand - background_migration:
DB-Migrations
Relevanz für CI/CD: Ohne Sidekiq keine Pipelines. Wenn Sidekiq überlastet, verzögern sich Pipeline-Starts.
Rolle: Persistente Datenspeicherung
PostgreSQL speichert alle GitLab-Daten: - Users, Groups,
Projects: Struktur und Permissions - Issues, Merge
Requests: Content, Metadaten, Comments - CI/CD
Configuration: .gitlab-ci.yml gespeichert
(gecached) - Pipeline Runs: Jobs, Status, Logs,
Artifacts-Referenzen - Git Metadata: Referenzen zu
Gitaly-Repositories
Schema: Hunderte Tabellen, Millionen Rows in großen Instanzen.
Skalierung: - Read Replicas: Für Read-Heavy Workloads - Connection Pooling (PgBouncer): Limitiert DB-Connections - Partitioning: Große Tabellen (z.B. CI-Logs) werden partitioniert
Backups: Kritisch. GitLab bietet
gitlab-backup Tool für konsistente Backups.
Relevanz für CI/CD: Jede Pipeline schreibt tausende DB-Rows (Jobs, Logs, Artifacts). DB-Performance ist kritisch für CI/CD-Throughput.
Rolle: Caching, Session-Speicher, Job-Queues
GitLab nutzt Redis intensiv:
Caching: - User-Sessions - API-Response-Caching - Git-Metadata-Caching
Job-Queues: Sidekiq nutzt Redis für Job-Queues.
Real-Time Features: - Live-Updates in Web-UI (via ActionCable) - Pipeline-Status-Updates
Rate Limiting: Request-Rates werden in Redis getrackt.
Skalierung: GitLab kann multiple Redis-Instanzen nutzen: - Redis für Caching - Separate Redis für Sidekiq-Queues - Separate Redis für Shared State
Redis Sentinel/Cluster: High-Availability für Redis.
Relevanz für CI/CD: Sidekiq-Jobs (inkl. Pipeline-Jobs) sind in Redis-Queues. Redis-Probleme = keine Pipeline-Starts.
Sprache: Go (basiert auf Docker Distribution) Rolle: Docker Image Storage
Wenn CI/CD Docker-Images baut, können sie direkt in GitLab Registry gepusht werden:
build:
stage: build
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHAStorage: Registry speichert Images in Object Storage (S3, Azure Blob, Google Cloud Storage) oder lokalem Filesystem.
Integration: Registry ist per-Projekt.
registry.gitlab.com/user/project ist automatisch
verfügbar.
Authentication: Via GitLab-Tokens, keine separate User-DB.
Relevanz für CI/CD: Zentral für Container-basierte Workflows. Build → Push → Deploy Pipeline.
Sprache: Go Rolle: CI/CD Job Execution
Runner sind separate Prozesse/Server, die Jobs ausführen. Sie sind nicht Teil der GitLab-Server-Installation.
Architektur: 1. Runner registriert sich bei GitLab (via Registration-Token) 2. Runner pollt GitLab für verfügbare Jobs (via API) 3. Wenn Job verfügbar: Runner nimmt Job, führt aus, reportet Ergebnis zurück
Executor-Types: - Shell: Führt Commands direkt in Shell aus (auf Runner-OS) - Docker: Führt Jobs in Docker-Containern aus (isoliert, clean) - Kubernetes: Pods für Jobs (hochskalierbar) - VirtualBox/Parallels: VMs für Jobs - SSH/Docker+Machine: Dynamische Provisioning
Shared vs. Specific Runners: - Shared: Verfügbar für alle Projekte (auf GitLab.com: GitLab-managed) - Specific: Registriert für spezifisches Projekt (eigene Hardware)
Runner Configuration (config.toml):
[[runners]]
name = "my-runner"
url = "https://gitlab.com/"
token = "registration-token"
executor = "docker"
[runners.docker]
image = "alpine:latest"
privileged = false
volumes = ["/cache"]
[runners.cache]
Type = "s3"
Shared = trueRelevanz für CI/CD: Ohne Runner keine Job-Ausführung. Runner-Kapazität = CI/CD-Kapazität.
Dieser Flow zeigt: 1. NGINX nimmt Git-Push entgegen 2. Workhorse handelt Git-Protocol 3. Rails authentifiziert und autorisiert 4. Gitaly speichert Git-Objekte 5. Sidekiq verarbeitet Push-Event, erstellt Pipeline 6. Runner führt Jobs aus
Alle Komponenten auf einem Server:
Geeignet für: < 100 User, < 500 Projects
Komponenten auf separate Server verteilt:
Geeignet für: 100-1000 User, 1000-10000 Projects
Alle Komponenten als Pods, hochskalierbar:
Vereinfachte Helm-Konfiguration:
# Vereinfachtes Helm-Deployment
gitlab:
replicas:
webservice: 3 # Rails Pods
sidekiq: 5 # Sidekiq Pods
gitaly: 2 # Gitaly Statefulsets
postgresql:
persistence: true
size: 100Gi
redis:
replicas: 3
registry:
enabled: true
storage: s3Geeignet für: 1000+ User, Enterprise-Scale, Cloud-Native Environments
GitLab exportiert Metriken für alle Komponenten:
GitLab integriert mit Prometheus:
# Wichtige Metriken
gitlab_transaction_duration_seconds # Request Latency
gitlab_sql_duration_seconds # DB Query Time
sidekiq_jobs_processed_total # Job Throughput
gitaly_service_client_requests_total # Git OperationsGrafana Dashboards: Visualisieren GitLab-Metriken
Key Indicators: - Request Rate: Requests/Sekunde - Error Rate: 5xx Responses/Sekunde - Latency: p50, p95, p99 Response Times - Job Queue Depth: Wartende Sidekiq-Jobs - Runner Utilization: Aktive vs. Idle Runners
GitLab-Backups müssen mehrere Komponenten umfassen:
1. PostgreSQL Database:
gitlab-rake gitlab:backup:create2. Git Repositories (Gitaly): - Entweder im Backup enthalten - Oder separate Gitaly-Backup-Strategie
3. Configuration: -
/etc/gitlab/gitlab.rb - SSL-Zertifikate -
Runner-Registrations
4. Secrets: - Database-Encryption-Keys - CI/CD Secret-Variables
Recovery:
gitlab-rake gitlab:backup:restore
Best Practice: Automatisierte tägliche Backups, Offsite-Storage, regelmäßige Restore-Tests.
GitLab ist kein monolithisches System, sondern ein Ökosystem spezialisierter Komponenten:
Frontend-Layer: NGINX, Workhorse → Empfangen Requests, routen effizient Application-Layer: Rails → Business-Logic, Web-UI, API Git-Layer: Gitaly, GitLab Shell → Git-Operations hochperformant Data-Layer: PostgreSQL, Redis → Persistenz und Caching Background-Layer: Sidekiq → Asynchrone Verarbeitung Execution-Layer: GitLab Runner → CI/CD Job-Ausführung Storage-Layer: Registry, Object Storage → Artifacts, Images, Caches
Diese Architektur ermöglicht: - Skalierbarkeit: Jede Komponente kann horizontal skaliert werden - Performance: Spezialisierte Services für spezifische Aufgaben - Reliability: Komponenten können unabhängig ausfallen, Redundanz möglich - Flexibility: Self-Managed, SaaS, Hybrid – dieselbe Architektur
Für CI/CD ist entscheidend zu verstehen: - Sidekiq
erstellt Pipelines aus .gitlab-ci.yml -
Runner führen Jobs aus - Gitaly
liefert Code an Runner - Registry speichert Docker
Images - PostgreSQL trackt Job-Status -
Redis queued Jobs
Ohne dieses Verständnis ist Troubleshooting schwierig. Mit diesem Verständnis kann man gezielt Performance optimieren, Bottlenecks identifizieren, und GitLab-Deployments planen, die für spezifische Workloads optimiert sind.
GitLab ist eine Maschine aus vielen Zahnrädern. Jedes Zahnrad ist wichtig, aber erst ihr Zusammenspiel macht DevOps-Automatisierung möglich.