Сегодня мы расскажем о принципах и моделях GitOps, а также о том, как эти модели реализуются на платформе OpenShift. Интерактивное руководство на эту тему доступно .

Если вкратце, то GitOps – это набор практических методов использования pull-запросов Git для управления конфигурациями инфраструктуры и приложений. Git-репозиторий в рамках GitOps рассматривается как один единственный источник сведений о состоянии системы, причем любые изменения этого состояния полностью отслеживаются и поддаются аудиту.
Идея с отслеживаемостью изменений в GitOps отнюдь не нова, такой подход уже давно и практически повсеместно применяется при работе с исходным кодом приложений. GitOps просто реализует аналогичные функции (review-проверки, pull-запросы, теги и т. д.) при управлении конфигурациями инфраструктуры и приложений и дает аналогичные преимущества, как в случае управления исходным кодом.
Для GitOps нет какого-то академического определения или утвержденного свода правил, лишь свод принципов, на которых строится эта практика:
- Декларативное описание системы хранится в репозитории Git (конфиги, мониторинг и т. д).
- Изменения состояния выполняются через pull-запросы.
- Состояние работающих систем приводится в соответствие с данными в репозитории с помощью push-запросов Git.
Принципы GitOps
- Определения систем описываются как исходный код
Конфигурация систем рассматривается как код, поэтому ее можно хранить и автоматически версионировать в репозитории Git, который служит единственным источником истины. Такой подход позволяет легко накатывать (rollout) и откатывать (rollback) изменения в системах.
- Желаемое состояние и конфигурация систем задаются и версионируются в Git
Храня и версионируя в Git желаемое состояние систем, мы получаем возможность легко накатывать и откатывать изменения в системах и приложениях. Также мы можем использовать Git’овские механизмы безопасности для контроля владения кодом и подтверждения его подлинности.
- Изменения в конфигурациях могут автоматически применяться с помощью pull-запросов
Используя Git’овские pull-запросы, мы можем легко управлять тем, как изменения применяются к конфигурациям в репозитории. Например, их можно отдать на проверку другим участникам команды или прогнать через тесты CI и пр.
И при этом не нужно раздавать админские полномочия направо и налево. Чтобы выполнить commit изменений в конфигурации, пользователи достаточно соответствующих полномочий в репозитории Git, где хранятся эти конфигурации.
- Устранение проблемы неконтролируемого дрифта конфигураций
Когда желаемое состояние системы хранится в репозитории Git, нам остается только найти софт, который бы контролировал, что текущее состояние системы соответствует ее желаемому состоянию. Если это не так, то этот софт должен – в зависимости от настроек – либо самостоятельно устранить несоответствие, либо уведомить нас о дрифте конфигураций.
Модели GitOps для OpenShift
On-Cluster Resource Reconciller
Согласно этой модели в кластере есть контроллер, который отвечает за сравнение Kubernetes-ресурсов (файлов YAML) в Git-репозитории с реальными ресурсами кластера. При выявлении расхождений контроллер рассылает уведомления и, возможно, принимает меры для устранения несоответствий. Эта модель GitOps используется в Anthos Config Management и Weaveworks Flux.

External Resource Reconciler (Push)
Эту модель можно рассматривать как разновидность предыдущей, когда у нас есть один или несколько контроллеров, отвечающих за синхронизацию ресурсов в парах «репозиторий Git – кластер Kubernetes». Отличие же здесь в том, что в каждом управляемом кластере необязательно должен быть свой отдельный контроллер. Пары «Git – кластер k8s» часто определяются как CRD-описания (custom resources definition), в которых можно описать, как контроллер должен выполнять синхронизацию. В рамках этой модели контроллеры сравнивают Git-репозиторий, заданный в CRD, с ресурсами кластера Kubernetes, которые тоже заданы в CRD, и выполняют соответствующие действия по результатам сравнения. В частности, такая модель GitOpsиспользуется в ArgoCD.

GitOps на платформе OpenShift
Администрирование мультикластерной Kubernetes-инфраструктуры
С распространением Kubernetes и ростом популярности мультиоблачных стратегий и периферийных вычислений (edge computing) увеличивается и среднее количество кластеров OpenShift в расчете на одного заказчика.
Например, при использовании периферийных вычислений кластеры одного заказчика могут развертываться сотнями и даже тысячами. В результате он вынужден управлять несколькими независимыми или согласованными кластерами OpenShift в публичном облаке и on-premise.
При этом приходится решать массу проблем, в частности:
- Контролировать, что кластеры находятся в идентичном состоянии (конфиги, мониторинг, хранилища и т. д.)
- Повторно создавать (или восстанавливать) кластеры по известному состоянию.
- Создавать новые кластеры по известному состоянию.
- Накатывать изменения на нескольких кластерах OpenShift.
- Откатывать изменений на нескольких кластерах OpenShift.
- Увязывать шаблонизированные конфигураций с различными средами.
Конфигурации приложения
В ходе своего жизненного цикла приложения часто проходят через цепочку кластеров (dev, stage и т. д.), прежде чем попасть в продакшн-кластер. Кроме того, из-за требований доступности и масштабируемости заказчики часто развертывают приложения сразу на нескольких кластерах on-premise или в нескольких регионах публичной облачной платформы.
При этом приходится решать следующие задачи:
- Обеспечивать движение приложений (бинарники, конфиги и т. д) между кластерам (dev, stage и т. д.).
- Накатывать изменения в приложениях (бинарники, конфиги и т. д) в нескольких кластерах OpenShift.
- Откатывать изменения в приложениях до уровня предыдущей известного состояния.
Сценарии использования OpenShift GitOps
1. Применение изменений из Git-репозитория
Администратор кластера может хранить конфигурации кластера OpenShift в Git-репозитории и автоматически применять их, чтобы без лишних усилий создавать новые кластеры и приводить их в состояние, идентичное известному состоянию, которое хранится в Git-репозитории.
2. Синхронизация с Secret Manager
Админу также пригодится возможность синхронизировать secret-объекты OpenShift с соответствующим ПО наподобие Vault, чтобы управлять ими с помощью специально созданных для этого инструментов.
3. Контроль дрифта конфигураций
Админ будет только за, если OpenShift GitOps будет сам выявлять и предупреждать о расхождениях между реальными конфигурациями и теми, что заданы в репозитории, чтобы можно было оперативно реагировать на дрифт.
4. Уведомления о дрифте конфигураций
Пригодятся в том случае, когда админ хочет оперативно узнавать о случаях дрифта конфигураций, чтобы быстро принимать соответствующие меры самостоятельно.
5. Ручная синхронизация конфигураций при дрифте
Позволяет админу синхронизировать кластер OpenShift с репозиторием Git в случае дрифта конфигураций, чтобы быстро вернуть кластер к предыдущему известному состоянию.
6.Автосихронизация конфигураций при дрифте
Админ также может настроить кластер OpenShift на автоматическую синхронизацию с репозиторием при обнаружении дрифта, чтобы конфигурация кластера всегда соответствовала конфигами в Git’е.
7. Несколько кластеров – один репозиторий
Админ может хранить в одном репозитории Git конфигурации сразу нескольких различных кластеров OpenShift и выборочно применять их по мере надобности.
8. Иерархия кластерных конфигураций (наследование)
Админ может задать иерархию кластерных конфигураций в репозитории (stage, prod, app portfolio и т. д с наследованием). Иначе говоря, он может определять, как должны применяться конфигурации – к одному или к нескольким кластерам.
Например, если админ задает в Git репозитории иерархию «Продакшн кластеры (prod) → Кластеры системы X → Продакшн кластеры системы X», то к продакшн-кластерам системы X применяется объединение следующих конфигов:
- Конфиги, общие для всех продакшн-кластеров.
- Конфиги для кластера системы X.
- Конфиги для продакшн-кластера системы X.
9. Шаблоны и переопределение конфигураций
Админ может переопределить набор унаследованных конфигов и их значений, например, чтобы тоньше настроить конфигурацию для определенных кластеров, к котором они будут применяться.
10. Избирательные include’ы и exclude’ы для конфигураций, конфигурации приложений
Админ может задать условия применения или неприменения тех или иных конфигураций к кластерам с определенными характеристиками.
11. Поддержка шаблонов
Разработчикам пригодится возможность выбирать, как будут определяться ресурсы приложения (Helm Chart, чистый Kubernetes’овский yaml и т. д), чтобы использовать наиболее подходящий формат для каждого конкретного приложения.
Инструменты GitOps на платфомре OpenShift
ArgoCD
ArgoCD реализует модель External Resource Reconcile и предлагает централизованный UI для оркестрации отношений между кластерами и Git-репозиториями по схеме «один ко многим». К недостаткам этой программы можно отнести невозможность управлять приложениями при неработающем ArgoCD.
Flux
Flux реализует модель On-Cluster Resource Reconcile, и, как следствие, здесь нет централизованного управления репозиторием определений, что является слабым местом. С другой стороны, именно из-за отсутствия централизации возможность управлять приложениями сохраняется и при выходе из строя одного кластера.
Установка ArgoCD на OpenShift
ArgoCD предлагает отличный интерфейс командной строки и веб-консоль, поэтому здесь мы не будем рассматривать Flux и другие альтернативы.
Чтобы развернуть ArgoCD на платформе OpenShift 4, выполните следующие шаги в качестве администратора кластера:
Развертывание компонентов ArgoCD на платформе OpenShift
# Create a new namespace for ArgoCD components
oc create namespace argocd
# Apply the ArgoCD Install Manifest
oc -n argocd apply -f https://raw.githubusercontent.com/argoproj/argo-cd/v1.2.2/manifests/install.yaml
# Get the ArgoCD Server password
ARGOCD_SERVER_PASSWORD=$(oc -n argocd get pod -l "app.kubernetes.io/name=argocd-server" -o jsonpath='{.items[*].metadata.name}')Доработка ArgoCD Server, чтобы его видел OpenShift Route
# Patch ArgoCD Server so no TLS is configured on the server (--insecure)
PATCH='{"spec":{"template":{"spec":{"$setElementOrder/containers":[{"name":"argocd-server"}],"containers":[{"command":["argocd-server","--insecure","--staticassets","/shared/app"],"name":"argocd-server"}]}}}}'
oc -n argocd patch deployment argocd-server -p $PATCH
# Expose the ArgoCD Server using an Edge OpenShift Route so TLS is used for incoming connections
oc -n argocd create route edge argocd-server --service=argocd-server --port=http --insecure-policy=RedirectРазвертывание ArgoCD Cli Tool
# Download the argocd binary, place it under /usr/local/bin and give it execution permissions
curl -L https://github.com/argoproj/argo-cd/releases/download/v1.2.2/argocd-linux-amd64 -o /usr/local/bin/argocd
chmod +x /usr/local/bin/argocdСмена админского пароля ArgoCD Server
# Get ArgoCD Server Route Hostname
ARGOCD_ROUTE=$(oc -n argocd get route argocd-server -o jsonpath='{.spec.host}')
# Login with the current admin password
argocd --insecure --grpc-web login ${ARGOCD_ROUTE}:443 --username admin --password ${ARGOCD_SERVER_PASSWORD}
# Update admin's password
argocd --insecure --grpc-web --server ${ARGOCD_ROUTE}:443 account update-password --current-password ${ARGOCD_SERVER_PASSWORD} --new-password После выполнения этих шагов с ArgoCD Server можно работать через веб-консоль ArgoCD WebUI или инструментарий командной строки ArgoCD Cli.
GitOps – никогда не поздно
«Поезд ушел» – так говорят о ситуации, когда возможность что-то сделать упущена. В случае с OpenShift желание тут же начать использовать эту новую классную платформу часто создает именно такую ситуацию с управлением и обслуживанием маршрутов, deployment’ов и других объектов OpenShift. Но всегда ли шанс окончательно упущен?
Продолжая серию статей о , сегодня мы покажем, как преобразовать созданное вручную приложение и его ресурсы в некий процесс, где всем управляет инструментарий GitOps. Для этого мы сначала руками развернем приложение httpd. На скрине ниже показано, как мы создаем пространство имен, deployment и сервис, а потом делаем expose для этого сервиса, чтобы создать маршрут.
oc create -f https://raw.githubusercontent.com/openshift/federation-dev/master/labs/lab-4-assets/namespace.yaml
oc create -f https://raw.githubusercontent.com/openshift/federation-dev/master/labs/lab-4-assets/deployment.yaml
oc create -f https://raw.githubusercontent.com/openshift/federation-dev/master/labs/lab-4-assets/service.yaml
oc expose svc/httpd -n simple-appИтак, у нас есть созданное вручную приложение. Теперь его надо перевести под управление GitOps без потери доступности. Вкратце, это делает так:
- Создаем Git-репозиторий для кода.
- Экспортируем наши текущие объекты и загружаем их в репозиторий Git.
- Выбираем и развертываем инструментарий GitOps.
- Добавляем в этот инструментарий наш репозиторий.
- Определяем приложение в нашем инструментарии GitOps.
- Выполняем пробный запуск приложения, используя инструментарий GitOps.
- Синхронизируем объекты с помощью инструментария GitOps.
- Включаем очистку (pruning) и автосинхронизацию объектов.
Как уже говорилось в предыдущей , в GitOps есть один и только один источник сведений обо всех объектах в кластере(ах) Kubernetes – репозиторий Git. Далее мы исходим из предпосылки, что у вас в организации уже используется Git-репозиторий. Он может быть публичным или частным, но он в обязательном порядке должен быть доступен кластерам Kubernetes. Это может быть тот же самый репозиторий, что и для кода приложений, или же отдельный репозиторий, созданный специально для deployment’ов. В репозитории рекомендуется иметь строгие разрешения, поскольку там будут храниться объекты secret, маршруты и другие чувствительные по безопасности вещи.
В нашем примере мы создадим новый публичный репозиторий на GitHub. Назвать его можно как угодно, мы используем имя blogpost.
Если YAML-файлы объектов не хранились локально или в Git’е, то придется воспользоваться бинарниками oc или kubectl. На скрине ниже мы запрашиваем YAML для нашего пространства имен, deployment’а, сервиса и маршрута. Перед этим мы клонировали только что созданный репозиторий и перешли в него командой cd.
oc get namespace simple-app -o yaml --export > namespace.yaml
oc get deployment httpd -o yaml -n simple-app --export > deployment.yaml
oc get service httpd -o yaml -n simple-app --export > service.yaml
oc get route httpd -o yaml -n simple-app --export > route.yamlТеперь поправим файл deployment.yaml, чтобы удалить из него поле, которое Argo CD не может синхронизировать.
sed -i '/sgeneration: .*/d' deployment.yamlКроме того, надо изменить маршрут. Сначала мы зададим многострочную переменную, а затем заменим ingress: null на содержимое этой переменной.
export ROUTE=" ingress:
- conditions:
- status: 'True'
type: Admitted"
sed -i "s/ ingress: null/$ROUTE/g" route.yamlТак, с файлами разобрались, осталось сохранить их в Git-репозиторий. После чего этот репозиторий становится одним-единственным источником сведений, и любые ручные изменения объектов должны быть строго запрещены.
git commit -am ‘initial commit of objects’
git push origin masterДалее мы исходим из того, что ArgoCD у вас уже развернут (как это сделать – см. предыдущий ). Поэтому добавим в Argo CD созданный нами репозиторий, содержащий код приложения из нашего примера. Только убедитесь, что указываете именно тот репозиторий, который создали ранее.
argocd repo add https://github.com/cooktheryan/blogpostТеперь создаем приложение. Приложение задает значения, чтобы инструментарий GitOps понимал, какой репозиторий и пути использовать, какой OpenShift необходим для управления объектами, а также какая конкретная ветвь репозитория нужна, и должна ли выполняться автосихронизация ресурсов.
argocd app create --project default
--name simple-app --repo https://github.com/cooktheryan/blogpost.git
--path . --dest-server https://kubernetes.default.svc
--dest-namespace simple-app --revision master --sync-policy none После того, как приложение задано в Argo CD, этот инструментарий начинает проверять уже развернутые объекты на соответствие определениям в репозитории. В нашем примере автосинхронизация и очистка отключены, поэтому элементы пока не меняются. Обратите внимание, что в интерфейсе Argo CD наше приложение будет иметь статус «Out of Sync» (Не синхронизировано), поскольку нет label-метки, которую проставляет ArgoCD.
Именно поэтому, когда мы чуть позднее запустим синхронизацию, повторное развертывание объектов выполняться не будет.
Теперь выполним пробный запуск, чтобы убедиться, что в наших файлах нет ошибок.
argocd app sync simple-app --dry-runЕсли ошибок нет, то можно переходить к синхронизации.
argocd app sync simple-appПосле выполнения команды argocd get над нашим приложением, мы должны увидеть, что статус приложения изменился на Healthy (Исправно) или Synced (Синхронизировано). Это будет означать, что все ресурсы в репозитории Git теперь соответствует тем ресурсам, что уже развернуты.
argocd app get simple-app
Name: simple-app
Project: default
Server: https://kubernetes.default.svc
Namespace: simple-app
URL: https://argocd-server-route-argocd.apps.example.com/applications/simple-app
Repo: https://github.com/cooktheryan/blogpost.git
Target: master
Path: .
Sync Policy: <none>
Sync Status: Synced to master (60e1678)
Health Status: Healthy
... А вот теперь уже можно включать автосинхронизацию и очистку, чтобы гарантировать, что ничего не будет создаваться вручную и что каждый раз, когда объект создается или обновляется в репозиторий, будет выполняться развертывание.
argocd app set simple-app --sync-policy automated --auto-prune Итак, мы успешно перевели под управление GitOps приложение, которое изначально никак не использовало GitOps.
Burimi: habr.com
