19 GitLab Architektur: Die DevOps-Plattform verstehen

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.

19.1 Von Git zu GitLab: Architekturelle Transformation

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.

19.2 GitLab Deployment-Modi

GitLab existiert in drei Varianten, die dieselbe Architektur nutzen:

19.2.1 GitLab.com (SaaS)

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.

19.2.2 Self-Managed (On-Premise)

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.

19.2.3 GitLab Dedicated (Hybrid)

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.

19.3 Die Kernkomponenten: Deep Dive

19.3.1 1. GitLab Rails Application (Puma)

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.

19.3.2 2. NGINX (Reverse Proxy)

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.

19.3.3 3. GitLab Workhorse

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.

19.3.4 4. Gitaly (Git RPC Service)

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.

19.3.5 5. GitLab Shell

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).

19.3.6 6. Sidekiq (Background Jobs)

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.

19.3.7 7. PostgreSQL (Primary Database)

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.

19.3.8 8. Redis (In-Memory Database)

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.

19.3.9 9. GitLab Container Registry

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_SHA

Storage: 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.

19.3.10 10. GitLab Runner (Separate Komponente)

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 = true

Relevanz für CI/CD: Ohne Runner keine Job-Ausführung. Runner-Kapazität = CI/CD-Kapazität.

19.4 Kommunikationsflüsse: Wie Komponenten interagieren

19.4.1 Git Push → Pipeline Trigger

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

19.4.2 Merge Request → CI/CD → Review

19.5 Skalierungs-Architekturen

19.5.1 Single-Node (Small Teams)

Alle Komponenten auf einem Server:

Geeignet für: < 100 User, < 500 Projects

19.5.2 Multi-Node (Medium Teams)

Komponenten auf separate Server verteilt:

Geeignet für: 100-1000 User, 1000-10000 Projects

19.5.3 Cloud-Native (Kubernetes)

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: s3

Geeignet für: 1000+ User, Enterprise-Scale, Cloud-Native Environments

19.6 Monitoring und Observability

GitLab exportiert Metriken für alle Komponenten:

19.6.1 Prometheus Metrics

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 Operations

19.6.2 Performance Monitoring

Grafana 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

19.7 Backup und Disaster Recovery

GitLab-Backups müssen mehrere Komponenten umfassen:

1. PostgreSQL Database:

gitlab-rake gitlab:backup:create

2. 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.

19.8 Zusammenfassung: GitLab als Ökosystem

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.