Ein Wiki privater Natur

Gitlab-ee Upgrade

Alte Gitlab Container upgraden

Gitlab upgrade path

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

Änderung in 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:

  1. nano /var/lib/docker/volumes/gitlab_config/_data/gitlab.rb
  2. docker exec -it gitlab vim /etc/gitlab/gitlab.rb

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

start.cmdline.sh

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

Compose vs. run

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.


Upgrade Strategie

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.

Scripte

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"

Restore

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

Logfile reduzieren.

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

Protokoll

Meine Schritte:

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


Upgrade Pfad

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

required-upgrade-stops

https://docs.gitlab.com/ee/update/#required-upgrade-stops

https://docs.gitlab.com/ee/update/versions/gitlab_14_changes.html


Fehler 1 Migration storage migrate_to_hashed

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 storage

Legacy 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


Fehler 2 background_migrations:finalize

docker exec -it gitlab gitlab-rake

gitlab:background_migrations:finalizeCopyColumnUsingBackgroundMigrationJob,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


Fehler 3 Errno::ENOSPC: No space left on device

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   ✅  

Zurück


Diverse Checks

Freien Space überwachen

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'

Zurück

Postgres Version

postgresql Version checken
docker exec gitlab gitlab-psql --version psql (PostgreSQL) 11.7 ✅

gitlab-rails console

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

Die internen gitlab Dienste listen :

$ docker exec gitlab gitlab-ctl status

Glossar:


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