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

Такая удобная возможность теперь встроена и в нашу GitOps-утилиту werf, что должно упростить весь процесс эксплуатации инфраструктуры для собираемых и выкатываемых в Kubernetes приложений.

Встроенный Helm


Пожалуй, основной успех Helm — «пакетного менеджера для Kubernetes» — связан не столько с его функциональностью, сколько с официальным репозиторием чартов и поддержкой репозиториев в целом. Рецепты и настройки чартов сопровождаются огромным сообществом. Специалисты поддерживают актуальные решения, которые требуются конечным пользователям. Каждый чарт официального репозитория стандартизирован и отлично документирован.

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

Мы уже долгое время активно применяем Helm внутри werf для выкатывания инфраструктуры приложения и теперь пошли дальше. Начиная с версии v1.0.4-alpha.10, в werf добавлены команды для работы с зависимостями и чарт-репозиториями, чтобы полностью отказаться от Helm-клиента.

Основные команды для этого:

  • werf helm repo

    add         Add a chart repository
    fetch       Download a chart from a repository and (optionally) unpack it in local directory
    init        Init default chart repositories configuration
    list        List chart repositories
    remove      Remove a chart repository
    search      Search for a keyword in charts
    update      Update information of available charts locally from chart repositories
  • werf helm dependency

    build       Rebuild the charts/ directory based on the requirements.lock file
    list        List the dependencies
    update      Update charts/ based on the contents of requirements.yaml

Плюс, в команде werf helm deploy-chart добавилась поддержка chart reference.

И вот как выглядит в действии вся эта магия — точнее, здесь мы показываем сравнение выката одного и того же чарта в werf (слева) и в Helm (справа):

image

Больше практики


Возвращаясь к удобству использования готовых решений для выката целых приложений — банальный пример с WordPress. Выкат его Helm-чарта в Kubernetes-кластер с помощью werf может выглядеть буквально так:

$ cat << EOF > values.yaml
wordpressBlogName: flant
wordpressUsername: admin       
wordpressPassword: password
mariadb:                                                          
  mariadbRootPassword: password
EOF
$ werf helm deploy-chart --values values.yaml stable/wordpress my-web-app

> Демонстрация в asciicinema.

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

К примеру, для веб-приложения требуются очередь, кэш и хранилище данных. Как мы развернём эти компоненты через werf?

Для начала — ускорим поиск всего необходимого, воспользовавшись CLI:

$ werf helm repo search queue 
NAME                  CHART VERSION    APP VERSION    DESCRIPTION                                                 
stable/rabbitmq       6.4.1            3.7.17         Open source message broker software that implements the A...
stable/rabbitmq-ha    1.31.0           3.7.15         Highly available RabbitMQ cluster, the open source messag...

По аналогии найдем остальные компоненты по всем зарегистрированным репозиториям чартов (список используемых репозиториев можно увидеть, выполнив команду werf helm repo list).

После того, как всё найдено, остаётся только добавить их к чарту. Это можно сделать несколькими способами: добавить чарты компонентов в директорию charts или создать файл requirements.yaml и описать зависимости, а дальше взаимодействовать с ними с помощью специальных команд werf helm dependency build|list|update.

Иллюстрация второго пути:

$ cat << EOF > .helm/requirements.yaml
dependencies:
- name: mysql
  version: 0.3.4
  repository: "@stable"
- name: redis
  version: 1.1.11
  repository: "@stable"
- name: rabbitmq
  version: 0.6.16
  repository: "@stable"
EOF
$ werf helm dependency build
$ werf deploy --env test

> Демонстрация в asciicinema.

В процессе выката werf создаст все зависимости и будет отслеживать их вместе с остальными ресурсами — никакие дополнительные действия не требуются.

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

Документация по командам работы с репозиториями и зависимостями в werf представлена здесь. Также вам может быть интересно прочитать в документации подробнее про выкат в werf и основные отличия от Helm.

Заключение


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

Как пример, вот уже долгое время (второй год!) мы работаем над тем, чтобы наше предложение по отслеживанию ресурсов в Helm приняли как альтернативный режим в основной кодовой базе проекта (upstream). Сообществом идея была принята и поддерживалась, т.к. многим нужна такая возможность. Однако подвижки в этом направлении начались в Helm 3 и только сейчас…

До сих пор реализация этой идеи в Helm была фактически заблокирована разработчиками. Однако за это время мы развили соответствующие функции по слежению за ресурсами в отдельной Open Source-библиотеке ­— kubedog — и уже используем её в werf. А судя по активности на GitHub, библиотека нашла интерес и у других пользователей Kubernetes/Helm, что очень радует.

Поддержать нашу идею (и реализацию) можно, поставив звезду проекту kubedog на GitHub и/или thumbs up в оригинальном issue в Helm. Спасибо!

P.S.


Читайте также в нашем блоге:

Комментарии (3)


  1. gecube
    24.09.2019 11:22
    +1

    Как относитесь к Flux и Argo-CD
    Это больше похоже на настоящий GitOps, чем модель с werf. Очень интересно увидеть сравнение плюсов разных методик.


    сколько с официальным репозиторием чартов и поддержкой репозиториев в целом.

    Бешено плюсую.


    1. distol
      24.09.2019 14:47
      +4

      Спасибо за вопрос. Он возникает уже не первый раз, значит требует подробного ответа.


      Никак не относимся. Мы не пробовали ни Argo-CD ни Flux – хотя они и решают в целом ту же область задач, но они это делают по-другому, используя чуть другие подходы.


      • По Flux лучше всего цитировать их собственную доку:


        What Flux does

        Flux is most useful when used as a deployment tool at the end of a Continuous Delivery pipeline. Flux will make sure that your new container images and config changes are propagated to the cluster.

      • По ArgoCD – я могу ошибаться, но это в первую очередь конструктор пайплайнов.


      • Werf же старается не решать вопросы CI, предполагая, что есть некоторая внешняя CI-система (Gitlab CI, Jenkins, etc), в которой описаны пайплайны, и первичная задача в werf "синхронизировать" состояние Git c состоянием Kubernetes, а именно: собрать и пушнуть образы, применить манифесты для Kubernetes. Причем сделать это удобно и гарантировано.



      Почему так? Ну во-первых по историческим причинам. А во-вторых – у меня (как у "владельца продукта") есть следующий взгляд:


      1. Если вы используете Gitlab CI – у вас уже есть "Pipeline as a Code". Github запустил Github Actions, и когда станут доступны self-hosted runner'ы (они анонсированы, будут бесплатно) – получается, что в Github тоже появляется удобно сделанный "Pipeline as a Code". Что еще нужно кроме Gitlab и Github? Ну еще есть Bitbucket и пока что там все сильно хуже, но они подтянутся (или умрут) и этот вопрос тоже будет решен.
      2. Для по-настоящему эффективной работы функционал CI должен быть плотно проинтегрирован с SCM и с управлением задачами: должна быть двух сторонняя связь. В идеале – в задаче мы должны видеть конечный результат (выкаты связанных MR/PR, проходят ли тесты по ним и пр.). То есть это не простое автозакрытие задачи при принятии, а сквозная видимость в обе стороны (Issue <-> MR <-> Pipeline). Это означает, что CI фактически должен быть частью SCM/трекера. И именно так происходит в Gitlab и Github. То есть большая часть пользователей будет с удовольствием использовать или Gitlab или Github, которые будут решать все три задачи под ключ и надо ориентироваться именно на это. Плюс я думаю Atlassian подтянется и доделает свой стек, и там тоже будет 3-in-1.
      3. Мир сложный, и сколько людей – столько мнений. Мне очень нравится, в этом смысле, философия Unix, и, хотя werf это и интеграционная утилита (мы используем и helm и docker), мы все таки решаем одну основную задачу: "синхронизация Git c Kubernetes". Соответственно, если по каким-то причинам вам удобней Jenkins (у которого, кстати, Pipeline'ы тоже можно в SCM хранить, пусть и менее элегантно), или любую другую систему – да пожалуйста, werf это идеальный вариант для вас. Это просто консольная тула, которая синкает Git-комит с Kubernetes'ом. При чем оптимизированная для работы под управлением CI.

      Таким образом, да – werf, сам по себе, не реализовывает в полной мере GitOps. Но в сочетании с любой "Pipeline as a Code" тулой, связка в полной мере решает этот вопрос. И будучи простой консольной тулой werf дает гораздо большую гибкость. Мы на сайте написали: A missing part of a CI/CD system.


      Сейчас мы находимся на финишной прямой к выпуску 1.0 stable. Сразу после этого у нас есть Milestone, который мы называем "поддержка TOP10 CI-систем". В рамках этого Milestone мы хотим написать практические руководства о том, как правильно использовать werf под наиболее популярными CI системами (плюс сделать удобную поддержку, так же как это сейчас сделано для Gitlab). Мы посмотрим, возможно одной из этих систем будет Argo CD.


      1. gecube
        24.09.2019 15:35

        Я сейчас буду совершенно неоригинален, но скажу крамольную вещь — Gitlab-CI и называется Gitlab-CI ИМЕННО потому что он хорошо справляется с задачей интеграции. Что такое интеграция кода? Это как раз постоянный "слив" мастер, девелоп и feature веток и прогон по ним интеграционных тестов. Эта задача не является приоритетной и может быть в любой момент времени прервана (если ресурсы заняты) и переназначена на другое время. Атомарностью и стабильностью тут не пахнет. В частности, у нас регулярно поджигает пуканы, когда используешь kubernetes executor gitlab-runner'а и сам раннер в кубе — если куб его перешедьюливает, то раннер теряет уже выполняемые джобы. В общем — стабильностью тут и не пахнет. Но она как бы и не нужна особо.
        Также тезис, что Gitlab CI — это все-таки инструмент для CI подтверждается набором его возможностей и отсутствием определенного ряда фич, которые характерны именно для CD-систем.


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


        Еще добавлю. Пайплайн — это пайплайн. Даже если вы его опишете как код — он не перестанет быть последовательностью команд. Это примерно как рассказывать, что ансибл декларативен. Да ни разу он не декларативен — это по сути получается ТО ЖЕ процедурное программирование, только на мета-языке, основанном на YAML формате. В этом отношении гитлаб тоже очень слаб, т.к. оформляя в нем пайплайн вы пишете на баше. В ямле. Жесть. Со всеми недостатками обоих, назовем так, языков. Сильной стороной гитлаба является возможность использовать кастомные докер-образа для того, чтобы в них выполнять некую функциональность. Я считаю, что это действительно крутая штука. Но по сути тот же подход проповедует concourse-ci. И никакого ноу-хау здесь у гитлаба нет.


        Касательно вашего мнения по Bitbucket/Gitlab/Github — понял, спасибо, но оно достаточно субъективно (впрочем, как и моя точка зрения). Тот же энтерпрайз плотно сидит на Atlassian стеке вне зависимости от того плохо это или хорошо. Вообще — что лучше на текущий момент времени — вообще тема отдельного разговора, вне контекста werf.


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