Короткий ответ
Универсальной схемы нет: как правило комбинируют immutable-теги (например, git SHA или семантическая версия) для релизных сборок с политикой автоматического удаления непромотированных/временных тегов (CI-сборки, dev-ветки) по возрасту, и отдельно — явно согласованный срок хранения релизных тегов, достаточный для возможных откатов.
Как это работает подробнее
retention/garbage collection политика реестра обычно оперирует правилами вида "удалить образы старше N дней, не соответствующие шаблону тега release-*" или "оставить только последние K тегов для репозитория X". Такая политика безопасна для временных артефактов (сборки для feature-веток, ночные CI-образы), но рискованна для релизных образов, если не учитывает, какие окружения в принципе могут откатываться на старые версии и на какой горизонт времени.
Пример кода
# Пример политики жизненного цикла (концептуально, под Harbor/ECR-подобный реестр)
rules:
- name: keep-releases
tag_pattern: "release-*"
action: keep
retention: unlimited
- name: clean-ci-builds
tag_pattern: "ci-*"
action: delete
older_than_days: 14Что использовать на практике
- Практика. разделяют репозитории или префиксы тегов на категории с разной политикой — например,
myapp:ci-SHAс retention 7-14 дней, иmyapp:v1.4.2(соответствует релизу) с retention на порядок дольше или вовсе без автоматического удаления, с явным процессом архивации в холодное хранилище после истечения активного окна.
Подводные камни
- Риск. применяют одинаковую агрессивную retention-политику ко всем тегам без разделения на временные и релизные, из-за чего случайно удаляется образ, нужный для hotfix-откату редко обновляемого окружения (например, у отдельного крупного клиента на устаревшей версии); не учитывают, что удаление тега без удаления самого слоя (если на него ссылается другой тег) не освобождает реально много места — нужно понимать модель дедупликации конкретного реестра.