company_banner

Что же такое GitOps?

Автор оригинала: Alexis Richardson, Weaveworks
  • Перевод
Прим. перев.: После недавней публикации материала о методах pull и push в GitOps мы увидели интерес к этой модели в целом, однако русскоязычных публикаций на эту тему оказалось совсем мало (на хабре их попросту нет). Посему рады предложить вашему вниманию перевод другой статьи — пусть и уже почти годичной давности! — от компании Weaveworks, глава которой придумал термин «GitOps». В тексте поясняется суть подхода и ключевые отличия от уже существующих.



Год назад мы опубликовали введение в GitOps. Тогда мы рассказали, как команда Weaveworks запустила SaaS, целиком основанную на Kubernetes, и разработала набор предписывающих лучших практик для развертывания, управления и мониторинга в среде cloud native.

Статья оказалась популярной. Другие люди заговорили о GitOps, стали публиковать новые инструменты для git push, разработки, секретов, функций, непрерывной интеграции и т.п. На нашем сайте появилось большое количество публикаций и вариантов использования GitOps. Но у некоторых людей все же остались вопросы. Чем модель отличается от традиционной infrastructure as code и непрерывной поставки (continuous delivery)? Обязательно ли использовать Kubernetes?

Вскоре мы поняли, что необходимо новое описание, предлагающее:

  1. Большое количество примеров и историй;
  2. Конкретное определение GitOps;
  3. Сравнение с традиционной continuous delivery.

В этой статье мы попытались охватить все эти темы. В ней вы найдете обновленное введение в GitOps и взгляд на него со стороны разработчиков и CI/CD. Мы преимущественно ориентируемся на Kubernetes, хотя модель вполне можно обобщить.

Знакомьтесь: GitOps


Представьте себе Алису. Она управляет компанией Family Insurance, предлагающей полисы по страхованию здоровья, автомобилей, недвижимости и туристическую страховку людям, которые слишком заняты, чтобы разбираться в нюансах контрактов самостоятельно. Ее бизнес начинался как сторонний проект, когда Алиса работала в банке как data scientist. Однажды она поняла, что может использовать передовые компьютерные алгоритмы для более эффективного анализа данных и формирования страховых пакетов. Инвесторы профинансировали проект, и теперь ее компания приносит более 20 млн долларов в год и стремительно растет. В настоящий момент в ней на различных должностях работают 180 человек. В их числе технологическая команда, которая занимается разработкой, обслуживанием сайта, базы данных и анализом клиентской базы. Команду из 60 человек возглавляет Боб — технический директор компании.

Команда Боба развертывает production-системы в облаке. Их основные приложения работают на GKE, пользуясь преимуществами Kubernetes в Google Cloud. Кроме того, они используют в работе различные инструменты для работы с данными и аналитики.

Family Insurance не собиралась использовать контейнеры, но заразилась энтузиазмом вокруг Docker. Вскоре специалисты компании обнаружили, что GKE позволяет развертывать кластеры для тестирования новых функций легко и непринужденно. Были добавлены Jenkins для CI и Quay для организации реестра контейнеров, написаны скрипты для Jenkins, которые push'или новые контейнеры и конфигурации в GKE.

Прошло некоторое время. Алиса и Боб разочаровались в производительности выбранного подхода и его влиянии на бизнес. Внедрение контейнеров не повысило производительность настолько, насколько надеялась команда. Иногда deployment'ы ломались, и было неясно, виноваты ли в этом изменения кода. Также оказалось тяжело отслеживать изменения конфигов. Часто приходилось создавать новый кластер и перемещать в него приложения, поскольку так было проще всего ликвидировать тот бардак, в который превратилась система. Алиса боялась, что ситуация ухудшится по мере развития приложения (кроме того, назревал новый проект на основе машинного обучения). Боб автоматизировал большую часть работы и не понимал, почему пайплайн по-прежнему неустойчив, плохо масштабируется и периодически требует ручного вмешательства?

Затем они узнали о GitOps. Это решение оказалось именно тем, что им было нужно для уверенного движения вперед.

Алиса и Боб уже не один год слышали о рабочих процессах на основе Git, DevOps и infrastructure as code. Уникальность GitOps в том, что он привносит ряд лучших практик — категоричных и нормативных — по реализации этих идей в контексте Kubernetes. Эта тема неоднократно поднималась, в том числе и в блоге Weaveworks.

Family Insurance решает внедрить GitOps. Теперь у компании есть автоматизированная модель эксплуатации, совместимая с Kubernetes и сочетающая скорость со стабильностью, поскольку они:

  • обнаружили, что у команды вдвое выросла производительность и никто при этом не сходит с ума;
  • перестали обслуживать скрипты. Вместо этого теперь они могут концентрироваться на новых функциях и совершенствовать инженерные методы — например, внедрить канареечные выкаты и улучшить тестирование;
  • усовершенствовали процесс развертывания — теперь он редко ломается;
  • получили возможность восстанавливать deployment'ы после частичных сбоев без ручного вмешательства;
  • приобрели большую уверенность в системах поставки. Алиса и Боб обнаружили, что можно разделить команду на группы, занимающиеся микросервисами и работающие параллельно;
  • могут вносить по 30-50 изменений в проект каждый день усилиями каждой группы и пробовать новые техники;
  • легко привлекают к проекту новых разработчиков, которые имеют возможность накатывать обновления на production с помощью pull request'ов уже через несколько часов;
  • легко проходят аудит в рамках SOC2 (на соответствие поставщиков услуг требованиям по безопасному управлению данных; подробнее читайте, например, здесь — прим. перев.).

Что произошло?


GitOps — это две вещи:

  1. Модель эксплуатации для Kubernetes и cloud native. Она предоставляет набор лучших практик для развертывания, управления и мониторинга собранных в контейнеры кластеров и приложений. Элегантное определение в виде одного слайда от Luis Faceira:

  2. Путь к созданию ориентированного на разработчиков окружения для управления приложениями. Мы применяем рабочий процесс Git как к эксплуатации, так и к разработке. Обратите внимание, что речь идет не просто о Git push, а об организации всего набора инструментов CI/CD и UI/UX.

Пара слов о Git


Если вы не знакомы с системами контроля версий и основанном на Git рабочим процессом, мы настоятельно рекомендуем изучить их. Поначалу работа с ветвями и pull request'ами может показаться черной магией, но плюсы стоят затраченных усилий. Вот хорошая статья для начала.

Как работает Kubernetes


В нашей истории Алиса и Боб обратились к GitOps, некоторое время проработав с Kubernetes. Действительно, GitOps тесно связан с Kubernetes — это модель эксплуатации для инфраструктуры и приложений, основанных на Kubernetes.

Что Kubernetes дает пользователям?


Вот некоторые основные возможности:

  1. В модели Kubernetes все можно описывать в декларативной форме.
  2. API-сервер Kubernetes принимает такую декларацию как вводные данные, а затем постоянно пытается привести кластер в состояние, описанное в декларации.
  3. Декларации достаточны для описания и управления большим разнообразием рабочих нагрузок — «приложений».
  4. В результате, внесение изменений в приложение и кластер происходит из-за:
    • изменений в образах контейнеров;
    • изменений в декларативной спецификации;
    • ошибок в среде — например, падений контейнеров.

Прекрасные способности Kubernetes по конвергенции


Когда администратор вносит изменения в конфигурацию, оркестратор Kubernetes будет применять их к кластеру до тех пор, пока его состояние не приблизится к новой конфигурации. Эта модель работает для любого ресурса Kubernetes и расширяется с помощью Custom Resource Definitions (CRDs). Поэтому deployment'ы Kubernetes обладают следующими чудесными свойствами:

  • Автоматизация: обновления Kubernetes предоставляют механизм для автоматизации процесса применения изменений корректно и своевременно.
  • Конвергенция: Kubernetes будет продолжать попытки обновлений до достижения успеха.
  • Идемпотентность: повторные применения конвергенции приводят к тому же результату.
  • Детерминизм: при достаточности ресурсов состояние обновленного кластера зависит только от желаемого состояния.

Как работает GitOps


Мы достаточно узнали о Kubernetes, чтобы объяснить принципы работы GitOps.

Давайте вернемся к командам Family Insurance, связанным с микросервисами. Чем им обычно приходится заниматься? Посмотрите на перечень ниже (если какие-то пункты в нем покажутся странными или незнакомыми — пожалуйста, повремените с критикой и оставайтесь с нами). Это всего лишь примеры рабочих процессов на основе Jenkins. Существует и множество других процессов при работе с другими инструментами.

Главное — мы видим, что каждое обновление заканчивается внесением изменений в конфигурационные файлы и репозитории Git. Эти изменения в Git приводят к тому, что «оператор GitOps» обновляет кластер:

1. Рабочий процесс: «Сборка Jenkins — ветка master».
Список задач:

  • Jenkins push'ит тегированные образы в Quay;
  • Jenkins push'ит конфиг и Helm-чарты в бакет master-хранилища;
  • Облачная функция копирует конфиг и чарты из бакета master-хранилища в Git-репозиторий master;
  • Оператор GitOps обновляет кластер.

2. Сборка Jenkins — ветка release или hotfix:

  • Jenkins push'ит нетегированные образы в Quay;
  • Jenkins push'ит конфиг и Helm-чарты в бакет staging-хранилища;
  • Облачная функция копирует конфиг и чарты из бакета staging-хранилища в Git-репозиторий staging;
  • Оператор GitOps обновляет кластер.

3. Сборка Jenkins — ветка develop или feature:

  • Jenkins push'ит нетегированные образы в Quay;
  • Jenkins push'ит конфиг и Helm-чарты в бакет develop-хранилища;
  • Облачная функция копирует конфиг и чарты из бакета develop-хранилища в Git-репозиторий develop;
  • Оператор GitOps обновляет кластер.

4. Добавление нового клиента:

  • Менеджер или администратор (LCM/ops) вызывает Gradle для первоначального развертывания и настройки сетевых балансировщиков нагрузки (NLB);
  • LCM/ops коммитит новый конфиг для подготовки deployment'а к обновлениям;
  • Оператор GitOps обновляет кластер.

Краткое описание GitOps


  1. Опишите желаемое состояние всей системы, используя декларативные спецификации для каждого окружения (в нашей истории команда Боба определяет всю конфигурацию системы в Git).

    • Git-репозиторий является единственным источником истины в отношении желаемого состояния всей системы.
    • Все изменения в желаемое состояние осуществляются путем коммитов в Git.
    • Все желаемые параметры кластера также наблюдаемы в самом кластере. Таким образом мы можем определить, совпадают (конвергируют, converge) или отличаются (дивергируют, diverge) желаемое и наблюдаемое состояния.
  2. Если желаемое и наблюдаемое состояния отличаются, то:

    • Существует механизм конвергенции, который рано или поздно автоматически синхронизирует целевое и наблюдаемое состояния. Внутри кластера этим занимается Kubernetes.
    • Процесс запускается незамедлительно с оповещением «change committed».
    • Через некоторый настраиваемый промежуток времени может быть послано оповещение «diff», если состояния отличаются.
  3. Таким образом, все коммиты в Git вызывают проверяемые и идемпотентные обновления в кластере.

    • Откат — это конвергенция к ранее желаемому состоянию.
  4. Конвергенция окончательна. О ее наступлении свидетельствуют:

    • Отсутствие оповещений «diff» в течение определенного промежутка времени.
    • Оповещение «converged» (например, webhook, событие Git writeback).

Что такое дивергенция?


Повторим еще раз: все желаемые свойства кластера должны быть наблюдаемы в самом кластере.

Несколько примеров дивергенции:

  • Изменение в файле конфигурации из-за слияния веток в Git.
  • Изменение в файле конфигурации из-за коммита в Git, сделанного GUI-клиентом.
  • Множественные изменения в желаемом состоянии из-за PR в Git с последующей сборкой образа контейнера и изменениями конфига.
  • Изменение состояния кластера из-за ошибки, конфликта ресурсов, приводящего к «плохому поведению», или просто случайного отклонения от оригинального состояния.

Что представляет собой механизм конвергенции?


Несколько примеров:

  • Для контейнеров и кластеров механизм конвергенции предоставляет Kubernetes.
  • Тот же механизм можно использовать для управления приложениями и конструкциями на основе Kubernetes (например, Istio и Kubeflow).
  • Механизм для управления рабочим взаимодействием между Kubernetes, репозиториями образов и Git'ом предоставляет GitOps-оператор Weave Flux, являющийся частью Weave Cloud.
  • Для базовых машин механизм конвергенции должен быть декларативным и автономным. По своему опыту можем сказать, что Terraform ближе всего к этому определению, однако все же требует контроля со стороны человека. В этом смысле GitOps расширяет традиции Infrastructure as Code.

GitOps объединяет Git с прекрасным механизмом конвергенции Kubernetes, предлагая модель для эксплуатации.

GitOps позволяет нам заявить: автоматизации и контролю поддаются только те системы, которые можно описывать и наблюдать.

GitOps предназначен для всего cloud native-стека (например, Terraform и т.п.)


GitOps — это не только Kubernetes. Мы хотим, чтобы вся система управлялась декларативно и использовала конвергенцию. Под всей системой мы подразумеваем совокупность сред, работающих с Kubernetes — например, «dev cluster 1», «production» и т. п. В каждую среду входят машины, кластеры, приложения, а также интерфейсы для внешних сервисов, обеспечивающих данные, мониторинг и т. п.

Заметьте, насколько в данном случае Terraform важен для проблемы bootstrapping'а. Kubernetes должен быть где-то развёрнут, и использование Terraform означает, что мы можем применить те же самые рабочие процессы GitOps для создания управляющего слоя, лежащего в основе Kubernetes и приложений. Это полезная лучшая практика.

Большое внимание уделяется применению концепций GitOps к слоям над Kubernetes. На данный момент имеются решения GitOps-типа для Istio, Helm, Ksonnet, OpenFaaS и Kubeflow, а также например, для Pulumi, что создают слой для разработки приложений под cloud native.

Kubernetes CI/CD: сравнение GitOps с другими подходами


Как говорилось, GitOps — это две вещи:

  1. Модель эксплуатации для Kubernetes и cloud native, описанная выше.
  2. Путь к организации ориентированной на разработчиков среды для управления приложениями.

Для многих GitOps — это прежде всего рабочий процесс на основе Git push'ей. Нам он тоже нравится. Но это не все: давайте теперь посмотрим на CI/CD-пайплайны.

GitOps обеспечивает непрерывное развертывание (CD) под Kubernetes


GitOps предлагает механизм непрерывного развертывания, устраняющий необходимость в отдельных «системах управления развертываниями». Всю работу за вас выполняет Kubernetes.

  • Обновление приложения требует обновления в Git'е. Это транзакционное обновление до желаемого состояния. «Развертывание» затем осуществляется внутри кластера самим Kubernetes на основе обновленного описания.
  • Из-за специфики работы Kubernetes эти обновления конвергентны. Так обеспечивается механизм для непрерывного развертывания, в котором все обновления атомарны.
  • Примечание: Weave Cloud предлагает GitOps-оператор, интегрирующий Git и Kubernetes и позволяющий выполнять CD путем согласования желаемого и текущего состояния кластера.

Без kubectl и скриптов


Следует избегать использования Kubectl для обновления кластера, а в особенности — скриптов для группирования команд kubectl. Вместо этого, с помощью GitOps-пайплайна пользователь может обновить свой кластер Kubernetes через Git.

Преимущества включают в себя:

  1. Правильность. Группу обновлений можно применить, конвергировать и наконец валидировать, что приближает нас к цели атомарного развертывания. Напротив, использование скриптов не дает никаких гарантий конвергенции (подробнее об этом ниже).
  2. Безопасность. Цитируя Kelsey Hightower: «Ограничьте доступ к кластеру Kubernetes инструментам автоматизации и администраторам, в обязанности которых входит его отладка или поддержание работоспособности». См. также мою публикацию о безопасности и соответствии техническим условиям, а также статью о взломе Homebrew путем хищения учетных данных из небрежно составленного Jenkins-скрипта.
  3. Пользовательский опыт. Kubectl обнажает механику объектной модели Kubernetes, которая весьма сложна. В идеале пользователи должны взаимодействовать с системой на более высоком уровне абстракции. Здесь я снова сошлюсь на Kelsey и рекомендую посмотреть такое резюме.

Разница между CI и CD


GitOps улучшает существующие CI/CD-модели.

Современный CI-сервер представляет собой инструмент для оркестрации. В частности, это инструмент для оркестрации CI-пайплайнов. Они включают в себя build, test, merge to trunk и т. д. CI-серверы автоматизируют управление сложными многошаговыми пайплайнами. Распространенный соблазн состоит в том, чтобы создать скрипт для набора обновлений Kubernetes и выполнить его в качестве элемента пайплайна для push'а изменений в кластер. Действительно, так поступают многие специалисты. Однако это неоптимально, и вот почему.

CI должна использоваться для внесения обновлений в trunk, а кластер Kubernetes должен менять себя на основе этих обновлений, чтобы управлять CD «внутренне». Мы называем это pull-моделью для CD, в отличие от CI push-модели. CD является частью runtime-оркестрации.

Почему CI-серверы не должны делать CD через прямые обновления в Kubernetes


Не используйте CI-сервер для оркестрации прямых обновлений в Kubernetes в виде набора CI-заданий. Это анти-паттерн, о котором мы уже рассказывали в своем блоге.

Давайте вернемся к Алисе и Бобу.

С какими проблемами они столкнулись? CI-сервер Боба применяет изменения к кластеру, но если в процессе он упадет, Боб не будет знать, в каком состоянии находится (или должен быть) кластер и как его исправить. То же самое справедливо и в случае успеха.

Давайте предположим, что команда Боба собрала новый образ и затем пропатчила свои deployment'ы, чтобы развернуть образ (все это из CI-пайплайна).

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

  • Развернулось ли обновление?
  • Запускаем ли мы новую сборку? Приведет ли это к ненужным побочным эффектам — с возможностью получить две сборки одного и того же неизменного образа?
  • Стоит ли нам дождаться очередного обновления, прежде чем запустить сборку?
  • Что именно пошло не так? Какие шаги нужно повторить (и какие из них безопасно повторять)?

Организация основанного на Git'е рабочего процесса не гарантирует, что команда Боба не столкнется с этими проблемами. Они по-прежнему могут ошибиться с push'ем коммита, с тегом или каким-либо другим параметром; однако этот подход все же гораздо ближе к явному все-или-ничего.

Подытоживая, вот почему CI-серверы не должны заниматься CD:

  • Скрипты обновления не всегда детерминированы; в них легко наделать ошибок.
  • CI-серверы не конвергируют к декларативной модели кластера.
  • Сложно гарантировать идемпотентность. Пользователи должны разбираться в глубокой семантике системы.
  • Сложнее провести восстановление после частичного сбоя.

Примечание о Helm'e: если вы хотите использовать Helm, мы рекомендуем объединить его с GitOps-оператором, таким как Flux-Helm. Это поможет обеспечить конвергентность. Сам по себе Helm не является ни детерминированым, ни атомарным.

GitOps как лучший способ осуществлять Continuous Delivery для Kubernetes


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

Модель эксплуатации для Kubernetes


Посмотрите на следующую диаграмму. Она представляет Git и хранилище образов контейнеров как общие ресурсы для двух оркестрированных жизненных циклов:

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



Каковы основные выводы?


  1. Разделение проблем: Обратите внимание, что оба пайплайна могут обмениваться данными, только обновляя Git или репозиторий образов. Другими словами, существует сетевой экран между CI и runtime-средой. Мы называем его «брандмауэром неизменяемости» (immutability firewall), поскольку все обновления репозиториев создают новые версии. Для дополнительной информации по данной теме обратитесь к слайдам 72-87 этой презентации.
  2. Можно использовать любой CI- и Git-сервер: GitOps работает с любыми компонентами. Вы можете продолжать использовать свои любимые CI- и Git-серверы, репозитории образов и наборы тестов. Почти все остальные инструменты для Continuous Delivery на рынке требуют собственного CI-/Git-сервера или хранилища образов. Это может стать ограничивающим фактором в развитии cloud native. В случае GitOps вы можете использовать привычные инструменты.
  3. События как инструмент интеграции: Как только данные в Git обновляются, Weave Flux (или оператор Weave Cloud) извещает об этом runtime. Всякий раз, когда Kubernetes принимает набор изменений, Git обновляется. Это обеспечивает простую модель интеграции для организации рабочих процессов для GitOps, как показано ниже.



Заключение


GitOps предоставляет весомые гарантии обновления, необходимые любому современному инструменту CI/CD:

  • автоматизация;
  • конвергенция;
  • идемпотентность;
  • детерминизм.

Это важно, поскольку он предлагает модель эксплуатации для разработчиков в области cloud native.

  • Традиционные инструменты для управления и мониторинга систем связаны с командами эксплуатации, действующими в рамках runbook'а (набора рутинных процедур и операций — прим. перев.), привязанного к конкретному deployment'у.
  • В управлении cloud native-системами инструментарий для наблюдения является лучшим способом оценки результатов развертываний, чтобы команда разработчиков смогла оперативно реагировать на них.

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

P.S. от переводчика


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

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Вы знали про GitOps до появления этих двух переводов на хабре?

  • 22.4%Да, всё знал(а)11
  • 34.6%Лишь поверхностно17
  • 42.8%Нет21
  • +33
  • 11,5k
  • 7
Флант
449,17
Специалисты по DevOps и Kubernetes
Поделиться публикацией

Комментарии 7

    +2
    Хороший концепт и я его применяю с самого начала, как я стал использовать Kubernetes. И на фоне этого я не очень вижу как можно применять helm, а я так хотел.
      0
      Так одно другого не исключает.

      Допустим, у вас приложение, состоящее из двух бэков + базы.
      И у вас Docker и Helm Chart лежат прямо с кодом, который они обсуждивают — у каждого из двух бэков свой набор.
      Вы сделали изменение в брэнче одного из бэков. Он улетел в ориджин. Оттуда хуком пнулся Дженкинс, тот увидел новый брэнч, сгенерировал под него джобу (multibranch) и запустил pipeline. Один из шагов — деплоймент.
      Допустим, Helm не используется. Деплоймент пойдет напрямую через apply deployment.yml в k8s. В таком случае получается, что деплоймент только одного бэка. То есть у вас прилетит бэк1 новый, а бэк2 будет стоять старый. Вместе они работать не рассчитаны, так как находятся на разных версиях.
      А теперь тот же сценарий, но с Helm.
      Вы ставите бэк1 через helm upgrade. Он по зависимостям вытягивает правильную версию базы (да может даже у вас там прибавилось еще других зависимостей даже) и правильную версию парного бэка2.

      Другими словами, Helm дает вам консистентность на уровне всего приложения. И Git это никак не отменяет. Они даже никак не связаны. Вы, конечно, могли изначально в Jenkinfile захардкодить это поведение, но боюсь, это не так элегентно и гибко.
      +2

      Где-то можно скачать HelloWorld-проект, в котором это всё добро внедрили?

        +1

        Такого репозитория я не видел. Пока есть getting started документация от flux: https://github.com/weaveworks/flux/blob/master/site/get-started.md. Но там нет конфигов для развёртывания самого куба.


        А было бы круто прям с нуля сделать git clone, start.sh и уже готовый куб поднялся где-то в AWS, остаётся только коммиты пушить для изменений.

          +2
          Попробуйте JenkinsX, там все так и устроено.
          Rancher тоже делает подобное, правда более упрощенно. В новой версии из коробки будет istio и, возможно, канареечные деплойменты.
            +1

            А любая проблема выглядит как черный ящик, забыли добавить вы)

          0
          «GitOps is the best thing since configuration as code. Git changed how we collaborate, but declarative configuration is the key to dealing with infrastructure at scale, and sets the stage for the next generation of management tools.»

          Kelsey Hightower, Aug 21, 2019.

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое