GitOps — это такой способ управлять инфраструктурой и приложениями, когда «правда» о состоянии системы живёт в Git. Идея простая: всё, что должно быть в кластере (обычно Kubernetes), описано в манифестах, лежит в репозитории, и любые изменения делаются через коммиты и pull request’ы.
Вместо того чтобы крутить kubectl apply руками или запускать скрипты из CI, вы сначала обновляете конфигурацию в Git, а уже потом специальный контроллер (Argo CD, Flux и т.п.) подтягивает изменения и приводит кластер в нужное состояние. Кластер становится как бы «отзеркаленным» из репозитория.
Основные идеи GitOps можно разложить так:
- Git как единственный источник правды — если чего-то нет в репозитории, этого не должно быть и в кластере (в идеале);
- Pull request как точка входа — любые изменения проходят через PR: можно сделать ревью, прогнать тесты, проверить политику безопасности;
- Автосинхронизация — GitOps-контроллер следит за тем, чтобы состояние кластера совпадало с тем, что в Git, и подтягивает обновления при расхождении;
- Обратимость — чтобы откатиться, достаточно сделать
git revert, а система сама «перекрутит» кластер к предыдущей версии конфигов.
Инструменты, которые чаще всего всплывают в контексте GitOps:
- Argo CD — GitOps-контроллер для Kubernetes с удобным UI, показывает дрифт, статусы, даёт управлять синхронизацией;
- Flux — более лёгкий и модульный движок, хорошо интегрируется с разными Git-платформами;
- GitHub Actions / GitLab CI — сами по себе не GitOps, но обычно используются рядом: валидируют манифесты, гоняют тесты, проверяют политики.
За счёт такого подхода становится проще:
- вести аудит — кто что поменял, когда и зачем, всё видно по истории коммитов;
- автоматизировать релизы без SSH на сервера и ручных команд;
- держать несколько окружений (dev, staging, prod) в одном или нескольких репозиториях, но по одной и той же логике;
- восстановить кластер «из Git» после аварии, потому что вся конфигурация уже описана в коде.
Если сравнивать с DevOps, то GitOps — это не замена, а частный случай. DevOps — это про культуру, процессы, автоматизацию в целом, а GitOps — конкретный паттерн: «всё через Git + контроллер, который синхронизирует кластер».
Сейчас GitOps особенно заходит там, где много Kubernetes, микросервисов и требований к прозрачности: банкинг, крупные SaaS, телеком — в общем, всё, где важно понимать, какая версия чего и где крутится.
GitOps Flow: от коммита до обновления кластера (на примере Argo CD) #
- Разработчик правит манифесты
- В репозитории лежат YAML-ы с описанием Deployment, Service, Ingress и прочего.
- Изменения оформляются в виде Pull Request в нужную ветку — например,
mainилиstaging.
- PR мёржится
- После того как PR приняли, изменения попадают в основную ветку. Argo CD уже знает, что этот каталог/ветка связаны с конкретным кластером и namespace.
- Argo CD проверяет дрифт
- Контроллер опрашивает Kubernetes, забирает текущее состояние ресурсов и сравнивает его с тем, что написано в Git.
- Если есть разница — состояние помечается как OutOfSync.
- Синхронизация
- Argo CD либо автоматически, либо по кнопке/триггеру применяет нужные манифесты.
- Под капотом всё сводится к стандартным операциям наподобие
kubectl apply.
- Кластер обновился
- Новая версия образа, конфигурация или ресурсы вступают в силу.
- В интерфейсе Argo CD можно посмотреть историю, статусы, логи и увидеть, где сейчас какие версии.
Пример манифеста Argo CD Application (CRD) #
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
namespace: production
source:
repoURL: https://github.com/my-org/k8s-manifests
targetRevision: main
path: apps/my-app
project: default
syncPolicy:
automated:
prune: true
selfHeal: true
Что делает этот манифест #
- Подвязывает каталог
apps/my-appиз заданного репозитория к этому Application. - Следит за веткой
mainи тянет оттуда изменения. - Развёртывает все описанные ресурсы в namespace
production. - Включает авто-синхронизацию с
selfHeal(самовосстановление при ручных правках) иprune(удаление ресурсов, которых больше нет в Git).
