В процессе сборки и публикации образов приложений Docker-слои создаются, но никогда не удаляются. Как следствие, хранилище стадий и репозиторий образов в Docker registry постоянно увеличивается в размерах, требуя все больше и больше ресурсов. Прерванная сборка образа также оставляет после себя образы, которые уже никогда не будут использоваться.

Таким образом, необходимо периодически производить очистку от неиспользуемых образов как хранилища стадий, так и Docker registry.

В werf реализован эффективный многоуровневый алгоритм очистки образов, использующий следующие подходы:

  1. Очистка по политикам
  2. Ручная очистка
  3. Очистка хоста

Очистка по политикам

Этот метод очистки рассчитан на периодический запуск по расписанию. Удаление производится в соответствии с принятыми политиками очистки и является безопасной процедурой, т.к. при его запуске используются блокировки, а также игнорируются используемые в кластере образы.

Очистка по политикам состоит из двух шагов и выполняется в следующем порядке:

  1. Очистка образов очищает Docker registry от неактуальных образов в соответствии с политиками очистки.
  2. Очистка хранилища стадий синхронизирует состояние хранилища стадий с существующими образами в Docker registry.

Оба указанных способа очистки объединены в команде werf cleanup, при которой сначала выполняется удаление неактуальных образов проекта, а затем синхронизация хранилища стадий.

Docker registry является главным источником информации об образах, поэтому в первую очередь выполняется очистка образов, а уже потом хранилища стадий.

Очистка образов

Алгоритм работы очистки по схемам тегирования

В версиях <v1.2 по умолчанию используется алгоритм работы очистки по схемам тегирования. Алгоритм работы очистки по истории git будет единственным, начиная с версии v1.2. Для принудительного включения алгоритма необходимо использовать опцию --git-history-based-cleanup

  • по веткам:
    • Каждый новый коммит обновляет образ соответствующий git-ветке (т.о. существует только один Docker-тег для каждой ветки git-репозитория).
    • werf удаляет образ из Docker registry в случае отсутствия в git-репозитории соответствующей ветки. Образ никогда не удаляется, пока существует соответствующая ветка в git-репозитории.
    • Политика применяется к образам, которые тегированы werf при использовании параметра запуска --tag-git-branch.
  • по коммитам:
    • werf удаляет образ из Docker registry в случае отсутствия в git-репозитории соответствующего коммита.
    • Для остальных образов применяется следующая политика:
      • git-commit-strategy-expiry-days.

        Оставлять образы в Docker registry не старше указанного количества дней с момента их публикации. Для повторно опубликованного в Docker registry образа указанное количество дней считается с момента новой публикации.

        По умолчанию: -1, т.е. лимит отключен.

        Значение может быть установлено с помощью опции запуска werf --git-commit-strategy-expiry-days, либо переменной окружения $WERF_GIT_COMMIT_STRATEGY_EXPIRY_DAYS.

      • git-commit-strategy-limit.

        Оставлять в Docker registry не более чем указанного количества образов.

        По умолчанию: -1, т.е. лимит отключен.

        Значение может быть установлено с помощью опции запуска werf --git-commit-strategy-limit, либо переменной окружения $WERF_GIT_COMMIT_STRATEGY_LIMIT.

    • Политика применяется к образам, которые тегированы werf при использовании параметра запуска --tag-git-commit.
  • по тегам:
    • werf удаляет образ из Docker registry в случае отсутствия в git-репозитории соответствующего тега.
    • Для остальных образов применяется следующая политика:
      • git-tag-strategy-expiry-days.

        Оставлять образы в Docker registry не старше указанного количества дней с момента их публикации. Для опубликованного в Docker registry повторно образа указанное количество дней считается с момента новой публикации.

        По умолчанию: -1, лимит отключен.

        Значение может быть установлено с помощью опции запуска werf --git-tag-strategy-expiry-days, либо переменной окружения $WERF_GIT_TAG_STRATEGY_EXPIRY_DAYS.

      • git-tag-strategy-limit.

        Оставлять в Docker registry не более чем указанного количества образов.

        По умолчанию: -1, лимит отключен.

        Значение может быть установлено с помощью опции запуска werf --git-tag-strategy-limit, либо переменной окружения $WERF_GIT_TAG_STRATEGY_LIMIT.

    • Политика применяется к образам, которые тегированы werf при использовании параметра запуска --tag-git-tag.

Обратите внимание, что политика очистки применяется только к образам собранным werf и тегированным werf при использовании одного из следующих параметров запуска: --tag-git-branch, --tag-git-tag or --tag-git-commit. Остальные образы в Docker registry, даже собранные с помощью werf, остаются неизменными.

Алгоритм работы очистки по истории git

В версиях <v1.2 по умолчанию используется алгоритм работы очистки по схемам тегирования. Алгоритм работы очистки по истории git будет единственным, начиная с версии v1.2. Для принудительного включения алгоритма необходимо использовать опцию --git-history-based-cleanup

Результатом сборки является конечный образ, который может быть связан с произвольным количеством Docker-тегов. Конечный образ связан с внутренним идентификатором werf, сигнатурой стадий образа.

В основу алгоритма очистки ложится тот факт, что в хранилище стадий сохраняется информация о коммитах, на которых выполнялась публикация тегов (добавился, изменился или нет образ в Docker registry — не имеет значения), связанных с определённой сигнатурой стадий образа: связка коммит и сигнатура стадий образа для конкретного image из werf.yaml.

В результате сборки и публикации очередного коммита, конечный образ может не измениться, тем не менее в хранилище стадий добавится запись с информацией о том, что публикация сигнатуры стадий образа была вызвана на определённом коммите.

Таким образом, обеспечивается связь сигнатуры стадий образа (произвольного количества связанных Docker-тегов) с историей git и появляется возможность организации эффективной очистки неактуальных образов на основе состояния git и выбранных политик. Алгоритм сканирует историю git, отбирает значимые образы и удаляет образы, которые не попали ни под одну политику, при этом теги используемые в Kubernetes игнорируются.

Рассмотрим основные шаги алгоритма очистки:

Пользовательские политики

Используя политики очистки, keepPolicies, пользователь определяет образы, которые не должны удаляться при очистке. При отсутствии конфигурации в werf.yaml будет использован набор политик по умолчанию.

Стоит отметить, что алгоритм сканирует локальное состояние git репозитория и актуальность git-веток и git-тегов крайне важна. Для синхронизации состояния git можно воспользоваться опцией --git-history-synchronization, которая по умолчанию включена при запуске в CI системах.

Используемые при очистке данные хранилища стадий

Для оптимизации и решения специфичных кейсов, werf при работе сохраняет дополнительные данные в хранилище стадий. Среди таких данных мета-образы, хранящие связку сигнатуры стадий образа и коммита, на котором выполнялась публикация, а также имена образов, которые когда-либо собирались.

Информация о коммитах является единственным источником правды при работе алгоритма, поэтому теги без подобной информации обрабатываются отдельно. Теги, опубликованные версией <v1.1.20, игнорируются (с версии v1.2 удаляются; можно форсировать поведение, используя опцию --git-history-based-cleanup-v1.2).

При организации автоматической очистки команда werf cleanup выполняется либо по расписанию, либо вручную по случаю. Чтобы избежать удаления рабочего кеша при добавлении/удалении образов в werf.yaml в соседних git-ветках, при сборке в хранилище стадий добавляется имя собираемого образа. Используя набор команд werf managed-images ls|add|rm, пользователь может редактировать, так называемый набор managed images.

Игнорирование используемых в кластере Kubernetes образов

Пока в кластере Kubernetes существует объект использующий образ, он никогда не удалится из Docker registry. Другими словами, если что-то было запущено в вашем кластере Kubernetes, то используемые образы ни при каких условиях не будут удалены при очистке.

При запуске очистки werf сканирует следующие типы объектов в кластере Kubernetes: pod, deployment, replicaset, statefulset, daemonset, job, cronjob, replicationcontroller.

Описанное поведение, — проверка объектов в кластере при очистке, может быть отключено параметром --without-kube.

Подключение к кластеру Kubernetes

werf получает информацию о кластерах Kubernetes и способах подключения к ним из файла конфигурации kubectl — ~/.kube/config. Для сбора информации об используемых объектами образах, werf подключается ко всем кластерам Kubernetes, описанным во всех контекстах конфигурации kubectl.

Очистка хранилища стадий

Выполнение очистки хранилища стадий с помощью команды werf stages cleanup необходимо, чтобы синхронизировать его состояние с состоянием Docker registry.

Выполняя эту операцию, werf удаляет стадии, которые не связаны ни с одним образом в Docker registry.

Если первый этап очистки по политикам, выполнение команды werf images cleanup, был пропущен, то выполнение команды werf stages cleanup не даст никакого эффекта

Ручная очистка

Ручная очистка подразумевает полное удаление образов из хранилища стадий или Docker registry (в зависимости от команды). Ручная очистка не учитывает, используется образ в кластере Kubernetes или нет.

Ручная очистка не подразумевает использования для запуска по расписанию. Она предназначена преимущественно для ручного удаления всех образов проекта.

Выполнение ручной очистки возможно следующими способами:

Оба способа ручной очистки объединены в команде werf purge, при которой сначала выполняется удаление образов проекта из Docker registry (werf images purge), а затем, удаление образов из хранилища стадий werf stages purge).

Очистка хоста

Для очистки хоста, на котором используется werf, предназначены следующие команды:

  • werf host cleanup. Очищает старые, неиспользуемые и неактуальные данные, включая кэш стадий во всех проектах на хосте.
  • werf host purge. Удаляет образы, стадии, кэш и другие данные (служебные папки, временные файлы), относящиеся к любому проекту werf на хосте. Другими словами, удаляет все следы werf для всех проектов. Эта команда обеспечивает максимальную степень очистки. Используйте её, например, если не планируете больше использовать werf на данном хосте.