Чтобы вам было комфортно и вы чувствовали себя уверенно при использовании werf, нужно знать несколько особенностей и возможностей:

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

Все эти вопросы подробнее рассмотрены далее.

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

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

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

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

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

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

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

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

Подробнее про гитерминизм можно прочитать в документации werf.

dev-режим

Режим разработчика активируется опцией --dev или соответствующей переменной окружения WERF_DEV. Поддерживается два режима работы, которые регулируются опцией --dev-mode (по умолчанию simple):

  • simple: для работы с состоянием worktree git-репозитория проекта;
  • strict: для работы с состоянием index, в git-репозитории проекта.

Стоит отметить, что новые файлы (untracked) должны всегда добавляться в index вручную (единоразовая операция, которая выполняется командой git add для каждого вновь добавленного файла).

follow-режим

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

  • команда перезапускается при создании нового коммита;
  • совместно с dev-режимом (--dev) дополнительно отслеживается состояние index git-репозитория, для перезапуска команды достаточно добавить новые изменения в index (git add).

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

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

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

      - name: basicapp
        command: ["python3","manage.py"]
        args: ["runserver", "0.0.0.0:8000"]
        image: {{ .Values.werf.image.basicapp }}

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

Как это всё работает?

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

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

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

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

Helm, релизы, вот это всё

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Место в хранилище

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

Регулярная очистка registry

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

В главе «Работа с инфраструктурой» мы будем настраивать регулярную очистку registry по расписанию, используя возможности CI-системы.

Удалить всё

Если есть необходимость освободить место на диске, удалив все образы и другие данные, можно воспользоваться служебными командами:

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