Automatické čištění Docker cache volumes pro Gitlab Runner
Jak vyřešit problém s neustále rostoucími Docker volumes pro GitLab Runner cache a nastavit jejich automatické čištění.
Problém
GitLab Runner při použití Docker executoru vytváří volumes pro ukládání cache mezi buildy. Tyto volumes však nemají žádný vestavěný mechanismus pro automatické čištění a postupem času mohou narůst do obřích rozměrů – není výjimkou vidět stovky gigabajtů či dokonce terabajty obsazeného místa.
Volumes můžete zobrazit příkazem:
docker volume ls | grep runner
A jejich velikost zjistíte pomocí:
for vol in $(docker volume ls -q | grep -E '^runner-.*-cache'); do
SIZE=$(docker run --rm -v "$vol":/data alpine du -sh /data 2>/dev/null | cut -f1)
echo "$SIZE $vol"
done
Typický výstup může vypadat následovně:
132G runner-yd6eca4h-project-100-concurrent-0-cache-3c3f060a0374fc8bc39395164f415a70
124G runner-88bmy4dg2-project-100-concurrent-0-cache-3c3f060a0374fc8bc39395164f415a70
29G runner-0558e6a41bfb19b22a086fc2330d186c-cache-3c3f060a0374fc8bc39395164f415a70
Všimněte si dvou různých formátů pojmenování – starší verze GitLab Runneru (před 15.x) používaly 32-znakový hash, novější verze používají formát runner-{system_id}-project-{id}-concurrent-{n}.
Příčina
GitLab Runner vytváří nové cache volumes při:
- změně
cache:keyv.gitlab-ci.yml - přeregistraci runneru (nové
system_id) - změně projektu nebo větve (záleží na konfiguraci cache key)
Staré volumes však zůstávají na disku a nejsou automaticky mazány. Navíc při přeregistraci runneru vznikne nové system_id a všechny předchozí volumes se stanou "osiřelými".
Aktuální system_id vašeho runneru zjistíte příkazem:
cat /etc/gitlab-runner/.runner_system_id
Řešení
Jednorázové vyčištění
GitLab Runner obsahuje oficiální skript pro vyčištění cache. Na Debian/Ubuntu je součástí balíčku gitlab-runner a najdete jej v /usr/share/gitlab-runner/clear-docker-cache.
/usr/share/gitlab-runner/clear-docker-cache
Skript nabízí několik možností:
# Zobrazí nápovědu
/usr/share/gitlab-runner/clear-docker-cache help
# Smaže pouze osiřelé volumes (výchozí)
/usr/share/gitlab-runner/clear-docker-cache prune-volumes
# Smaže všechny runner cache volumes
/usr/share/gitlab-runner/clear-docker-cache space
Oficiální skript obsahuje workaround pro změnu chování v Docker 23.0, který uměle snižuje API verzi na 1.41. U novějších verzí Dockeru (API 1.44+) to způsobuje chybu, např.:
Error response from daemon: client version 1.41 is too old. Minimum supported API version is 1.44
V takovém případě použijte přímo Docker příkazy:
# Smaže volumes s GitLab Runner labelem
docker volume prune -f --filter "label=com.gitlab.gitlab-runner.managed=true"
Pro ruční smazání všech cache volumes:
docker volume ls -q | grep -E '^runner-.*-cache' | xargs -r docker volume rm
Automatické čištění pomocí cron
Pro pravidelné čištění vytvořte soubor /etc/cron.d/gitlab-runner-cache-cleanup:
# Každou neděli ve 3:00 smaže nepoužívané runner cache volumes
0 3 * * 0 root docker volume prune -f --filter "label=com.gitlab.gitlab-runner.managed=true" >> /var/log/gitlab-runner-cache-cleanup.log 2>&1
Prevence
Pro omezení růstu cache přímo v projektech lze v .gitlab-ci.yml nastavit expiraci:
cache:
key:
files:
- package-lock.json # nová cache pouze při změně dependencies
paths:
- node_modules/
expire_in: 1 week
Nastavení expire_in však funguje pouze na úrovni GitLab serveru, ne na úrovni Docker volumes. Pro skutečné omezení velikosti na úrovni runneru je nutné použít výše popsané čištění.
Další zdroje
Potřebujete více informací?
Zpráva byla úspěšně odeslána.
Děkujeme
Omlouváme se, ale zprávu se nepovedlo odeslat.
Budeme rádi, když nám o tomto dáte vědět na info@id-sign.com