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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Информация о коммитах является единственным источником правды при работе алгоритма и werf удаляет теги без подобной информации.

При организации автоматической очистки команда 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 images purge. Удаляет все образы текущего проекта в Docker registry.
  • Команда werf stages purge. Удаляет все стадии текущего проекта в хранилище стадий.

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

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

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

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