В данной главе приведена основная информация для комфортной и уверенной работы с werf:

  • Принципы работы с исходным кодом и гитерминизм, что обеспечивают надежность и гарантию воспроизводимости, а также унифицируют все процессы.
  • Как в werf тегируются образы и надо ли беспокоиться о тегах, чтобы организовать сборку и деплой (нет, не надо).
  • Как выглядит релиз и как производится его отладка.
  • Как освободить место в хранилище образов, которое рано или поздно начнет заканчиваться.

Работа с исходным кодом и гитерминизм

Зачастую часть настроек, влияющих на конфигурацию выкаченного приложения, формируется на основании «внешних» данных: окружения, в котором выполняется сборка и выкат, предустановленных переменных окружения и сгенерированных файлов, использования внешних ресурсов и т.д. Это напрямую влияет на невозможность гарантировать воспроизводимость состояния приложения.

А зачем нам воспроизводимость?

Если в любой момент можно быстро воспроизвести состояние приложения, то: проще заниматься отладкой, проще развернуть копию проекта (как для разработки, так и для организации нового стенда) и мы можем увереннее опираться на результаты тестирования на том или ином стенде (т.к. у нас меньше скрытых параметров, влияющих на состояние).

Воспроизводимость фундаментально необходима для реализации подхода Infrastructure as Code и immutable infrastructure.

Стандартный режим

Чтобы гарантировать воспроизводимость, werf следует принципу гитерминизма (giterminism), т.е. определяет (детерминирует) работу с проектом с помощью файлов из текущего Git-состояния (HEAD-коммита). По умолчанию werf не позволяет использовать некоммитнутые файлы в конфигурации и сборочном контексте собираемых образов, а также исключает функционал, потенциально имеющий внешние зависимости.

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

Изменение файлов проекта при отладке и разработке может быть неудобным из-за необходимости создавать промежуточные коммиты. В таких случаях рекомендуется работать в режиме разработчика.

Более подробную документацию по гитерминизму см. здесь.

Режим dev

Режим разработчика позволяет ослабить ограничения гитерминизма и работать с некоммитнутыми изменениями. Он активируется опцией --dev или переменной окружения WERF_DEV.

В режиме разработчика werf использует все tracked и untracked-изменения с учётом .gitignore-правил, а также дополнительных пользовательских исключений, которые задаются опцией --dev-ignore=<glob> или переменной окружения WERF_DEV_IGNORE_<ANY>.

Режим follow

Режим follow позволяет перезапускать команду при изменении состояния Git:

  • команда перезапускается при создании нового коммита;
  • совместно с dev-режимом (--dev) при любом изменении.

Режим активируется опцией --follow или переменной окружения WERF_FOLLOW.

Выбор режима для локальной разработки

Сводная таблица по режимам работы werf:

Режим без флагов --dev --follow --dev --follow
использование только файлов из коммита + - + -
использование некоммитнутых изменений - + - +
автоматический перезапуск деплоя - - + +

Сборка и тегирование образов

Сборка

В классическом подходе к сборке образов при помощи родных инструментов Docker требовалось использовать команды docker build и docker tag, а затем опубликовать вновь собранный образ в registry (через docker push).

В werf это делается в рамках одной команды — werf build. Подробнее почитать про отличия между werf и Docker можно в этом сравнении.

Кроме того, в werf «из коробки» работают (включены по умолчанию):

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

Тегирование образов

Если строить процесс деплоя без werf, вручную, то приходится задавать строгие правила тегирования образов и соблюдать их (поверьте, это очень непросто). Однако в случае werf в чартах используется конструкция вида image: {{ .Values.werf.image.app }}:

      - name: app
        image: {{ .Values.werf.image.app }}
        command: ["/app/start.sh"]

То есть нет необходимости заботиться о правилах тегирования: если что-то изменилось в коде — werf самостоятельно инициирует пересборку необходимого образа, загрузит полученный образ со служебными тегами в registry и подставит этот образ в шаблоны. Для того, чтобы всё это корректно работало, werf хранит в registry метаданные и отслеживает содержимое файлов в Git-репозитории.

Как это всё получается?

В werf реализовано тегирование, которое называется content-based (т.е. основанное на содержимом): образы меняются и выкатываются автоматически, если меняется состояние контента в Git. Что важно, образы не меняются от коммита к коммиту и не происходит лишних перевыкатов, если состояние контента в GIt не поменялось.

При организации деплоя без использования werf зачастую приходится формализовать принципы, по которым именуются образы в registry. В нашем случае нет необходимости думать об этом: werf берёт организацию тегирования на себя.

Если кратко, werf рассчитывает контрольную сумму файлов, добавляемых в образы, и на основании этого генерирует теги для образа. Однако werf делает это таким образом, чтобы несколько сборок, собирающихся параллельно (в том числе и на разных серверах), не конфликтовали. Для этого используется подход, основанный на идеях MVCC и optimistic locking.

Подробнее о том, как хранятся данные в registry, можно почитать в документации werf. Там написано, как устроен процесс сборки, как учитываются зависимости между стадиями сборки, а также — как устроено именование полученных образов.

Релизы и Helm

werf использует Helm для деплоя приложения. Helm-чарт — это набор файлов, который описывает связанный набор объектов Kubernetes. Когда чарт выкатывается в кластер в определённое окружение — создаётся релиз.

Где почитать подробнее

В документации werf есть подробное описание того, как устроена работа с релизами, их хранение и именование.

werf всецело использует политику гитерминизма при работе с релизами. Для Helm-релизов применяется механика 3-way merge: изменения, вручную внесённые в кластер и противоречащие тому, что описано в Git, будут приведены к состоянию в Git. Обратите внимание, что внесённые вручную изменения, не противоречащие Git, остаются не под контролем Helm и werf.

werf создает релизы самостоятельно, но если вы хотите вручную работать с релизами, доступны команды werf helm <...>.

Подробнее почитать про werf и Helm в этом сравнении.

Посмотреть, что установлено

Определенное состояние выкаченного приложения называется релизом. Релизы показывают, что конкретно в кластере установлено при помощи werf и Helm, в каком окружении и в каком состоянии оно находится.

Чтобы посмотреть список релизов или найти, как называется нужный вам релиз, воспользуйтесь CLI-командой werf helm list -A.

Удалить лишнее

Чтобы удалить релиз приложения из Kubernetes, воспользуйтесь werf dismiss.

Отладка установки

Отладка позволяет посмотреть, что пошло не так в процессе работы werf. Зачастую возникают сложности при выкате релиза из-за ошибок, допущенных при написании чартов. Отладить такие проблемы помогает команда werf render.

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

Обратите внимание, что, как и все другие команды, werf render работает только с коммитнутыми в Git файлами, но поддерживает режим --dev.

Очистка

Со временем в хранилище (локально или в registry) может накопиться множество данных. Есть две группы команд, которые занимаются очисткой, но имеют разное предназначение: werf cleanup и werf purge (подробнее можно прочитать в документации). Первая работает только с данными в registry, а вторая — со всем, что касается werf.

werf cleanup

Для регулярной очистки registry от неактуальных данных есть безопасная команда werf cleanup. Она безопасно удаляет образы, которые более не требуются, с помощью продвинутого алгоритма, учитывающего Git-историю, содержимое registry и состояние кластера. Команда используется с ключом --repo <reponame> для очистки данных определенного project.

Для очистки хоста от неактуальных данных, связанных с werf, используется werf host cleanup.

werf purge

Если есть необходимость освободить место на диске, удалив все образы и другие данные, следует использовать werf host purge.

Для полного удаления на хосте всего, что связано с werf, следует использовать werf purge. Помните, что это НЕБЕЗОПАСНАЯ КОМАНДА, которая удаляет все образы!