Новый авиалайнер. Входит стюардесса в пассажирский салон: «Вы находитесь на нашем новом авиалайнере, в носовой части самолёта у нас находится кинозал, в хвостовой — зал игровых автоматов, на нижней палубе — бассейн, на верхней — сауна. А теперь, уважаемые господа, пристегните ремни, и со всей этой хреновиной мы попробуем взлететь».
Привет, меня зовут Олег! В ИТ-индустрии я работаю большую часть своей жизни. Мне очень интересно развитие инженерной мысли в области управления конфигурацией инфраструктуры, и последние шесть лет я занимаюсь тем, что называется DevOps.
Одна из свежих популярных тенденций — это концепция GitOps, которая была представлена в 2017 году на ставшем уже легендарным «Кубконе» Алексисом Ричардсоном — СЕО компании Weaveworks.
Weaveworks — это большая взрослая компания, которая в 2020 году привлекла больше 36 миллионов инвестиций под развитие своего GitOps.
Сейчас я попробую рассказать о тех неочевидных проблемах, которые могут вас ждать при принятии этой концепции. Если коротко, то GitOps не является «Серебряной пулей». Вполне вероятно, что спустя какое-то время вы закончите реорганизацию с ворохом велосипедов и костылей, которыми очень сложно управлять. Мы сами изрядно походили по этим граблям и хотим показать наиболее неприятные проблемы, которые не видны при чтении красивых статей.
Что такое GitOps и зачем он нужен
Stateless и Stateful
Самой перспективной и многообещающей концепцией построения инфраструктуры на сегодняшний день является immutable infrastructure.
Её ключевая идея — в разделении инфраструктуры на две принципиально разные части: Stateless и Statefull. Stateless-часть инфраструктуры иммутабельна и идемпотентна. То есть не накапливает в себе состояние (не сохраняет данных) и не меняет своей работы в зависимости от накопленного состояния. Инстансы этой части инфраструктуры могут содержать какие-то базовые артефакты, скрипты, ассеты. Как правило, мы создаём их из базовых образов в облачных/виртуализированных окружениях, они хрупки и эфемерны: новые версии приложений мы доставляем путём пересоздания инстансов с новых базовых образов.
Персистентные данные хранятся в Stateful-части. Она может быть реализована как по классической схеме с выделенными серверами, так и при помощи каких-то облачных механизмов (например, DBaaS, объектных или блочных хранилищ).
Для того чтобы заставить весь этот зоопарк быть управляемым и корректно работать, нам нужны коллаборация между engineering и ops team (сиречь DevOps), а также полностью автоматизированные пайплайны доставки.
CI-часть
Экстремальное программирование — одна из гибких методологий разработки. Отличается большим количеством петель обратной связи, что позволяет поддерживать синхронизацию с потребностями клиента.
Автоматизация пайплайнов доставки реализуется у нас при помощи CI/CD-систем. Сам термин CI — Continuous Integration — в 1994 году предложил Grady Booch, а в 1997-м Kent Beck и Ron Jeffries ввели его в дисциплину экстремального программирования. В рамках CI мы должны интегрировать наши изменения как можно чаще в основную рабочую ветку нашего проекта. Это требует, во-первых, более гранулярной декомпозиции задач: мелкие изменения более атомарны, их проще отследить, понять и интегрировать. Во-вторых, мы не можем просто взять и смержить свеженаписанный код. Перед слиянием веток нам нужно убедиться, что ничего из того, что работало раньше, не было сломано. Для этого приложение надо хотя бы собрать. А ещё неплохо было бы покрыть код тестами.
И именно вот эту задачу выполняют CI-системы, которые прошли долгий путь развития и где-то посередине этого пути превратились в CI/CD-системы.
CD-часть
Что такое CD? Тот же Martin Fowler различает сразу два CD:
- Continuous Delivery — это когда при помощи практик Continuous Integration и культуры DevOps вы держите основную ветку своего проекта постоянно готовым к деплою на продакшн.
- Continuous Deployment — это Continuous Delivery плюс всё, что попадает в основную ветку, выливается у вас в ваш кластер, в ваш продакшн.
Проблема инфраструктурных «снежинок»
К сожалению, immutable infrastructure имеет ряд проблем. Львиную часть она унаследовала от концепции «инфраструктура как код» — IaC.
Прежде всего это configuration drift. Этот термин родился в недрах puppet labs (авторов всем известной puppet scm) и констатирует тот факт, что не все изменения на целевых системах делаются при помощи систем управления конфигурацией (system configuration management — SCM). Некоторые делаются вручную, в обход.
В процессе таких множественных изменений накапливается configuration drift — разница между описанной в SCM конфигурацией и реальным состоянием дел.
Это приводит к спирали страха автоматизации (Automation fear spiral).
Спираль страха автоматизации
Чем больше сделано ручных изменений, тем больше вероятность, что запуск сценария SCM сломает неучтённые изменения, тем страшнее его запускать, тем больше вероятность новых ручных правок.
В конце концов эта порочная положительная обратная связь приводит к образованию так называемых серверов-«снежинок», которые стали настолько неконсистентными, что уже никто не понимает, что внутри. После ручных правок узел становится уникальным, как каждая отдельная снежинка в снегопад.
В рамках immutable infrastructure этот дрифт выходит из серверов на более высокие уровни: теперь мы можем говорить о GCP Project/AWS VPC/Kubernetes-кластер-«снежинках». Такое происходит из-за того, что на immutable infrastructure не регламентирована имплементация изменений. Более того, никто не знает, как это правильно делать.
GitOps — панацея от всех ваших проблем. Или нет
И вот тут появляется компания Weaveworks и говорит: «Ребята, у нас есть то, что вам нужно, — GitOps». Для пиара GitOps они привлекли такого тяжеловеса, как Kelsey Hightower, создавшего гайд «Kubernetes the hard way». В процессе пиара он усиленно транслирует мысль: «Будь мужиком, б...! Stop Scripting and Start Shipping». И выдаёт некоторое количество маркетингового bullshit bingo:
Key Benefits
- Increased Productivity
- Enhanced Developer Experience
- Improved Stability
- Higher Reliability
- Consistency and Standardization
- Stronger Security Guarantees
Why I should use GitOps
- Deploy Faster More Often
- Easy and Fast Error Recovery
- Easier Credential Management
- Self-documenting Deployments
- Shared Knowledge in Teams
На мой взгляд, наиболее интересные части — это:
- Улучшение консистентности и стандартизации деплоев.
- Улучшенная гарантия безопасности.
- Простое и быстрое восстановление после ошибок.
- Более простое управление доступами и секретами.
- Самодокументирующиеся деплои.
- Распределение знаний в команде.
И каждый, кто пытается разобраться, что такое GitOps, первым делом натыкается на этот хрестоматийный слайд:
GIT — единственный источник правды.
GIT — единственное место, где мы работаем с окружениями.
Все изменения верифицируемы и обозреваемы.
Далее находим принципы GitOps, которые напоминают чуть дополненные принципы IaC:
- Инфраструктура описана декларативно.
- Каноничное желаемое состояние версионировано в Git.
- Одобренные изменения автоматически разворачиваются в инфраструктуре.
- Программное обеспечение следит за корректностью развёртывания и оповещает, если есть расхождение с желаемым состоянием.
Тем не менее всё это — сферическое описание в вакууме, поэтому мы продолжаем наши исследования, находим сайт GitOps.tech и на нём — ряд важных уточнений.
Прежде всего мы узнаём, что GitOps — это инфраструктура, как код в git плюс CD-тулинг, который автоматически применяет это на инфраструктуру.
При этом в рамках GitOps мы должны иметь как минимум два репозитория:
- Репозиторий приложения — описывает исходный код приложения и манифесты, которые описывают деплой этого приложения.
- Инфраструктурный репозиторий — описывает манифесты инфраструктуры и deployment-окружение.
Также в GitOps-идеологии pull-ориентированный подход предпочтительнее, чем push-ориентированный (что идёт несколько вразрез с эволюцией SCM-систем, прошедших путь от тяжеловесных pull-монстров Puppet и Chef к легковесным push-основанным Ansible и Terraform).
Варианты инструментария с официального сайта gitops.tech
И если GitOps — это в первую очередь история про инструментарий, то вполне разумно взять и разобрать концепцию на базе Flux от самой компании Weaveworks. Уж, наверное, авторы идеи должны были сделать эталонную реализацию.
Flux сейчас дорос уже до второй версии и архитектурно состоит из контроллеров, которые работают внутри кластера:
- Source controller.
- Kustomize controller.
- HELM controller.
- Notification controller.
- Image automation controllers.
Логика работы Flux с Helm
Дальнейшее повествование я буду вести на примере деплоя приложения при помощи Helm package manager в Flux 2.
Почему так? Согласно CNCF Survey 2021 HELM package manager был самым популярным Packaging application с долей более 50 %.
К сожалению, более актуальных данных я не нашёл, но не думаю, что с тех пор что-то сильно изменилось.
Итак, давайте пройдёмся с по основной логике работы Flux 2 с Helm. У нас есть два репозитория: приложения и инфраструктуры.
Из репозитория приложения мы делаем HELM-чарт, docker image и пушим их в репозиторий чартов и docker registry соответственно.
Далее у нас есть Kubernetes-кластер, в котором работают контроллеры flux:
Чтобы выкатить наше приложение, мы подготавливаем YAML с описанием custom resource (CR) HelmRelease и пушим его в инфраструктурный репозиторий.
Чтобы flux мог его получить, мы создаём CR GitRepository в кластере Kubernetes. Source-контроллер видит его, идёт в git и скачивает.
Для того чтобы задеплоить этот YAML в кластер, мы описываем ресурс Kustomization.
Kustomize-контролер видит его, идёт к Source-контроллеру, получает YAML и деплоит в кластер.
Helm-контроллер видит, что в кластере появился CR HelmRelease, и идёт к Source-контроллеру, чтобы получить HELM-чарт, который в нём описан.
Для того чтобы Source-контроллер мог дать HELM-контроллеру запрашиваемый чарт, мы должны создать в кластере CR HelmRepository.
Helm-контроллер получает чарт от Source-контроллера, создаёт релиз и деплоит его в кластер, а дальше Kubernetes создаёт нужные pod`ы, идёт в docker registry и скачивает соответствующие имиджи.
Соответственно, чтобы выкатить новую версию нашего приложения, мы должны сделать новый имидж, новый файл с HelmRelease и, возможно, новый HELM chart, разложить их по соответствующим хранилищам и дождаться, когда контроллеры Flux повторят работу по описанной выше цепочке.
И, чтобы картина была законченной, мы ставим где-то Notification-контроллер, который извещает нас о том, что вообще могло пойти не так в нашей схеме.
Кастом-ресурсы Flux
А сейчас пройдёмся по custom resources, которыми оперирует Flux.
Первое — это Git-репозиторий. Здесь мы можем указать адрес Git-репозитория (строка 14) и ветку, куда он смотрит (строка 10).
Таким образом, мы выкачиваем только отдельную ветку, а не весь репозиторий целиком. Но! Так как мы ответственные инженеры и стараемся придерживаться концепции Zero Trust, то закрываем доступ к репозиторию, создаём в Kubernetes-кластере секрет с ключом и даём его Flux’у, чтобы он мог туда ходить (строка 12).
Далее — Kustomization. Тут я сразу хочу обратить ваше внимание, что Kustomize-контроллер от Flux и Kustomize от авторов Kubernetes-деплой-системы — это две разные вещи. Я не знаю, почему был выбран такой странный дезориентирующий нейминг, но их важно не путать.
Kustomization — это способ задеплоить YAML (любой) из Git-репозитория в кластер. Здесь мы должны указать source, откуда мы это ставим (строка 12 — название описанного выше CR GitRepository), каталог, из которого мы берём YAML (строка 8), и можем указать target namespace, куда их деплоить (строка 13).
Следующее — Helm-релиз.
Здесь мы можем указать имя, версию chartа (строки 10,11). Тут вы указываете значения переменных для того, чтобы Helm мог кастомизировать релиз от окружения к окружению (строки 15–19). Это крайне важная и нужная функция, так как окружения у вас могут значительно отличаться. Также вы указываете source, из которого нужно брать на Helm chart (строки 12, 13, 14). В данном случае это Helm-репозиторий.
Но! Так как мы всё ещё ответственные инженеры, то также закрываем доступ в Helm-репозиторий и даём Flux’у секрет для того, чтобы он мог туда попасть (строки 7, 8).
Чек-лист для GitOps
Итак, сделаем небольшой чек-лист для того, чтобы зафиксировать то, что мы сейчас проговорили. Для того чтобы начать делать GitOps, мы должны внезапно написать кучу скриптов (мы ведь помним, что Immutable infrastructure — это полностью автоматизированные пайплайны доставки). Поэтому прежде всего мы должны создать:
- Скрипт для сборки и пуша имиджей в Docker registry.
- Инфраструктурный Git-репозиторий.
- Аккаунт для доступа CI-системы в инфраструктурный GIT-репозиторий.
- Скрипт для генерации и пуша HelmRelease-файла.
- Репозиторий Helm.
- Аккаунт для доступа CI-системы в репозиторий Helm.
- Скрипт для сборки и публикации Helm chart`а.
- Акаунт Flux для инфраструктурного репозитория.
- Акаунт Flux для репозитория Helm-чартов.
Нарушение концепции единого источника правды
Единого источника не получается
Посмотрим, что вообще у нас получается с нашим Helm-релизом. Вполне очевидно, что Git в данном конкретном случае не может быть единственным источником правды. У нас есть по крайней мере два ресурса — два артефакта вне git, от которых этот Helm-релиз зависит:
- Helm chart (строки 8–14).
- Docker image (строка 19).
Причём мы можем ещё больше усложнить ситуацию и указать диапазон версий Helm chart`а.
При этом Flux будет следить и устанавливать новые Helm chart`ы, которые появляются в рамках этого диапазона. Кроме того, Source-контроллер у нас может использовать в качестве источника YAML, в том числе S3-бакеты.
Оттуда мы можем оставить и YAML, и Helm chart`ы.
Кроме того, у нас есть Image automation-контроллеры, которые могут следить за появлением новых образов в Docker registry и править инфраструктурный репозиторий.
Но мы не хотим HELM Chart repo-Ops или Docker registry-Ops, мы хотим быть как можно более GitOps. Поэтому смотрим документацию и правим процессы так, чтобы деплоить наш Helm chart из GIT-репозитория (для его хранения мы выбираем репозиторий приложения).
Это заставляет нас сделать ещё один CR GitRepository для репозитория приложения, аккаунт для доступа к нему Flux и создать секрет с ключами.
При этом мы никак не решаем проблему очень непростой зависимости от Docker image.
Полагаю, что на сегодня будет достаточно. В следующем посте расскажу, какие у этого добра проблемы.
UPD Вышла вторая часть статьи.
Комментарии (54)
LabEG
00.00.0000 00:00+2GitOps на самом деле хорошая концепция, но вы от нее слишком много хотите.
Есть вариант хранить конфиги окружений на машинах, но тогда появляется проблема как их версионировать, как их поддерживать нескольким девопсам, как синхронизировать окружения, как обновить не лазя лишний раз в продуктовый контур. На все эти вопросы отвечает GitOps. Вы храните конфиге в гите и раскатываете из гита так же как вы раскатываете софт.
Да конфиг использует внешние артефакты для своей работы, но это так же плюс. Ибо если в этот конфиг каждый раз вносить хеш сборки ручками то можно замучаться. А так новая версия сервиса накатывается автоматом с ее релизом.
seasadm Автор
00.00.0000 00:00+6Дьявол кроется в деталях.
Хранить конфигурацию в гите и раскатывать их из гита придумали задоооооолго до гитопса (посмотрите тот же тест Лимончелли).
Я хочу от концепции ровно то, что она заявляет - от гита как единственного источника истины до key benefits + пунктов why i should use gitops.
И во второй части статьи обязательно раскрою как GitOps (конкретно flux2) реализует эти пункты. Как говорится, не переключайтесь.
Apoheliy
00.00.0000 00:00+15Честно пытался осилить статью. Честно.
Что такое GitOps и почему он (почти) бесполезен
... Если коротко, то GitOps не является «Серебряной пулей» ... Так что такое GitOps?
Что такое GitOps и зачем он нужен
В этом разделе не раскрывается, что такое GitOps. Ok, читаем дальше
GitOps — панацея от всех ваших проблем. Или нет
Ребята, вам нужен GitOps ... Сайт ... утверждает, что GitOps - это инфраструктура ...
Сарказм: а другие сайты в интернете утверждают про инопланетян и 100500 теорий заговора. Так что такое GitOps?
Логика работы Flux с Helm
Э-э-э, а это причём? Так Helm самое популярное packaging application! Правда, потом выясняется, что это только для kubernetes (видимо, без него не существует GitOps). Так, здесь появляется git репозиторий. Уже хорошо. Их у нас много, набиты кодом. Что по поводу GitOps?
Чек-лист для GitOps
Уже? GitOps - непонятно, но чек-лист - он есть.
Небольшой взгляд в сторону: ну есть скрипты ci/cd. Много кто хранит их в git репозитории. Да что далеко ходить: тот же gitlab настоятельно склоняет к этому. В отдельном хранить репозитории или нет - по моему оба подхода (иногда сильно различны) имеют как плюсы, так и минусы.
Так в чём смысл выделения отдельного понятия GitOps? Что такое GitOps? Пожалуйста, для людей не в теме чуть по-подробнее.
seasadm Автор
00.00.0000 00:00Там картинка есть. GitOps in 1 slide. На английском правда, но знание английского - обязательная вещь для ИТ-шника.
Переведу его для вас: GitOps это паттерн разработки/управления системами. Имеется в виду информационные системы и управление их конфигурацией.
Далее в том же разделе идёт достаточно подробное описание паттерна. Git - единственный источник истины, момент про CD тулинг и два репозитория. Если на ваш взгляд я их не полно изложил, там есть ссылки на сайт, целиком посвященный GitOps - можете разобраться самостоятельно.
И я категорически не понимаю что вас смущает в том, что я рассматриваю один из самых распространённых вариантов реализации GitOps? С Helm и Kubernetes.
Причем я подробно, по шагам, рассматриваю процесс доставки приложения в рамках процессов GitOps.
Если вы настолько не в теме, возможно вам нужно начать с какого-то более простого материала?
Кстати про сравнение CIOps с GitOps будет во второй части статьи. Но опять же судя по всему это может быть для вас сложновато.
event1
00.00.0000 00:00+5Если help-chartы и образы докера создаются из гита автоматически (именно так и выглядит), то принцип "гит — единственный источник правды" не нарушен. Просто часть правды потребляется через посредников
seasadm Автор
00.00.0000 00:00+1Хелм чарт это "лёгкая" зависимость. Но её, как правило, нужно делать out of gitops scope и тут могут быть варианты, - например в HelmRelease у вас диапазон версий чарта, а та часть пайплайна, которая должна собрать и запушить в репозиторий последнюю версию чарта сфэйлилась - в итоге у вас новый имидж на старом чарте, и глядя в гит вы просто не можете понять что пошло не так. Или сервис репозитория чартов слетел и был восстановлен из бэкапа (не самого свежего), - всё консистентность окружения нарушена.
Что до сборки докер имиджа - пвторяемость сборок докер имиджей это фундаментальная проблема. Тут слишком много чего может пойти не так, - от незафиксированной зависимости в библиотеках до содержимого кэша на сборщике.
Если вы утверждаете, что ваши сборки имиджей на 100% повторяемые, то либо вы большой молодец и провели очень большую работу чтобы это было так, либо вы что-то не знаете.
Хорошей практикой чтобы гарантировать повторяемость выкатов является испоьзование так называемых "золотых имиджей", - когда мы собираем один имидж и прогоняем его через все наши окружения и именно его доставляем на продакшен. ТОлько тогда мы можем гарантировать, что доставили на прод именно то что оттестировали.
И это не учитывается в GitOps вообще никак. Даже намёка нет на накую возможность.
event1
00.00.0000 00:00а та часть пайплайна, которая должна собрать и запушить в репозиторий последнюю версию чарта сфэйлилась - в итоге у вас новый имидж на старом чарте, и глядя в гит вы просто не можете понять что пошло не так.
Хуже того, может отключится электричество или упасть сеть и разобраться, что пошло не так "глядя в гит" тоже не получится.
Что до сборки докер имиджа - пвторяемость сборок докер имиджей это фундаментальная проблема.
У нас была аналогичная проблема с повторяемостью сборок (правда не образов докера а образов всего ПО маршрутизатора). Решили путём вынесения всей среды в образ докера, а сборки, соответственно, в контейнер.
JuriM
00.00.0000 00:00Не совсем понял почему нельзя реализовать повторяемость сборок в гитопс. Например дженкинс собирает некий билд и пушит в регистри с тэгом build-1.0-b1. Используем в пайплайнах и манифестах этот имидж с этим тэгом. Собираем другой билд build-1.0-b2 и тд
seasadm Автор
00.00.0000 00:00Причин может быть много. В основном они связаны с подключаемыми библиотеками и внешними зависимостями.
Например в моей практике был случай, когда интеграционные тесты падали на некторых сборках. Это было потому что сборка производилась на четырёх раннерах, и на одном из них в кеше залип базовый имидж с неправильной библиотекой, который сопредельная команда собрала неправильно, потом перепушила с тем же тегом. И поймать это было ой как сложно.
slisli
00.00.0000 00:00+2Вообще я заметил что люди гитопс слишком прямо воспринимают. "У вас секреты не в гите - у вас не гитопс!".
По поводу "артефактов вне гита" вообще странный посыл. Никого не удивляют Gemfile.lock, go.mod и т.д. в репозитории для фиксации зависимостей, но вот тег докер имаджа или хелм чарта уже не канон.
n_bogdanov
00.00.0000 00:00+2Вот прям под каждым словом подпишусь. У вас же программы бинарные, а код вполне себе текстом является. Почему же тогда вас смущает docker-образ, но бинарник, полученный путём компиляции, не смущает.
seasadm Автор
00.00.0000 00:00А какая разница по большому счету? Что образ, что бинарник - артефакты сборки. Образ это такой расширенный бинарник, который включает среду выполнения.
Вопрос в повторяемости сборок.
seasadm Автор
00.00.0000 00:00-1Тоесть по-вашему секреты не в гите позволяют гиту оставаться единственным источником правды?
У нас база на проде отвалилась от воркеров. Гит не менялся. В чем же может быть проблема? Неучто кто-то снёс секрет в волте?
Про повторяемость сборок докер имиджей я уже писал выше. Мы не можем их гарантировать на 146%.
n_bogdanov
00.00.0000 00:00+2Ну раз вы не можете гарантировать повторяемость - тогда это к вам же вопросы, а не к gitops.
Люди бьются, чтобы у них была повторяемая среда. Чтобы их системы сборки изо дня в день выдавали один и тот же результат, а вы нивелируете их усилия своим отношением - у нас не получилось - ни у кого не получилось. Пока я это вижу и в статье и в ответах автора.
seasadm Автор
00.00.0000 00:00Повторяемость мы можем гарантировать с использованием концепции golden image.
Заметка была о другом. Повторяемость это краеуголный камень доставки приложений. И он полностью проигнорирован в GitOps.
И нет, это не очевидно.
n_bogdanov
00.00.0000 00:00+1Олег, на мой взгляд, ты путаешь концепцию и инструментарий. В концепции нет точного описания инструментов, а есть только общая линия построения рабочих процессов. Именно поэтому там не рассматривается повторяемость. Она подразумевается, но её реализация отдана на откуп sre-инженера.
seasadm Автор
00.00.0000 00:00+1Любую концепцию можно описать критерием полноты, с которой она решает поставленную задачу.
Концепция "колесо" не будет полной без указания того, что колесо должно быть круглым для облегчения качения.
slisli
00.00.0000 00:00+2Зависит от того как вы воспринимаете гитопс как концепцию. Если для вас опредление компании weaveworks является догмой - то да, секреты не в гите не позволяют быть единственным источником правды. Ещё можно вспоминать mutation вебхуки которые дополнят поля в манифестах, или OCIRepository который не гит. Да и много чего ещё. Я просто пользуюсь концепцией reconciliation loop и источника данных в гите. Как в Chef да.
Повторяемость сборок - это сложно, полностью согласен. Можно зайти чуть сбоку - собрать один раз, подписать образ с помощью cosign. И проверять на стадии деплоя (Flux это умеет делать). Всё таки чаще мы хотим задеплоить на прод тот же имадж что првоерили ранее. А не собрать ну точно такой же гарантирую это.
seasadm Автор
00.00.0000 00:00Я правильно понимаю, что в своём подходе вы не ориентируетесь на правила GitOps?
Gorthauer87
00.00.0000 00:00+2Очень много боли приносит fluxcd image automation bot.
Суть в том, что он как бы автоматизирует перезаписывание тегов во всяких манифестах типа такого:apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 kind: Kustomization metadata: name: podinfo namespace: default spec: images: - name: ghcr.io/stefanprodan/podinfo newName: ghcr.io/stefanprodan/podinfo # {"$imagepolicy": "flux-system:podinfo:name"} newTag: 5.0.0 # {"$imagepolicy": "flux-system:podinfo:tag"}
И в дальнейшем он просто создает коммит в репозиторий, в котором подменяет newName на что-то другое в соответствии с каким-то своим другим манифестом.
И вот вся эта идея превращается в минное поле: такие файлы помечаются комментарием do not edit, но по сути они превращаются в мины замедленного действия, потому что они могут быть случайно перемещены при рефакторинге, они могут быть переформатированы утилитой автоформатирования. Просто случайно по запарке быть отредактированными.
И каждый раз это приводит ко всяким чудесным неожиданностям типа мерж конфликтов. Ну это если есть несколько окружений и под каждое окружение по своей ветке. Да и в целом выходит, что описание ресурса дублируется дважды: один раз в манифесте для automation бота, а второй раз собственно в том файле, где бот автоматически перезаписывает поле.А еще такое бывает, что даже когда нет автообновления версий, то все равно этот бот используется, просто версия на которую нужно обновить ресурс в том же самом automation манифесте и записывается. В результате обновления окружений перестают быть атомарными, получается все в две ступени:
1. Мержим в ветку окружения обновление версии в flux automation манифест
2. flux bot видит обновление в манифесте и коммитит в эту ветку само обновление ресурса.С этим есть проблема, что если он не сможет выполнить второй шаг, то первая часть то применится.
Короче говоря, как-то все это очень хрупко и проблемно выглядит. Ну или я совершенно не понимаю заложенных во все это принципов и идей.
slisli
00.00.0000 00:00По своему опыту могу лишь сказать что отдельный бранч для окружения делает сильно больно и неудобно. Теряется видимость. Могу порекомендовать попробовать подход с kustomize overlays. Либо генерация ямлов из верхнеуровневой абстракции, но опять таки в одном бранче всё.
Почему у вас дублирование и опасность при перемещении не очень понятно пока. Если можно пример будет понятнее.
n_bogdanov
00.00.0000 00:00+6После прочтения не покидает ощущение, что статья является не критикой gitops, а антирекламой flux.
Как уже выше заметили - наличие registry не отменяет принципа единого источника правды. Просто некоторые системы понимают один формат, в некоторые он другой и, соответственно, внедрение некой подписи выглядит как достойное расширение - есть коммит в git - он подписан ключем maintainer, далее по цепочке "подписываются" или тегируются артефакты. И вот у вас есть стройная цепочка. Главное, чтобы CD сам в Git не лез.
seasadm Автор
00.00.0000 00:00Посмотри на мой ответ выше. Наличие registry делает единый источник правды в гите очень посредственным.
Внедрение подписи многое бы решило, но в гитопс это даже не подразумевается.
Флюкс флюксом, но ты можешь назвать тулинг в котором это реализовано лучше?
n_bogdanov
00.00.0000 00:00+1Ты сам werf упомянул. Вот там, на мой взгляд, лучше. Там есть тот самый механизм подписи, пусть и условный. И связка werf + argocd неплоха.
seasadm Автор
00.00.0000 00:00Ну так верфь это не гитопс а гиттерминизм :)
artazar
00.00.0000 00:00+4Мысль в статье явно не окончена, хотелось бы увидеть следующие части. Вроде как оттенок у статьи негативный, при этом содержимое - просто рассказ про то, как это работает. Как пользователь и пропагандист GitOps/Flux с опытом, могу сказать, что все описанное - вполне себе преимущества данного подхода. Поэтому хочется услышать в чем все-таки автор видит проблемы и какие предлагаются альтернативы. Спасибо за статью!
seasadm Автор
00.00.0000 00:00что все описанное - вполне себе преимущества
Мы твой позор в подвиг обратим (с).
Почти уже закончили вёрстку второй части статьи. В ней целиком и полностью про проблемы подхода. Не переключайтесь :)
lexore
00.00.0000 00:00И если GitOps — это в первую очередь история про инструментарий
И вот здесь все пошло наклонной. Сам подход "git - источник правда" очень хорош. Но workflow у всех разный. И может так случиться, что для вашей реализации подхода GitOps больше подойдут совсем другие инструменты. Если вы чувствуете, что реализация GitOps у вас идет со скрипом, попробуйте остановиться и подумать "правильные ли инструменты я использую".
seasadm Автор
00.00.0000 00:00-1Сам подход "git - источник правда" очень хорош.
Подход хорош только на бумаге. Но если реализовать его только частично (чарт, имидж, секреты вне гита), то источник правды получается очень посредственный. Плюс получается очень много затрат на его реализацию.
Не проще ли принять то, что мир не идеален и попытаться сделать то же самое более лёгким и простым путём?
Об этом во второй части статьи.
lexore
00.00.0000 00:00+4попытаться сделать то же самое более лёгким и простым путём?
Так и я о том же. Выберите инструменты по душе.
Не проще ли принять то, что мир не идеален
Смотря что вы под этим имеете в виду. В моем опыте подход "git - источник правды" работает отлично. Всегда есть артефакты, контейнеры и виртуалки. Но они все собраны из кода и конфигов в гите. Всегда можно понять, из какого тега или коммита мы их получили. Меня спрашивают "Откуда это?". А я в ответ - ссылку на репу. А там и коммит, и комментарий, и номер тикета. А в тикете и описание, и заказчик, и исполнитель. А еще ссылка на pull request с review. Сразу весь контекст.
Если где-то что-то сделано руками по уважительной причине, человеку говорят "Молодец. А теперь реализуй это в гите и собери оттуда". Не все моменты можно решить техническими средствами. Иногда нужно просто напоминать людям, чтобы они соблюдали соглашения.
Хотя может быть, вы не эту проблему пытаетесь решить. Может быть, вам больше актуальна непрерывная доставка?
seasadm Автор
00.00.0000 00:00Так и я о том же. Выберите инструменты по душе.
Именно! Об этом во второй части статьи :)
akurilov
00.00.0000 00:00+1Чтобы Git оставался единственным источником истины, нужно Docker образы маркировать тэгами равными Git commit hash. Helm chart можно вообще генерить на ходу CICD pipeline, а после деплоя выбрасывать.
seasadm Автор
00.00.0000 00:00Не всё так просто. Кейс из практики:
Мы тегировали имидж по git commit hash, запушили его в registry, потом была автоматическая чистка регистри от образов старше полугода. Спот ноды, на которых крутилось приложение перезаказались и новые поды тупо не смогли подняться. Мы повторяем сборку этого имиджа, но в коде есть незафиксированная транзитивная зависимость от библиотечки, которая за пол года стала несовместима с текущими вызовами и часть функционала приложения просто ломается.
akurilov
00.00.0000 00:00+6Так тут у вас проблема в другом - у вас
мастер сломанбилд не работает уже полгода. Gitops здесь не при чем и никак эту проблему решать и не долженОтсутствие внешней библиотеки относится к внешним, неконтролируемым факторам. Это все равно, что заявлять, что Gitops - плохой, потому что не помог при отключении интернета и падении астероида
Плюс фактор самостоятельного отстрела себе ног. Используйте доп тэг latest и чистите старые имажи если они не latest. И ваши волосы станут мягкими и шелковистыми
seasadm Автор
00.00.0000 00:00Да это просто пример, иллюстрирующий что гит - плохой источник истины, если он не имеет связи с артефактами.
Два запуска сборки артефакта на одном комите могут дать совершенно разные результаты. Причин может быть тысяча - от незафиксированных зависимостей до кешей на сборщике.
И в гиотпс нет рецепта как сделать его хорошим источником истины.
Это нужно понимать чтобы выстроить качественный, стабильный процесс доставки программного обеспечения.
akurilov
00.00.0000 00:00+1Git - это лучший источник истины. Другого лучше пока не придумали. Ну разве только что может быть блокчейн? Попробуйте подстроить его под нужды девопс, посмотрим.
lllamnyp
00.00.0000 00:00Мир изменчив, гит не может сохранить все детали реализации вселенной вокруг себя.
Вывод - гитопс плохой, да здравствует CIops (во второй части статьи).
По моему, это какой-то детский идеализм, который не помогает продукту работать и приносить прибыль.
past
00.00.0000 00:00+1Всё становится сильно проще, если убрать из цепочки helm или хотя бы добавить промежуточный стейт репозиторий с плоскими отрендеренными манифестами, на который смотрит Флакс/арго
seasadm Автор
00.00.0000 00:00-1Helm слишком удобный и популярный инструмент чтобы его убирать. Можно рендерить тимплейты из чарта и ложить их в инфраструктурный репозиторий, но тогда мы лишаемся как минимум хелм хуков и функции lookup. Проще убрать из цепочки gitops.
lllamnyp
00.00.0000 00:00+2Или проще убрать лукапы и хуки. Очень легко аргументировать, когда волен задавать все вводные и подбирать те определения, которые удобнее.
seasadm Автор
00.00.0000 00:00Лукапы для рандомных паролей и самоподписанных сертов, генерируемых на окружение. Хуки - для миграций и прогрева баз и кешей. Какие есть способы сделать это проще в рамках гитопс?
past
00.00.0000 00:00+3Хелм это всего лишь sed на стероидах. Гиперусложнен и избыточен. Без него процессы поставки сильно упрощаются.
seasadm Автор
00.00.0000 00:00+1Кубернетес это всего лишь докер композ на стероидах. Гиперсложен и избыточен. Без него процессы поставки сильно упрощаются.
Сори, ничего личного. Просто к слову пришлось :)
Iliya_karin
00.00.0000 00:00+1Я бы сказал что для полноценного GitOps требуется очень высокая зрелость ИТ в компании, нужно что бы разработчики сами были и dev и ops и sre и так далее, для того что бы использовать прям GitOps GitOps.
Я предпочитаю смешанный подход, когда мы работаем вокруг git, но без чрезмерной абстракции и всяких модных и порой лишних (на мой взгляд) инструментов.
felixd7u
00.00.0000 00:00Спасибо за статью, но у нее есть один существенный недостаток. Она не отвечает на тот вопрос, который выносит в заголовок.
Создается впечатление, что вы пытаетесь понять что такое GitOps, но сами для себя не можете это сделать. На мой взгляд это происходит потому, что вы изначально ограничиваете себя только техническими соображениями и не допускаете, что причиной может выступать что то еще. Технические детали важны и технические соображения приведенные вами верны, но в данном случае они не являются существенными.
GitOps, как и микросервисная архитектура, появились и быстро закрепились в индустрии потому, что решают управленческую задачу. Они позволяют создать в компании условия, при которых технические границы повторяют границы административные, разграничивая ответственность между отдельными командами и даже отдельными людьми. Как следствие, достигаются несколько целей. Например, снижается сложность управления людьми, а так же повышается прозрачность процессов. Что в итоге при правильном использовании выражается в деньгах.
Если быть конкретным, GitOps позволяет рассматривать процесс CI/CD как два независимых процесса, с разными зонами ответственности. И тем самым решить извечную боль всех сисадминов и программистов, когда вторым через систему автоматизации постоянно необходимо так или иначе предоставлять администраторский доступ к продакшену. Даже если это происходит не явно, границы ответственности тут несколько размыты и не могут быть жестко проведены. Используя GitOps, мы имеем отдельно CI процесс и отдельно CD процесс, причем их можно рассматривать как различные и не связанные во времени и пространстве. Команда эксплуатации и инфраструктуры, которая отвечает за Kubernetes, может спать спокойно не опасаясь, что кто то скопировав из системы автоматизации токен начнет "только на пять минут, очень надо" производить миграцию базы данных, менять конфигурацию системы и так далее. Причем это изменение никак в коде не отразится и о нем никак узнать будет нельзя.
seasadm Автор
00.00.0000 00:00У вас неверное понимание определений CI CD. Это достаточно частая ошибка, и в начале статьи я специально дал их каноническое определение со ссылкой на источники. Поскольку они появились задолго до GitOps, нет нужды их пересматривать.
Что до обещаний улучшенной безопасности GitOps, это я рассмотрю этот вопрос во второй части статьи. Опубликую на следующей неделе.
felixd7u
00.00.0000 00:00Обычно, когда находят ошибку в рассуждении, дают понять человеку где же именно он ошибся и что в его рассуждениях не верно. Это считается хорошим тоном и уважением к собеседнику. И ни в коем случае не ссылаться на свою же статью, с которой собеседник очевидно не согласен. Я с таким же успехом могу предложить вам перечитать мой коментарий. Вашу статью я прочитал и вынужден заключить, что содержательного подхода там не содержиться, по крайней мере для меня. В любом случае, вы имеете право на свое мнение.
А теперь по существу. Вы действительно думаете, что раз данные определения и принципы не эволюционируют, не изменяются, и не обретают порой иное, иногда даже противоположное изначальному содержание?
Вам привели в коментариях пример FluxCD Image Automation controller, где слепое следование принципу Single Source of State приводит к абсурду и я не вижу причин разворачивать это еще больше. Считать за истину этот принцип сегодня может только тот, кто не работает с реальными системами в боевых окружениях и не понимает всю возникающую проблематику и ньюансы. Уже почти все интерпретируют GitOps шире и не загоняют сами себя в ненужные рамки, прикрываясь устаревшими понятиями. Хотя нужно признать, что одно это не делает эти понятия плохими. В свое время они являлись важными вехами в становлении и развитии нашей профессии. Вы цепляетесь за устаревшую концепцию и, указывая на это, хотите доказать, что она не работает. Но дело в том, что практическая деятельность уже давно решила эту проблему и сегодня никто уже не использует GitOps в контексте "Гит как единственный источник правды", только если он по какой то причине не продолжает цепляться за догмы. Ибо не нужно.
seasadm Автор
00.00.0000 00:00Прошу прощения если мой комментарий вас обидел. Давайте поясню.
Не стоит путать концепцию CI/CD со сборкой и деплоем. Это гораздо более сложная концепция, в которой делается акцент в первую очередь на соблюдении качества кода и стабильности приложения.
Например Continuous delivery не предполагает деплоя куда бы то нибыло. Она предполагает что наш код в мастере настолько качественный, что мы можем при желании задеплоить его в прод в любое время.
Continuous deployment предполагает что всё что приходит в наш мастер, деплоится на прод автоматически. И это, как вы наверное уже понимаете, невозможно без Continuous delivery.
Тоесть вся схема полностью представляет собой матрёшку Continuous integration -> Continuous delivery -> Continuous deployment, каждая часть которой включает в себя предыдущую.
Чтобы говорить что GitOps это Continuous deployment - концепция, нужно пересмотреть определение Continuous deployment. Тоесть поставить знак тождества между Continuous deployment и автоматическим деплоем. На мой взгляд, практических причин это делать нет. Есть только маркетинговые.
Они позволяют создать в компании условия, при которых технические границы повторяют границы административные, разграничивая ответственность между отдельными командами и даже отдельными людьми.
Вы ведь понимаете что это утверждение идёт в разрез с культурой DevOps, которая как раз и создана чтобы рушить барьеры?
Команда эксплуатации и инфраструктуры, которая отвечает за Kubernetes, может спать спокойно не опасаясь, что кто то скопировав из системы автоматизации токен начнет "только на пять минут, очень надо" производить миграцию базы данных, менять конфигурацию системы и так далее.
Тут идёт явная подмена понятий. Почему вы считаете что записать токен в CI-систему равно отдать его программисту? Управление секретами - одна из важных функций CI-систем. При желании можно достаточно тонко выдавать права программистам на ключи, скрывать их и защищать от кражи. И что вас вообще заставляет записывать токены в CI-систему? Есть куча других способов интеграции CI-системы и kubernetes.
И почему вы считаете, что разработчик модет запустить миграцию базы данных только вручную? Почему он не может сделать это в коде? Почему вообще вы считаете что опосредованный доступ к инфраструктуре (через комит кода в гит) безопаснее непосредственного?
Создается впечатление, что вы пытаетесь понять что такое GitOps, но сами для себя не можете это сделать.
Вышла вторая часть и в ней есть вывод что такое гитопс по моему мнению.
https://habr.com/ru/company/gazprombank/blog/717098/
Резюмирую для вас: GitOps не принёс ничего нового. Всё было изобретено до него. Можно подумать что GitOps сделал обязательным требование хранить манифесты IaC в гите (идею Git as the single source of truth вы ведь сами только что обесценили - так что просто забудем про неё), но они утверждают что это не верно:
https://www.gitops.tech/#is-gitops-just-versioned-infrastructure-as-code
Is GitOps just versioned Infrastructure as Code?
No. Declarative Infrastructure as Code plays a huge role for implementing GitOps, but it’s not just that. GitOps takes the whole ecosystem and tooling around Git and applies it to infrastructure. (Здесь всё понятно? Перевод нужен?)
Тоесть под названием гитопс вам фактически продают тулинг. Просто ещё один способ что-то задеплоить.
Если кто-то считает, что он хорошо подходит на его процессы - это нормально. Но ни о каком прорыве/серебряной пуле речи не идёт.
seasadm Автор
Прошу прощения если мой комментарий вас обидел. Давайте поясню.
Не стоит путать концепцию CI/CD со сборкой и деплоем. Это гораздо более сложная концепция, в которой делается акцент в первую очередь на соблюдении качества кода и стабильности приложения.
Например Continuous delivery не предполагает деплоя куда бы то нибыло. Она предполагает что наш код в мастере настолько качественный, что мы можем при желании задеплоить его в прод в любое время.
Continuous deployment предполагает что всё что приходит в наш мастер, деплоится на прод автоматически. И это, как вы наверное уже понимаете, невозможно без Continuous delivery.
Тоесть вся схема полностью представляет собой матрёшку Continuous integration -> Continuous delivery -> Continuous deployment, каждая часть которой включает в себя предыдущую.
Чтобы говорить что GitOps это Continuous deployment - концепция, нужно пересмотреть определение Continuous deployment. Тоесть поставить знак тождества между Continuous deployment и автоматическим деплоем. На мой взгляд, практических причин это делать нет. Есть только маркетинговые.
Вы ведь понимаете что это утверждение идёт в разрез с культурой DevOps, которая как раз и создана чтобы рушить барьеры?
Тут идёт явная подмена понятий. Почему вы считаете что записать токен в CI-систему равно отдать его программисту? Управление секретами - одна из важных функций CI-систем. При желании можно достаточно тонко выдавать права программистам на ключи, скрывать их и защищать от кражи. И что вас вообще заставляет записывать токены в CI-систему? Есть куча других способов интеграции CI-системы и kubernetes.
И почему вы считаете, что разработчик модет запустить миграцию базы данных только вручную? Почему он не может сделать это в коде? Почему вообще вы считаете что опосредованный доступ к инфраструктуре (через комит кода в гит) безопаснее непосредственного?
Вышла вторая часть и в ней есть вывод что такое гитопс по моему мнению.
https://habr.com/ru/company/gazprombank/blog/717098/
Резюмирую для вас: GitOps не принёс ничего нового. Всё было изобретено до него. Можно подумать что GitOps сделал обязательным требование хранить манифесты IaC в гите (идею Git as the single source of truth вы ведь сами только что обесценили - так что просто забудем про неё), но они утверждают что это не верно:
https://www.gitops.tech/#is-gitops-just-versioned-infrastructure-as-code
Is GitOps just versioned Infrastructure as Code?
No. Declarative Infrastructure as Code plays a huge role for implementing GitOps, but it’s not just that. GitOps takes the whole ecosystem and tooling around Git and applies it to infrastructure. (Здесь всё понятно? Перевод нужен?)
Тоесть под названием гитопс вам фактически продают тулинг. Просто ещё один способ что-то задеплоить.
Если кто-то считает, что он хорошо подходит на его процессы - это нормально. Но ни о каком прорыве/серебряной пуле речи не идёт.