Was ist Gitlab? Ein Versions Control System.
Wer es genauer wissen möchte: https://de.wikipedia.org/wiki/GitLab
Hier geht es konkret um das selbstgehostete Gitlab als Docker image.
Dieses Biest ist ziemlich komplex, wie die Liste der laufenden Prozesse im Container zeigt:
docker exec gitlab gitlab-ctl status
alertmanager
gitaly
gitlab-monitor
gitlab-workhorse
grafana
logrotate
nginx
postgres-exporter
postgresql
prometheus
redis
redis-exporter
sidekiq
sshd
unicorn
Also 15 Dienste/Applikationen! WTF
Ich fand ein uraltes Gitlab gitlab/gitlab-ee:11.10.4-ee.0 vor, also vor 5 Jahren veröffentlicht.
https://about.gitlab.com/releases/
Einige Voreinstellungen hatte ich im Vorfeld noch gemacht, weil das System häufig muckte.
Es gibt etliche Parameter in
/var/lib/docker/volumes/gitlab_config/_data/gitlab.rb
Bewirkt, dass der DB genug Zeit gegeben wird, zu antworten. Das war eine der Hauptursachen für die merkwürdigen Ausfälle von gitlab.
postgresql['max_service_checks'] = 30
postgresql['service_check_interval'] = 5 # seconds
Am besten an zwei Stellen kontrollieren oder anpassen:
im Volume git_lab_config:
docker restart gitlab
Also unbedingt beachten und evtl. noch großzügier sein.
Es gibt noch immer Fehlermeldungen, die bei geringer Last wie hier aber ignoriert werden können:
/opt/gitlab/embedded/bin/runsvdir-start: line 24: ulimit: pending signals: cannot modify limit: Operation not permitted
/opt/gitlab/embedded/bin/runsvdir-start: line 37: /proc/sys/fs/file-max: Read-only file system
Es gibt eine ansich gute interne Dokumentation, mit der ich mich durchgehangelt habe, und dann nach vielen Versuchen auch ein funktionierendes
docker run script erstellt habe.
Das ist der Inhalt von start.cmdline.sh
GITLAB_OMNIBUS_CONFIG ist entscheidend, will man ssl und https benutzen.
Hier wird es benutzt, u.a. weil user per ldap über Domain Controller authentiziert werden.
docker run -d --name=gitlab -e TZ=Europe/Berlin \
--env GITLAB_OMNIBUS_CONFIG="external_url 'https://gitlab.firma.de/'; nginx['redirect_http_to_https'] = true; nginx['ssl_certificate'] ='/var/opt/gitlab/ssl/server-cert.pem'; nginx['ssl_certificate_key'] = '/var/opt/gitlab/ssl/server-key.pem' " \
-v /var/lib/docker/volumes/gitlab_cert/_data:/var/opt/gitlab/ssl \
-v /var/lib/docker/volumes/gitlab_config/_data:/etc/gitlab \
-v /var/lib/docker/volumes/gitlab_data/_data:/var/opt/gitlab \
-v /var/lib/docker/volumes/gitlab_logs/_data:/var/log/gitlab -p 2222:22 -p 443:443 -p 80:80 \
--restart unless-stopped gitlab/gitlab-ee:11.10.5-ee.0
Warum habe ich nicht mit einem docker-compose.yml die übersichtlichere compose Variante gewählt?
Gute Frage, leider hat das yml beim zweiten Upgrade einen irrationalen Fehler geworfen, der mich aufgeben liess. Mit dem start.cmdline.sh bin ich aber sehr glücklich. Da ich über kurz oder lang dann auch dockge installieren will, ist das
mit docker run und mit compose möglich.
Lange Vorrede, kommen wir nun zur upgrade Strategie, die ich verwende.
Bevor man sich auf das Abenteuer einlässt, sollte man sich Gedanken über eine solide Backup und Restore Strategie machen.
cat backup-gitlab.sh
#!/bin/bash
# backup-gitlab.sh by bed
# Sichert alle volumes von Gitlab in /backup/volumes/
# zum starten sollte gitlab pausiert werden
# Laufzeit ca. 15 Minuten Speicherbedarf 5GB
# docker volumes ls zeigt die volumes an
# Backup Aller Datenbanken komprimiert
#docker exec gitlab pg_dumpall -c -U POSTGRESUSER | gzip > backup.sql.gz
# da fehlt noch der socket, nicht weiter untersucht
# Name
if [ $# -eq 0 ]
then
echo "Gebrauch:"
echo "$0 Kuerzel"
echo "Z.B."
echo "$(docker logs gitlab|grep 'Current version: gitlab-ee=')"
exit 0
fi
echo "Benutze $1 als Tag"
echo "Der gitlab Container wurde mit \"docker pause gitlab\" angehalten?"
echo -n "Eine Taste drücken, oder ctrl-C zum Abbruch"
read -r keypressed
# gitlab_data
docker run --rm \
-v /backup/volumes:/backup \
-v gitlab_data:/data:ro \
debian:bullseye-slim bash -c "cd /data && /bin/tar -czvf /backup/gitlab-data-$1.tar.gz ."
# gitlab_config
docker run --rm \
-v /backup/volumes:/backup \
-v gitlab_config:/data:ro \
debian:bullseye-slim bash -c "cd /data && /bin/tar -czvf /backup/gitlab-config-$1.tar.gz ."
# gitlab_cert
docker run --rm \
-v /backup/volumes:/backup \
-v gitlab_cert:/data:ro \
debian:bullseye-slim bash -c "cd /data && /bin/tar -czvf /backup/gitlab-cert-$1.tar.gz ."
# gitlab_logs
docker run --rm \
-v /backup/volumes:/backup \
-v gitlab_logs:/data:ro \
debian:bullseye-slim bash -c "cd /data && /bin/tar -czvf /backup/gitlab-logs-$1.tar.gz ."
# docker Sicherung
docker commit -p gitlab backup-$1
docker save -o /backup/gitlab-$1.tar backup-$1
cat restore-gitlab.sh
#!/bin/bash
# restore-gitlab.sh by bed
# restored alle volumes von Gitlab aus /backup/volumes/
if [ $# -eq 0 ]
then
echo "Gebrauch:"
echo "$0 Kuerzel"
echo "Z.B."
echo "$0 11.10.4-ee.0"
echo "Wenn auch der Container restored werden soll: docker load -i /backup/gitlab-[kürzel].tar "
exit 0
fi
echo "Benutze $1 als Tag"
echo "Der gitlab Container wurde mit \"docker pause gitlab\" angehalten?"
echo -n "Eine Taste drücken, oder ctrl-C zum Abbruch"
read -r keypressed
# docker volumes ls zeigt die volumes an
# gitlab_data
docker run --rm \
-v /backup/volumes:/backup \
-v gitlab_data:/data \
debian:bullseye-slim bash -c "cd /data && /bin/tar -xzvf /backup/gitlab-data-$1.tar.gz"
# gitlab_config
docker run --rm \
-v /backup/volumes:/backup \
-v gitlab_config:/data \
debian:bullseye-slim bash -c "cd /data && /bin/tar -xzvf /backup/gitlab-config-$1.tar.gz"
# gitlab_cert
docker run --rm \
-v /backup/volumes:/backup \
-v gitlab_cert:/data \
debian:bullseye-slim bash -c "cd /data && /bin/tar -xzvf /backup/gitlab-cert-$1.tar.gz"
# gitlab_logs
docker run --rm \
-v /backup/volumes:/backup \
-v gitlab_logs:/data \
debian:bullseye-slim bash -c "cd /data && /bin/tar -xzvf /backup/gitlab-logs-$1.tar.gz"
Wenn etwas nicht funktioniert und man eine Version wieder einspielen muss, dann geht das für z.B. 13.12.15 so:
./restore-gitlab.sh 13.12.15
docker rename gitlab gitlab_13.12.15-ee.0_works_restore (kann weg)
./start.cmdline.sh_13.12.15 ✅
https://gitlab geht wieder
cat progress-anzeige.sh
#!/bin/bash
while :;do
echo "$(date) : new run..."
echo "$(date) : background jobs remaining $(docker exec -ti gitlab gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining')"
echo "$(date) : background jobs queued $(docker exec -ti gitlab gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.queued.count')"
# the following only for version 14.0 - 14.9
#echo "$(date) : failed migrations $(docker exec -ti gitlab gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.failed.count')"
# the following only for version >= 14.10
echo "$(date) : failed migrations $(docker exec -ti gitlab gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.with_status(:failed).count')"
sleep 1
done
Anfangs, also zu Version 11.10.4 Zeiten gab es fortwährend Performance Probleme, die im Wesentlichen an einer zu großen Logfile Sammlung lagen.
Im Gitlab Container werden alle Dienste in ein Log gesammelt das erreicht riesige Höhen.
cat clear_docker_container_logs.sh
#!/bin/bash
CLIST=""
help()
{
echo "Usage: $0 [-c \"<container>\"]"
echo ""
echo "By default, logs for all containers are cleared."
echo ""
echo -e "\t-c \"<container>\" Specific container(s) name or docker-compose service(s) name"
exit 1
}
if [ $# == 0 ]; then
echo "Clear logs for all containers"
CLIST="$(docker ps -aq)"
elif [ "$1" == "--" ] || [[ "$1" =~ ^-$ ]] || ! [[ "$1" =~ ^- ]]; then
help
else
while getopts "c:" opt; do
case $opt in
c)
CNAMES+=("$OPTARG")
echo "Clear logs for \"$CNAMES\"" ;;
\?) help ;;
esac
done
shift $((OPTIND -1))
if ! [ "$1" == "" ]; then
help
fi
fi
for i in $CNAMES; do
CONTAINERS=$(docker ps -aq -f name=$i 2> /dev/null)
if [ "$CONTAINERS" == "" ]; then
CONTAINERS="$(docker-compose ps -aq $i 2> /dev/null)"
if [ -z $CONTAINERS ]; then
echo "Container or service \"$i\" does not exist."
fi
fi
CLIST+=$CONTAINERS$'\n'
done
for i in $CLIST; do
log=$(docker inspect -f '{{.LogPath}}' $i 2> /dev/null)
truncate -s 0 $log
done
Immer schauen, ob reichlich Platz für das Backup un das installieren eines neuen Image zur Verfügung steht.
Wenn es knapp wird, lieber vorher aufräumen, das vermeidet streß und gefährdet nicht das upgrade.
Was notfalls weg kann, sind die gesavten -container, also die unter /backup/, weil die werden beim Restore nicht benötigt.
Auch nicht mehr benötigte Images löschen bringt sehr viel.
Stichwort LZD .
Meine durchgeführten Schritte habe ich immer mit ✅ markiert, hat sich bewährt
Damit ist alles getan. Es kann ein weiteres Upgrade erfolgen.
Bei DB Changes lieber einen Arbeitstag verstreichen lassen.
Im gitlab Container postgres psql ausführen:
docker exec -it -u gitlab-psql gitlab psql -h /var/opt/gitlab/postgresql/ -d gitlabhq_production
oder auch Tagebuch
Änderungen u.a.
Die Dienste haben sich geändert:
$ docker exec gitlab gitlab-ctl status
run: alertmanager: (pid 1306) 79957s; run: log: (pid 1017) 79994s
run: gitaly: (pid 1280) 79957s; run: log: (pid 283) 80160s
run: gitlab-exporter: (pid 930) 80013s; run: log: (pid 941) 80010s
run: gitlab-workhorse: (pid 1248) 79959s; run: log: (pid 873) 80030s
run: grafana: (pid 1336) 79956s; run: log: (pid 1047) 79986s
run: logrotate: (pid 11906) 815s; run: log: (pid 918) 80018s
run: nginx: (pid 888) 80025s; run: log: (pid 903) 80024s
run: postgres-exporter: (pid 1325) 79957s; run: log: (pid 1023) 79993s
run: postgresql: (pid 391) 80155s; run: log: (pid 417) 80152s
run: prometheus: (pid 1287) 79957s; run: log: (pid 983) 80000s
run: puma: (pid 829) 80043s; run: log: (pid 839) 80041s
run: redis: (pid 241) 80167s; run: log: (pid 248) 80165s
run: redis-exporter: (pid 1263) 79958s; run: log: (pid 964) 80004s
run: sidekiq: (pid 844) 80037s; run: log: (pid 854) 80036s
run: sshd: (pid 32) 80182s; run: log: (pid 31) 80182s
unicorn wurde durch puma ersetzt
Das ist insofern wichtig, weil im Upgrade Prozess manchmal Abhängigkeiten zu beachten sind
# Version 16.08
# docker exec gitlab gitlab-ctl status
run: alertmanager: (pid 966) 81038s; run: log: (pid 697) 81101s
run: gitaly: (pid 878) 81047s; run: log: (pid 316) 81339s
run: gitlab-exporter: (pid 944) 81041s; run: log: (pid 625) 81121s
run: gitlab-kas: (pid 892) 81042s; run: log: (pid 459) 81279s
run: gitlab-workhorse: (pid 904) 81042s; run: log: (pid 580) 81135s
run: logrotate: (pid 4533) 2145s; run: log: (pid 271) 81353s
run: nginx: (pid 597) 81130s; run: log: (pid 609) 81129s
run: postgres-exporter: (pid 976) 81039s; run: log: (pid 714) 81097s
run: postgresql: (pid 322) 81331s; run: log: (pid 331) 81327s
run: prometheus: (pid 953) 81040s; run: log: (pid 666) 81110s
run: puma: (pid 527) 81148s; run: log: (pid 534) 81147s
run: redis: (pid 275) 81348s; run: log: (pid 284) 81347s
run: redis-exporter: (pid 946) 81042s; run: log: (pid 647) 81116s
run: sidekiq: (pid 545) 81143s; run: log: (pid 564) 81139s
run: sshd: (pid 28) 81381s; run: log: (pid 27) 81381s
GitLab 13: 13.0.14 > 13.1.11 > 13.8.8 > 13.12.15
Details findet man z.B. so GitLab 13.1.11 patch release
https://docs.gitlab.com/ee/update/#upgrade-paths
GitLab 14: 14.0.12 > 14.3.6 > 14.9.5 > 14.10.5.
GitLab 15: 15.0.5 > 15.1.6 (for GitLab instances with multiple web nodes) > 15.4.6 > 15.11.13.
GitLab 16: 16.0.8 (only instances with lots of users or large pipeline variables history) > 16.1.6 (instances with NPM packages in their package registry) > 16.2.9 (only instances with large pipeline variables history) > 16.3.7 > 16.7.z > latest 16.Y.Z.
https://docs.gitlab.com/ee/update/#required-upgrade-stops
https://docs.gitlab.com/ee/update/versions/gitlab_14_changes.html
Beim Upgrade auf 14.0.12 kam es zu einem Fehler.
https://stackoverflow.com/questions/71251616/upgrade-failed-retry-the-upgrade-after-migrating-your-data-to-hashed-storage.
Abbruchmeldung:
gitlab Reconfigured!
Checking for unmigrated data on legacy storageLegacy storage is no longer supported. Please migrate your data to hashed storage.
Check https://docs.gitlab.com/ee/administration/raketasks/storage.html#migrate-to hashed->storage for details.
Upgrade failed. Retry the upgrade after migrating your data to hashed storage.
Also alte Version 13.12.15 restored und erstmal über die Fehlermeldung sinniert.
Es findet sich im Web einiges dazu. Mein Ansatz war:
docker pause gitlab
Frisches Backup machen, kein Rename und kein Stop
Dann
docker exec -it gitlab gitlab-rake gitlab:storage:migrate_to_hashed ✅
Enqueuing migration of 27 projects in batches of 200. Done! ✅
Eigentlich sollte das nun erledigt sein, weil ich aber etliches Wehklagen im Web fand, habe ich zusätzlich folgendes gemacht.
Die Schritte gemäß https://gitlab.com/-/snippets/2039252
durchgeführt:
docker exec -it gitlab bash
root@1d9302ef325f:/# wget -O /tmp/fix-legacy-hashed-storage-migration.rb https://gitlab.com/snippets/2039252/raw
--2024-03-07 10:51:05-- https://gitlab.com/snippets/2039252/raw
Resolving gitlab.com (gitlab.com)... 172.65.251.78, 2606:4700:90:0:f22e:fbec:5bed:a9b9
Connecting to gitlab.com (gitlab.com)|172.65.251.78|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1218 (1.2K) [text/plain]
Saving to: ‘/tmp/fix-legacy-hashed-storage-migration.rb’
/tmp/fix-legacy-hashed-storage-migration.rb 100%[=====================================================================================================>] 1.19K --.-KB/s in 0s
root@1d9302ef325f:/# gitlab-rails runner /tmp/fix-legacy-hashed-storage-migration.rb
root@1d9302ef325f:/# gitlab-rake gitlab:storage:migrate_to_hashed
There are no projects requiring storage migration. Nothing to do!
root@1d9302ef325f:/# gitlab-rake gitlab:storage:list_legacy_projects
* Found 0 projects using Legacy Storage ✅
root@1d9302ef325f:/# gitlab-rake gitlab:storage:list_legacy_attachments
* Found 0 attachments using Legacy Storage ✅
Jetzt sollte gitlab weiterhin funktionsfähig sein.
Zur Sicherheit ein Wochenende warten, dann erneut das Upgrade zu 14.0 durchführen
Zurück
docker exec -it gitlab gitlab-rake
gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,events,id,'"id"], ["id_convert_to_bigint"']
docker exec -it gitlab gitlab-rake gitlab:check SANITIZE=true
Die Startzeit ist zu kurz, um die oberen beiden commandos abzusetzen.
ich restore jetzt die 14.0.12
./restore-gitlab.sh 14.0.12 dauert 10 Minuten ✅
./start.cmdline.sh_14.0.12 dauert ca. 8 Minuten ✅
Damit ist die 14.0.12 wieder online.
Zurück
Gibt Fehler ala:
==> /var/log/gitlab/gitlab-rails/gitlab-rails-db-migrate-2024-02-23-10-26-21.log <==
rake aborted!
Errno::ENOSPC: No space left on device @ dir_s_mkdir - /tmp/prometheus-mmap20240223-267-40fji
https://git erreichbar ? Ja ✅
Repariert mit:
docker exec -it gitlab gitlab-rake gitlab:check SANITIZE=true
Liefert Fehler und gibt Empfehlungen:
Minor Error
docker exec gitlab chown -R git /var/opt/gitlab/gitlab-rails/uploads
docker exec gitlab find /var/opt/gitlab/gitlab-rails/uploads -type f -exec chmod 0644 {} \;
docker exec gitlab find /var/opt/gitlab/gitlab-rails/uploads -type d -not -path /var/opt/gitlab/gitlab-rails/uploads -exec chmod 0700 {} \;
Erneutes ausführen von
docker exec -it gitlab gitlab-rake gitlab:check SANITIZE=true ✅
Gibt keine Fehler mehr ✅
z.B. so:
alias LZD='docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock -v /.config:/.config/jesseduffield/lazydocker lazyteam/lazydocker'
postgresql Version checken
docker exec gitlab gitlab-psql --version psql (PostgreSQL) 11.7 ✅
Aufruf dauert ca. 2,5 Minuten lang, nicht nervös werden!
docker exec -it gitlab gitlab-rails console
--------------------------------------------------------------------------------
Ruby: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
GitLab: 13.12.15-ee (e4445d58bff) EE
GitLab Shell: 13.18.1
PostgreSQL: 12.6
--------------------------------------------------------------------------------
quit # ende
---
time docker exec -it gitlab gitlab-rails console
quit
--------------------------------------------------------------------------------
Ruby: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
GitLab: 14.0.12-ee (e8d8b151f23) EE
GitLab Shell: 13.19.1
PostgreSQL: 12.7
--------------------------------------------------------------------------------
Loading production environment (Rails 6.1.3.2)
irb(main):001:0> quit
real 1m16,083s
user 0m0,025s
sys 0m0,042s
$ docker exec gitlab gitlab-ctl status
Omnibus (GitLab): Eine Paketierungsmethode, bei der alle erforderlichen Komponenten, wie die Datenbank, Webserver und andere Abhängigkeiten, in einem einzigen Paket gebündelt sind. Dies erleichtert die Installation und Wartung von GitLab, da alle notwendigen Teile in einem Paket enthalten sind.
Docker-Container (GitLab-ee): Eine Technologie, die es ermöglicht, verschiedene Dienste von GitLab in einem isolierten und portablen Container zu bündeln. Dies erleichtert die Bereitstellung und Verwaltung von GitLab, da alle Dienste gemeinsam in einem Container laufen. Auch hier werden noch teilweise Omnibus Konstrukte verwendet.
Alertmanager: Ein Open-Source-Tool zur Verwaltung von Benachrichtigungen und Alarmen in Systemen.
Gitaly: Ein Service, der GitLab-Anfragen für die Git-Repository-Verwaltung behandelt.
GitLab-Monitor: Überwacht die Leistung und Ressourcennutzung von GitLab.
GitLab-Workhorse: Ein Reverse-Proxy, der Anfragen an GitLab-Backends weiterleitet.
Grafana: Eine Open-Source-Analyse- und Visualisierungsplattform für Metriken.
Logrotate: Ein Tool zur Verwaltung von Protokolldateien durch Rotation und Komprimierung.
Nginx: Ein Webserver und Reverse-Proxy für die Bereitstellung von Webanwendungen.
Postgres-Exporter: Ein Exporter für Prometheus, um Metriken aus PostgreSQL-Datenbanken zu sammeln.
PostgreSQL: Ein leistungsstarkes Open-Source-Relationales Datenbankmanagementsystem.
Prometheus: Ein Open-Source-Systemüberwachung- und Alarmierungstool.
Redis: Ein Open-Source-In-Memory-Datenstruktur-Store, der als Datenbank, Cache und Nachrichten-Broker verwendet werden kann.
Redis-Exporter: Ein Exporter für Prometheus, um Metriken aus Redis-Instanzen zu sammeln.
Sidekiq: Ein Hintergrund-Job-Verarbeitungssystem für Ruby.
SSHD: Der SSH-Daemon, der Secure Shell-Zugriff auf das System ermöglicht.
Unicorn: Ein Rack-HTTP-Server für Ruby-Webanwendungen.
Quellennachweis:
die Backup Scripte sind angelehnt an den Scripten von hier https://www.laub-home.de/wiki/Docker_Volume_Backup_Script
progress-anzeige.sh
https://docs.gitlab.com/ee/update/background_migrations.html
https://debianforum.de/forum/viewtopic.php?t=187317