· DevOps  · 9 Min. Lesezeit

GitLab über mehrere Versionen upgraden, ohne die Datenbank zu zerlegen

GitLab schreibt beim Sprung über mehrere Versionen feste Zwischenstopps vor. Wie Sie den Pfad vorab berechnen, PostgreSQL rechtzeitig mitheben, die Background Migrations pro Stufe sauber auslaufen lassen und einen Rollback vorbereiten, der im Ernstfall wirklich trägt.

GitLab schreibt beim Sprung über mehrere Versionen feste Zwischenstopps vor. Wie Sie den Pfad vorab berechnen, PostgreSQL rechtzeitig mitheben, die Background Migrations pro Stufe sauber auslaufen lassen und einen Rollback vorbereiten, der im Ernstfall wirklich trägt.

Ein GitLab von einer Hauptversion auf die übernächste zu heben ist kein docker pull mit neuem Tag. Die Doku zu den Upgrade-Pfaden beschreibt den Ablauf pro Stufe in drei Schritten: auf den nächsten Required Stop upgraden, die Background Migrations vollständig durchlaufen lassen, erst dann auf den nächsten Stop. Das ist keine Empfehlung, sondern die Bedingung dafür, dass die nächste Stufe überhaupt startet.

Wann Sie diesen Aufwand betreiben müssen

Bugfixes gehen ausschließlich in das aktuelle Stable-Release, Security-Fixes zusätzlich in die zwei vorherigen Monatsreleases. Wer drei Monate zurückliegt, bekommt keine Sicherheitskorrekturen mehr. Wer regelmäßig aktualisiert, hat pro Wartungsfenster eine Stufe. Wer zwei Jahre wartet, hat eine Kette aus Required Stops, dazwischen mindestens einen PostgreSQL-Sprung und möglicherweise einen Betriebssystem-Wechsel.

Seit GitLab 17.5 liegen die Required Stops nach festem Schema auf x.2.z, x.5.z, x.8.z und x.11.z.

HauptversionRequired Stops
GitLab 1717.1.8 (bedingt), 17.3.7, 17.5.5, 17.8.7, 17.11.7
GitLab 1818.2, 18.5, 18.8, 18.11
GitLab 1919.2, 19.5, 19.8, 19.11

Der Stop 17.1.8 gilt zusätzlich und nur für große Instanzen. Verlassen Sie sich nicht auf eine abgeschriebene Liste: Das vom Support-Team gepflegte Upgrade-Path-Werkzeug berechnet aus Ist- und Ziel-Version die nötigen Stops. Das ist die Quelle, gegen die Sie Ihren Plan prüfen.

Schritt 1: Ist-Stand feststellen

Sie brauchen Version, Edition und PostgreSQL-Version.

sudo gitlab-rake gitlab:env:info

Die Edition erkennen Sie am Suffix, -ee oder -ce. Ein Backup lässt sich nur auf exakt derselben Version und Edition zurückspielen.

Prüfung: Zusätzlich den Migrationsstand kontrollieren.

sudo gitlab-rake db:migrate:status

Steht dort eine Migration auf down, klären Sie das vor jedem Upgrade.

Schritt 2: Den Pfad berechnen und die Abhängigkeiten davorlegen

Jede Hauptversion hat eigene Mindestanforderungen an die Datenbank, und die müssen Sie vor der jeweiligen GitLab-Stufe erfüllen.

GitLab-VersionHelm-ChartPostgreSQL minimalPostgreSQL maximal
16.x7.x13.615.x
17.x8.x14.1416.x
18.x9.x16.517.x
19.x10.x17.x17.x

Die Matrix steht in den Installationsanforderungen. Lesen Sie sie als Reihenfolge: Wer die Kette 17 nach 18 nach 19 plant, braucht zwei PostgreSQL-Sprünge. Dazu kommen Entfernungen, die den Start blockieren. git_data_dirs ist ab GitLab 18.0 weg, die Gitaly-Speicherorte stehen dann unter gitaly['configuration']. GitLab 19 verlangt Redis 7.0 oder Valkey 7.2, ersetzt den s3-Treiber der Container Registry durch s3_v2 und streicht Ubuntu 20.04 sowie SUSE aus den Linux-Paketen.

Prüfung: Die entfernten Schlüssel im Ist-Stand suchen.

grep -n -E '^[^#]*git_data_dirs' /etc/gitlab/gitlab.rb

Ein Treffer bedeutet einen Konfigurationsschritt vor der 18.0.

Schritt 3: PostgreSQL heben, falls die Stufe es verlangt

Beim mitgelieferten PostgreSQL ist der Sprung ein eigener Schritt vor dem GitLab-Schritt. pg-upgrade legt eine zweite vollständige Kopie der Datenbank an. Die Doku formuliert das als Bedingung: Ohne Platz für zwei Kopien soll das Upgrade gar nicht erst starten.

sudo du -sh /var/opt/gitlab/postgresql/data
sudo df -h /var/opt/gitlab
sudo gitlab-ctl pg-upgrade -V 17

GitLab 18.11 liefert PostgreSQL 16.11 und 17.7 mit 17.7 als Default, 19.0 nur noch 17.8.

Prüfung:

sudo gitlab-rake gitlab:env:info | grep -i 'DB Version'

Die Version muss die Mindestanforderung der geplanten Stufe erfüllen, bevor Sie das nächste Image ziehen. Geht etwas schief, kehrt sudo gitlab-ctl revert-pg-upgrade -V 16 zurück.

Schritt 4: Sichern, und zwar vollständig

Das GitLab-Backup enthält die Konfigurationsdateien nicht. Der Grund steht in der Backup-Dokumentation: Die Datenbank enthält verschlüsselte Daten, darunter Zwei-Faktor-Informationen und CI/CD-Variablen. Den Schlüssel neben den verschlüsselten Daten abzulegen hebt den Zweck der Verschlüsselung auf. Sie brauchen daher zwei Aktionen statt einer.

sudo gitlab-backup create
sudo tar -czf /var/opt/gitlab/backups/etc-gitlab-$(date +%F).tar.gz \
  /etc/gitlab/gitlab-secrets.json /etc/gitlab/gitlab.rb

Im Container lautet der erste Befehl docker exec -t gitlab gitlab-backup create. Ablageort ist /var/opt/gitlab/backups, änderbar über gitlab_rails['backup_path'] mit folgendem reconfigure.

Prüfung: Ein angestoßenes Backup ist kein vorhandenes Backup.

ls -lh /var/opt/gitlab/backups/
sudo gitlab-rake gitlab:doctor:secrets

Die Datei muss existieren und eine plausible Größe haben. Der zweite Befehl bestätigt, dass sich die verschlüsselten Datenbankwerte mit den vorhandenen Schlüsseln entschlüsseln lassen. Ich halte diese beiden Zeilen für den wichtigsten Teil des Wartungsfensters, weil sich ein wertloses Backup nur hier noch vor dem Upgrade zeigt. Wie Sie einen Restore testen, steht im Beitrag Backup-Restore-Test.

Schritt 5: Health Checks vor und nach der Stufe

GitLab schreibt Health Checks vor und nach dem Upgrade vor, es sind dieselben zwei Kommandos.

sudo gitlab-rake gitlab:check
sudo gitlab-rake gitlab:doctor:secrets

gitlab:check muss vom Application-Server aus laufen und arbeitet auf Komponenten-Servern wie Gitaly nicht korrekt. Vor einem Major-Upgrade müssen zusätzlich alle Advanced-Search-Migrationen aus dem letzten Minor-Release abgeschlossen sein.

sudo gitlab-rake gitlab:elastic:list_pending_migrations

Prüfung: Die Liste muss leer sein und gitlab:check ohne offene Beanstandungen durchlaufen. Vor dem Schnitt empfiehlt die Doku außerdem, den Maintenance Mode einzuschalten, Pipelines und Jobs zu pausieren und GitLab Runner auf die Zielversion zu heben.

Schritt 6: Eine Stufe fahren

Die Logik ist überall gleich, die Zielversion geben Sie explizit an.

BetriebsartUpgrade auf eine Stufe
Linux-Paketsudo apt install gitlab-ee=<version>-ee.0
DockerContainer stoppen und entfernen, Image mit Versions-Tag ziehen, mit denselben Volumes neu erzeugen
Docker ComposeVersions-Tag ändern, dann docker compose pull und docker compose up -d

Verfügbare Paketversionen zeigt sudo apt-cache madison gitlab-ee. Unter Docker bleibt es beim Tag-Wechsel auf einen versionierten Stand wie gitlab/gitlab-ee:18.11.7-ee.0, die Volumes bleiben unverändert. Wählen Sie das neueste verfügbare Patch-Release der Ziel-Minor, nicht das erste. Die Doku sagt das ausdrücklich.

Prüfung: Nach jeder Stufe die laufende Version gegen den geplanten Stop halten.

sudo gitlab-rake gitlab:env:info | grep -i '^Version'

Schritt 7: Die Background Migrations auslaufen lassen

Dieser Schritt schließt die Stufe ab, und er ist der erste, den Zeitdruck frisst. Der Container läuft und die Oberfläche antwortet, aber solange die Migrationen weiterlaufen, ist die Stufe nicht fertig.

sudo gitlab-rake gitlab:background_migrations:list

Diese Form gilt ab GitLab 18.9. Bis GitLab 18.8 heißt der Task gitlab:background_migrations:status.

Prüfung: Die verbindliche Antwort gibt die Datenbank. Die Doku zu den Background Migrations nennt genau diese Abfrage.

sudo gitlab-psql -c "SELECT job_class_name, table_name, column_name, job_arguments FROM batched_background_migrations WHERE status NOT IN(3, 6);"

Null Zeilen bedeuten, dass alle Migrationen abgeschlossen sind und die nächste Stufe starten darf. Liefert die Abfrage Zeilen, warten Sie. Den Fortschritt zeigt parallel Admin > Monitoring > Background migrations. Auf stark genutzten Instanzen kann die Performance einbrechen, solange die Migrationen laufen. Das ist dokumentiert und kein Defekt.

Schritt 8: Die Stufe abnehmen

Nach den Health Checks aus Schritt 5 nennt die Doku zur Upgrade-Planung eine Prüfliste in der Oberfläche: Anmeldung, sichtbare Projektliste, erreichbare Issues und Merge Requests, ein Klon und ein Push. Gehen Sie diese fünf Punkte ab, bevor Sie die pausierten Pipelines freigeben und den Maintenance Mode abschalten. Dann beginnt die nächste Stufe wieder bei Schritt 4.

Rollback: was tatsächlich möglich ist

Ein Rollback verlangt ein Datenbank-Backup, das unter exakt derselben Version und Edition erstellt wurde, auf die Sie zurückgehen. Deshalb wird pro Stufe gesichert. Beim Linux-Paket lautet die Reihenfolge: Dienste stoppen, Paket entfernen, Zielversion installieren, reconfigure, Backup zurückspielen. Im Container läuft der Restore mit gestoppten puma und sidekiq, die Backup-ID ohne die Endung _gitlab_backup.tar.

docker exec -it gitlab gitlab-ctl stop puma
docker exec -it gitlab gitlab-ctl stop sidekiq
docker exec -it gitlab gitlab-backup restore BACKUP=<backup-id>
docker restart gitlab
docker exec -it gitlab gitlab-rake gitlab:check SANITIZE=true

Der Restore überschreibt den neueren Datenbankstand vollständig durch den älteren. GitLab empfiehlt Rollbacks nur dort, wo es nicht anders geht.

Die vier folgenreichsten Stolpersteine

1. Das Upgrade bricht ab, weil eine Migration noch aktiv ist

Symptom: Der Start der nächsten Stufe endet mit Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active'.

Ursache: Die Migrationen der vorherigen Stufe waren noch nicht durch, als das nächste Image startete. Der Required Stop wurde faktisch übersprungen.

Prüfung: Die Abfrage aus Schritt 7 muss null Zeilen liefern.

Lösung: Zurück auf die vorherige Version, die Migrationen vollständig durchlaufen lassen, erst dann weiter. Eine hängende Migration lässt sich gezielt abschließen:

sudo gitlab-rake gitlab:background_migrations:finalize[<job_class_name>,<table_name>,<column_name>,'<job_arguments>']

Beim manuellen Als-fertig-Markieren warnt die Doku dagegen vor Datenverlust und verlangt vorher Rücksprache mit dem GitLab-Support sowie ein Backup.

2. Die Datenbank ist für die Zielversion zu alt

Symptom: Das Upgrade auf 18.0 oder 19.0 scheitert oder wird blockiert, weil die PostgreSQL-Version nicht ausreicht.

Ursache: PostgreSQL 14 fällt ab GitLab 18 weg, GitLab 19 verlangt mindestens PostgreSQL 17.

Prüfung: gitlab:env:info | grep -i 'DB Version' gegen die Matrix aus Schritt 2 halten.

Lösung: Das PostgreSQL noch unter der alten GitLab-Version heben, mit sudo gitlab-ctl pg-upgrade -V 16 vor der 18 und -V 17 vor der 19.

3. Nach dem Restore scheitern 2FA und Runner-Authentisierung

Symptom: Nutzer mit Zwei-Faktor-Authentisierung kommen nicht mehr hinein, Runner authentisieren sich nicht.

Ursache: Das Backup enthält die Konfigurationsdateien nicht. Ohne /etc/gitlab/gitlab-secrets.json fehlen die Schlüssel für 2FA und die CI/CD-Variablen.

Prüfung: sudo gitlab-rake gitlab:doctor:secrets muss ohne Fehler durchlaufen.

Lösung: gitlab-secrets.json und gitlab.rb bei jedem Backup mitsichern und beim Restore zurückspielen. Ein Backup ohne Secrets-Datei ist für einen Rollback wertlos.

4. Der Sprung landet versehentlich auf der neuesten Version

Symptom: Nach dem Paket-Upgrade läuft eine deutlich höhere Version als geplant, Stops wurden übersprungen.

Ursache: sudo apt install gitlab-ee ohne Versionsangabe zieht das aktuellste verfügbare Paket.

Prüfung: gitlab:env:info | grep -i '^Version' nach jeder Stufe gegen den geplanten Stop halten.

Lösung: Pro Stufe explizit versionieren mit sudo apt install gitlab-ee=<version>-ee.0.

Die übrigen Fallen

Diese vier sind die folgenreichsten, nicht die einzigen. Umbenannte Rake-Tasks, der zusätzliche Stop bei 17.1, Known Issues einzelner Patch-Stände und fehlende Distributionspakete gehören ebenso dazu. Die vollständige Sammlung der Stolpersteine steht im Beitrag GitLab-Upgrade: alle Stolpersteine im Überblick, jeder Fall mit Symptom, Ursache, Prüfung und Lösung. Ich empfehle, sie bei der Planung des Wartungsfensters durchzugehen und nicht erst bei der Fehlersuche.

Grenzen

Diese Anleitung deckt Linux-Paket und Docker ab. Kubernetes über das Helm-Chart und Geo-Installationen verlangen eigene Betrachtung.

Die wichtigste Grenze ist zeitlich. Die Dauer der Batched Background Migrations lässt sich nicht aus der Versionsnummer ableiten, sie hängt an der Größe Ihrer Tabellen. Deshalb empfiehlt GitLab, den Plan in einem Klon der Produktion zu testen. Ein Wartungsfenster, das auf einer geschätzten Migrationsdauer beruht, ist eine Wette. Der Aufwand entsteht ohnehin nicht im Fenster selbst, sondern in den Monaten davor. Wie sich ein regelmäßiger Rhythmus verankern lässt, steht im Beitrag Patch-Management mit Ansible.

Sie betreiben Software, die regelmäßig und sicher aktualisiert werden muss? Ich plane und fahre solche Upgrades mit geprüftem Backup und klarem Rollback, im Wartungsfenster statt im Blindflug. Mehr unter Monitoring & Wartung, das Erstgespräch ist unverbindlich.

Alex Jabi, Jabi IT

Alex Jabi

Ich betreue IT, Informationssicherheit und Datenschutz für KMU und Praxen an der Bergstraße und im Odenwald, persönlich, dokumentiert und ohne Cloud-Zwang.

Mehr über mich
Zurück zum Blog

Passende Artikel

Alle Artikel »
GitLab-Upgrade: alle Stolpersteine im Überblick

GitLab-Upgrade: alle Stolpersteine im Überblick

Die vollständige Fallsammlung zum GitLab-Upgrade über mehrere Required Stops. Von blockierenden Background Migrations über PostgreSQL-Mindestversionen und umbenannte Rake-Tasks bis zu Backups, die sich nicht einspielen lassen. Jeder Fall mit Symptom, Ursache, Prüfung und Lösung.