Модуль 1.2: GitOps
Складність:
[MEDIUM]— ключовий операційний патернЧас на виконання: 30-35 хвилин
Попередні вимоги: Модуль 1 (Infrastructure as Code), основи Git
Що ви зможете зробити
Розділ «Що ви зможете зробити»Після цього модуля ви зможете:
- Пояснити принцип GitOps (Git як єдине джерело істини) та чим він відрізняється від традиційного CI/CD
- Порівняти push-модель та pull-модель розгортання та пояснити, чому pull є безпечнішим
- Описати, як ArgoCD або Flux автоматично виявляють та виправляють відхилення конфігурації (drift)
- Спроектувати базову структуру GitOps-репозиторію для застосунку з кількома оточеннями
Чому це важливо
Розділ «Чому це важливо»GitOps доводить ідею Infrastructure as Code до логічного завершення: Git стає єдиним джерелом істини для всього. Зміни в інфраструктурі відбуваються через Pull Request, а не через прямі команди. Цей патерн стає стандартом для операцій у Kubernetes і зробить вашу роботу набагато ефективнішою.
Реальний випадок: У моїй попередній fintech-компанії старший інженер о 2-й годині ночі розбирався з проблемою на production і вручну виконав команду
kubectl edit deployment payment-gateway, щоб додати змінну оточення для налагодження. Виправлення спрацювало, але він забув оновити вихідний код. Через два тижні відбувся плановий реліз, який затер його ручну зміну. Платіжний шлюз знову непомітно вийшов із ладу, що призвело до 4 годин простою. Це саме та проблема, яку вирішує GitOps: змушуючи проводити всі зміни через Git і автоматично перезаписуючи ручні правки в кластері, ваш репозиторій інфраструктури завжди відображає реальність.
Що таке GitOps?
Розділ «Що таке GitOps?»GitOps — це операційна модель, де:
- Git є джерелом істини для бажаного стану системи
- Зміни відбуваються через Git (коміти, Pull Request)
- Автоматизовані агенти синхронізують фактичний стан із тим, що вказано в Git
- Відхилення (drift) автоматично виправляється до стану, описаного в Git
┌─────────────────────────────────────────────────────────────┐│ TRADITIONAL vs GITOPS │├─────────────────────────────────────────────────────────────┤│ ││ Traditional CI/CD (Push-based): ││ ┌─────┐ ┌─────┐ ┌─────────┐ ┌─────────┐ ││ │ Dev │───►│ Git │───►│ CI │───►│ Cluster │ ││ └─────┘ └─────┘ │ Pipeline│ └─────────┘ ││ └─────────┘ ││ CI pipeline pushes to cluster (needs cluster credentials) ││ ││ GitOps (Pull-based): ││ ┌─────┐ ┌─────┐ ┌─────────┐ ┌─────────┐ ││ │ Dev │───►│ Git │◄───│ GitOps │───►│ Cluster │ ││ └─────┘ └─────┘ │ Agent │ └─────────┘ ││ └─────────┘ ││ Agent pulls from Git and applies (agent lives in cluster) ││ │└─────────────────────────────────────────────────────────────┘Зупиніться та подумайте: Якщо Git є єдиним джерелом істини, що стається з імперативними командами на кшталт
kubectl scaleабоkubectl edit? Чи залишаються вони корисними в середовищі GitOps?
Тепер, коли ми розуміємо концепцію синхронізації на основі pull-моделі на високому рівні, розглянемо фундаментальні правила, які змушують цю модель працювати на практиці.
Чотири принципи GitOps
Розділ «Чотири принципи GitOps»1. Декларативність
Розділ «1. Декларативність»Усе описується декларативно:
# Не "запусти 3 nginx pods"# А "бажаний стан — 3 nginx pods"apiVersion: apps/v1kind: Deploymentmetadata: name: webspec: replicas: 3 # ...2. Версіонованість та незмінність
Розділ «2. Версіонованість та незмінність»Усі зміни проходять через Git:
git log --oneline manifests/a1b2c3d Scale web to 5 replicasd4e5f6g Add redis cacheg7h8i9j Initial deployment
# Кожна зміна:# - Версіонована (хеш коміту)# - Незмінна (не можна змінити історію)# - Авторизована (відомо, хто її зробив)# - Доступна для перегляду (історія PR)3. Автоматичне отримання змін (Pull)
Розділ «3. Автоматичне отримання змін (Pull)»Агенти постійно отримують та застосовують зміни:
┌─────────────────────────────────────────────────────────────┐│ GitOps Agent Loop (кожні 30 секунд — 5 хвилин): ││ ││ 1. Перевірити Git на наявність змін ││ 2. Порівняти стан у Git зі станом у кластері ││ 3. Якщо є різниця: застосувати зміни до кластера ││ 4. Повторити ││ │└─────────────────────────────────────────────────────────────┘4. Постійна синхронізація (Reconciliation)
Розділ «4. Постійна синхронізація (Reconciliation)»Відхилення автоматично виправляється:
# Хтось вручну редагує productionkubectl scale deployment web --replicas=10
# GitOps агент виявляє drift# У Git вказано 3 репліки, у кластері — 10# Агент виправляє: масштабує назад до 3
# Результат: Git завжди перемагаєЗупиніться та подумайте: Виходячи з концепції постійної синхронізації, як швидко, на вашу думку, GitOps агент скасує ручну несанкціоновану зміну, зроблену безпосередньо в кластері?
Оскільки ці принципи закладають основу, нам потрібне спеціальне програмне забезпечення для виконання циклу постійної синхронізації всередині наших кластерів.
Інструменти GitOps
Розділ «Інструменти GitOps»Argo CD
Розділ «Argo CD»Найпопулярніший інструмент GitOps для Kubernetes:
┌─────────────────────────────────────────────────────────────┐│ ARGO CD ARCHITECTURE │├─────────────────────────────────────────────────────────────┤│ ││ ┌─────────────────────────────────────────────────┐ ││ │ KUBERNETES CLUSTER │ ││ │ │ ││ │ ┌──────────────────────────────────────────┐ │ ││ │ │ ARGO CD │ │ ││ │ │ ┌────────────┐ ┌────────────────────┐ │ │ ││ │ │ │ API Server │ │ Application │ │ │ ││ │ │ │ │ │ Controller │ │ │ ││ │ │ └────────────┘ │ (sync loop) │ │ │ ││ │ │ └─────────┬──────────┘ │ │ ││ │ │ ┌────────────┐ │ │ │ ││ │ │ │ Web UI │ │ │ │ ││ │ │ │ (dashboard)│ │ │ │ ││ │ │ └────────────┘ │ │ │ ││ │ └────────────────────────────┼────────────┘ │ ││ │ │ │ ││ │ ┌─────────────────────┘ │ ││ │ ▼ │ ││ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ ││ │ │ App 1 │ │ App 2 │ │ App 3 │ │ ││ │ │(synced) │ │(synced) │ │(synced) │ │ ││ │ └─────────┘ └─────────┘ └─────────┘ │ ││ │ │ ││ └───────────────────────────────────────────────┘ ││ ▲ ││ │ pulls manifests ││ ┌────┴────┐ ││ │ Git │ ││ │ Repo │ ││ └─────────┘ ││ │└─────────────────────────────────────────────────────────────┘Ось приклад конфігурації Argo CD Application, яка підключає Git-репозиторій до простору імен кластера:
# Приклад конфігурації ArgoCD ApplicationapiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: frontend-prod namespace: argocdspec: project: default source: repoURL: 'https://github.com/myorg/gitops-config.git' path: clusters/production/frontend targetRevision: HEAD destination: server: 'https://kubernetes.default.svc' namespace: frontend-prod syncPolicy: automated: prune: true selfHeal: trueFlux CD
Розділ «Flux CD»Альтернатива від CNCF (рівень Graduated):
# Flux GitRepositoryapiVersion: source.toolkit.fluxcd.io/v1kind: GitRepositorymetadata: name: my-app namespace: flux-systemspec: interval: 1m url: https://github.com/myorg/my-app ref: branch: main
---# Flux Kustomization (застосовує маніфести)apiVersion: kustomize.toolkit.fluxcd.io/v1kind: Kustomizationmetadata: name: my-app namespace: flux-systemspec: interval: 5m path: ./kubernetes prune: true sourceRef: kind: GitRepository name: my-appПорівняння
Розділ «Порівняння»| Функція | Argo CD | Flux CD |
|---|---|---|
| UI | Чудовий веб-інтерфейс | Орієнтований на CLI |
| Мультитенантність | Вбудована | Через простори імен |
| RBAC | Комплексний | Native для Kubernetes |
| Підтримка Helm | Першокласна | Через контролери |
| Поріг входження | Середній | Вищий |
| Статус CNCF | Graduated | Graduated |
Перш ніж повністю переходити на ці інструменти, важливо зрозуміти, що перехід на pull-модель не є панацеєю.
Плюси та мінуси GitOps
Розділ «Плюси та мінуси GitOps»Хоча GitOps вирішує багато проблем, він приносить і власні виклики:
- Плюси: Повний аудит через історію Git, спрощений відкат (
git revert), підвищена безпека (CI-системи не потребують облікових даних кластера), а відновлення після збоїв стає таким же простим, як підключення нового кластера до Git-репозиторію. - Мінуси: “Git commit” стає вузьким місцем для кожної дрібної зміни. Робота з секретами потребує додаткових інструментів (таких як SealedSecrets або External Secrets Operator), оскільки не можна зберігати паролі у відкритому вигляді в Git. Зрештою, шаблонізація складних середовищ може призвести до “YAML sprawl” (надмірного розростання YAML-файлів), якщо не керувати цим обережно.
Щоб мінімізувати ці мінуси та максимізувати вигоду, ви повинні ретельно спроектувати структуру ваших Git-репозиторіїв.
Структура репозиторію
Розділ «Структура репозиторію»Монорепозиторій (усе разом)
Розділ «Монорепозиторій (усе разом)»gitops-repo/├── apps/│ ├── frontend/│ │ ├── deployment.yaml│ │ └── service.yaml│ ├── backend/│ │ ├── deployment.yaml│ │ └── service.yaml│ └── database/│ └── statefulset.yaml├── infrastructure/│ ├── ingress-nginx/│ ├── cert-manager/│ └── monitoring/└── clusters/ ├── production/ │ └── kustomization.yaml └── staging/ └── kustomization.yamlПолірепозиторій (окремі репозиторії)
Розділ «Полірепозиторій (окремі репозиторії)»# Репозиторії застосунків (власність розробників)frontend-app/ └── kubernetes/ ├── deployment.yaml └── service.yaml
# GitOps репозиторій (власність Ops)gitops-config/ └── clusters/ ├── production/ │ └── apps.yaml # Посилається на репозиторії застосунків └── staging/ └── apps.yamlРобочий процес GitOps
Розділ «Робочий процес GitOps»┌─────────────────────────────────────────────────────────────┐│ GITOPS DEPLOYMENT WORKFLOW │├─────────────────────────────────────────────────────────────┤│ ││ 1. Розробник вносить зміни ││ └── Оновлює deployment.yaml (новий тег образу) ││ ││ 2. Створює Pull Request ││ └── PR запускає: лінтинг, валідацію, сканування безпеки ││ ││ 3. Рецензування та схвалення ││ └── Команда переглядає, коментує, схвалює ││ ││ 4. Злиття (merge) в main ││ └── Тепер Git має новий бажаний стан ││ ││ 5. GitOps агент виявляє зміну ││ └── Порівнює стан у Git зі станом у кластері ││ ││ 6. Агент застосовує зміну ││ └── kubectl apply (або Helm upgrade тощо) ││ ││ 7. Кластер досягає нового стану ││ └── Нові Pods запущені, старі Pods зупинені ││ ││ Час від злиття до деплою: ~30 секунд — 5 хвилин ││ │└─────────────────────────────────────────────────────────────┘Автоматизація оновлення образів
Розділ «Автоматизація оновлення образів»Сучасні інструменти GitOps можуть автоматично оновлювати теги образів:
# Анотація Argo CD Image Updatermetadata: annotations: argocd-image-updater.argoproj.io/image-list: myapp=myrepo/myapp argocd-image-updater.argoproj.io/myapp.update-strategy: semver
# Flux Image AutomationapiVersion: image.toolkit.fluxcd.io/v1beta1kind: ImageUpdateAutomationmetadata: name: flux-systemspec: interval: 1m sourceRef: kind: GitRepository name: flux-system git: checkout: ref: branch: main commit: author: email: fluxcdbot@users.noreply.github.com name: fluxcdbot messageTemplate: 'Update image to {{.NewTag}}' push: branch: mainПотік:1. CI збирає новий образ: myapp:v1.2.32. Пушить у реєстр (registry)3. GitOps виявляє новий тег4. Оновлює Git-репозиторій новим тегом5. Синхронізує кластер з новим образом
Повністю автоматизовано, повний аудит у Git!Просування (Promotion) через оточення
Розділ «Просування (Promotion) через оточення»┌─────────────────────────────────────────────────────────────┐│ ENVIRONMENT PROMOTION │├─────────────────────────────────────────────────────────────┤│ ││ environments/ ││ ├── base/ # Спільна конфігурація ││ │ ├── deployment.yaml ││ │ └── service.yaml ││ ├── dev/ # Перевизначення для Dev ││ │ └── kustomization.yaml (replicas: 1, image: latest) ││ ├── staging/ # Перевизначення для Staging ││ │ └── kustomization.yaml (replicas: 2, image: v1.2.3) ││ └── prod/ # Перевизначення для Production ││ └── kustomization.yaml (replicas: 5, image: v1.2.2) ││ ││ Процес просування: ││ 1. Зміни спочатку йдуть у dev (auto-deploy) ││ 2. Просування в staging (PR: оновити тег образу staging) ││ 3. Просування в prod (PR: оновити тег образу prod) ││ ││ Кожне просування — це коміт у Git = повний аудит ││ │└─────────────────────────────────────────────────────────────┘Відкат (Rollback) у GitOps
Розділ «Відкат (Rollback) у GitOps»Відкат — це просто git revert:
# На Production виявлено баг!
# Варіант 1: Скасувати комітgit revert abc123git push
# GitOps агент синхронізує: стару версію відновлено# Час на відкат: < 5 хвилин
# Варіант 2: Використати інтерфейс Argo CD# Натиснути "Rollback" у застосунку# Argo повертається до попереднього стану синхронізації
# Усі відкати відстежуються в історії Gitgit log --onelinedef456 Revert "Deploy v1.2.3" # ← Відкат зафіксованоabc123 Deploy v1.2.3 # ← Поганий деплойЧи знали ви?
Розділ «Чи знали ви?»- Термін “GitOps” був запропонований компанією Weaveworks у 2017 році. Усе почалося з допису в блозі, де описувалося, як вони керували кластерами Kubernetes.
- GitOps виключає “kubectl apply” із вашого робочого процесу. У чистому середовищі GitOps людина ніколи не запускає kubectl проти production. Усі зміни проходять через Git.
- Назва Argo CD походить із грецької міфології. “Арго” — це корабель, на якому Ясон та аргонавти вирушили в похід. CD означає Continuous Delivery (безперервна доставка).
- GitOps офіційно визнаний CNCF (Cloud Native Computing Foundation) через робочу групу Open GitOps, яка стандартизувала його основні принципи.
Типові помилки
Розділ «Типові помилки»| Помилка | Чому це шкодить | Рішення |
|---|---|---|
Ручне використання kubectl на production | Обходить аудит і спричиняє drift, який буде перезаписаний. | Обмежте доступ до кластера; проводьте всі зміни через Git-репозиторій. |
| Зберігання секретів у відкритому вигляді в Git | Відкриває доступ до конфіденційних API-ключів та паролів будь-кому, хто має доступ до репозиторію. | Використовуйте SealedSecrets, SOPS або External Secrets Operator. |
| Відсутність процесу рецензування PR | Дозволяє руйнівним або неперевіреним змінам автоматично синхронізуватися з production. | Впровадьте правила захисту гілок, що вимагають схвалення принаймні від одного колеги. |
| Занадто часта синхронізація | Перевантажує API-сервер Kubernetes і створює непотрібний мережевий трафік. | Налаштуйте інтервал синхронізації на розумний проміжок (наприклад, 3–5 хвилин). |
| Відсутність перевірок стану (health checks) | Дозволяє несправним деплоям залишатися запущеними, поки статус синхронізації показує “Healthy”. | Налаштуйте належні readiness та liveness probes у ваших маніфестах. |
| CI та CD в одному репозиторії | Спричиняє нескінченні цикли, де оновлення від CD знову запускають CI-пайплайни. | Розділяйте репозиторій із кодом застосунку та репозиторій із GitOps-маніфестами. |
| Ігнорування сповіщень про drift | Створює хибне відчуття безпеки, коли стан кластера відхиляється від Git без попередження. | Налаштуйте сповіщення в Slack або на email про будь-які події “OutOfSync” в ArgoCD або Flux. |
Контрольні запитання
Розділ «Контрольні запитання»-
Сценарій: О 3-й годині ночі у вашому веб-застосунку виявлено критичну вразливість. Черговий інженер заходить у кластер і використовує
kubectl set image, щоб негайно розгорнути виправлений контейнер. Через десять хвилин вразливість повертається. Що сталося?Відповідь
GitOps агент виявив відхилення конфігурації (drift) між кластером та Git-репозиторієм. Оскільки ручна зміна не була зафіксована в Git, агент вирішив, що кластер перебуває в некоректному стані. Він автоматично синхронізував кластер назад до версії образу з вразливістю, вказаної в репозиторії. Щоб виправити це належним чином, інженер повинен оновити тег образу в Git-репозиторії, дозволивши агенту отримати новий стан. -
Сценарій: Ваша команда вирішує впровадити GitOps і видаляє облікові дані адміністратора кластера з сервера Jenkins CI. Команда безпеки запитує, як Jenkins розгортатиме нові збірки застосунків без цих даних. Як ви поясните новий потік деплою?
Відповідь
Jenkins більше не пушить зміни безпосередньо в кластер Kubernetes. Замість цього останнім кроком CI-пайплайну є коміт та пуш тегу нового зібраного образу в конфігураційний Git-репозиторій. GitOps агент, який безпечно працює всередині кластера, стежить за цим репозиторієм. Коли агент бачить новий коміт, він отримує оновлені маніфести і застосовує їх локально, усуваючи потребу в зберіганні облікових даних кластера в зовнішніх системах. -
Сценарій: Останній реліз вашого мікросервісу платежів містить баг, який подвійно списує кошти в клієнтів. Вам потрібно якнайшвидше повернути систему до точного стану, в якому вона була годину тому. Як ви це зробите в чистому середовищі GitOps?
Відповідь
Ви виконуєте команду `git revert` для коміту, який вніс помилкові маніфести платіжного сервісу, і пушите це скасування в основну гілку. GitOps агент негайно виявить цей новий коміт і синхронізує стан кластера з попередньою стабільною конфігурацією. Оскільки історія Git є незмінною, цей процес забезпечує ідеально задокументований аудит як збою, так і операції відкату. -
Сценарій: Ви проектуєте структуру репозиторію для великого підприємства з 50 мікросервісами. Провідний розробник пропонує тримати всі маніфести Kubernetes у тому ж репозиторії, що і вихідний код застосунку. Яку конкретну проблему GitOps це, швидше за все, спричинить?
Відповідь
Змішування коду застосунку та GitOps-маніфестів в одному репозиторії часто призводить до нескінченних циклів CI/CD. Коли CI-пайплайн збирає новий образ і оновлює маніфест у репозиторії, цей новий коміт знову запустить CI-пайплайн, який знову збере образ, знову оновить маніфест і так далі. Крім того, така структура дуже ускладнює керування конфігураціями для різних оточень без масового дублювання. Щоб уникнути цього, командам слід використовувати полірепозиторну структуру з окремими репозиторіями для коду застосунків та інфраструктурних маніфестів. -
Сценарій: Ваш відділ комплаєнсу вимагає повний аудит того, хто вносив зміни в конфігурацію бази даних на production, коли ці зміни були зроблені і хто їх схвалив. Як pull-модель GitOps задовольняє цю вимогу за замовчуванням?
Відповідь
Оскільки Git слугує єдиним джерелом істини, `git log` виступає як остаточний журнал аудиту для всіх змін інфраструктури. Кожна модифікація прив'язана до підпису коміту конкретного розробника та мітки часу. Крім того, впроваджуючи Pull Request та правила захисту гілок на вашій платформі хостингу Git, ви автоматично створюєте незмінний запис про рецензування та схвалення колегами перед тим, як будь-яка зміна буде синхронізована з кластером. Це повністю усуває потребу в зовнішніх комісіях з управління змінами або ручному веденні журналів. -
Сценарій: Розробник скаржиться, що його новий деплой не з’являється в кластері, хоча ArgoCD показує зелений статус “Synced”. Коли ви перевіряєте кластер, Pods перебувають у стані CrashLoopBackOff. Чому GitOps не завадив цьому несправному деплою?
Відповідь
Інструменти GitOps гарантують, що запитані ресурси застосовані до кластера — саме це вказує статус "Synced". Однак вони покладаються на health probes Kubernetes для визначення фактичного стану застосунку. Якщо розробник не налаштував належні readiness та liveness checks у маніфестах деплою, ArgoCD вважає застосунок справним, доки API Kubernetes приймає ресурси. Ви повинні налаштувати правильні проби, щоб GitOps агент міг точно повідомити про стан "Degraded" і зупинити подальше розгортання. -
Сценарій: У вас є застосунок, розгорнутий у просторі імен
stagingтаproduction. Ви хочете оновити середовище staging новою конфігурацією, не зачіпаючи production. Як ви структуруєте цю зміну у вашому GitOps-репозиторії?Відповідь
Вам слід використовувати інструмент на кшталт Kustomize або Helm у вашому GitOps-репозиторії, щоб відокремити базові конфігурації від перевизначень (overrides) для конкретних середовищ. Ви комітите нову конфігурацію суворо в папку overlay для середовища staging, залишаючи конфігурацію production без змін. GitOps агент, що керує staging, отримає цей конкретний шлях і застосує оновлення. Тим часом агент production залишиться незмінним, забезпечуючи безпечну ізоляцію середовищ і запобігаючи випадковому взаємному впливу.
Практична вправа
Розділ «Практична вправа»Завдання: Ознайомитися з концепціями GitOps без встановлення Argo CD.
# Це симулює поведінку GitOps вручну# У справжньому GitOps це робить агент автоматично
# 1. Створіть "Git-репозиторій" (директорію)mkdir -p ~/gitops-demo/manifestscd ~/gitops-demo
# 2. Створіть початковий бажаний станcat << 'EOF' > manifests/deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: gitops-demospec: replicas: 2 selector: matchLabels: app: gitops-demo template: metadata: labels: app: gitops-demo spec: containers: - name: nginx image: nginx:1.24EOF
# 3. Застосуйте (симуляція синхронізації GitOps)kubectl apply -f manifests/
# 4. Перевіртеkubectl get deployment gitops-demo
# 5. Симулюйте drift (ручна зміна)kubectl scale deployment gitops-demo --replicas=5
# 6. Перевірте driftkubectl get deployment gitops-demo# Показує 5 реплік
# 7. Синхронізуйте (симуляція виправлення GitOps)kubectl apply -f manifests/# Повернулося до 2 реплік!
# 8. Зробіть "зміну в Git"sed -i '' 's/nginx:1.24/nginx:1.25/' manifests/deployment.yaml
# 9. Застосуйте новий стан (симуляція синхронізації GitOps)kubectl apply -f manifests/
# 10. Перевірте оновленняkubectl get deployment gitops-demo -o jsonpath='{.spec.template.spec.containers[0].image}'# Показує nginx:1.25
# 11. Очищенняkubectl delete -f manifests/rm -rf ~/gitops-demoКритерії успіху:
- Ви створили симульовану директорію Git-репозиторію та початковий маніфест деплою.
- Ви застосували початковий стан і перевірили правильну кількість реплік.
- Ви вручну масштабували деплой, щоб симулювати відхилення конфігурації (drift).
- Ви успішно синхронізували кластер назад до стану в Git, спостерігаючи повернення реплік до бажаної кількості.
- Ви оновили версію образу у вашому симульованому Git-репозиторії та застосували її, щоб побачити зміни в дії.
Підсумок
Розділ «Підсумок»GitOps — це операційна модель для сучасного Kubernetes:
Основні принципи:
- Git — єдине джерело істини
- Зміни через Pull Request
- Автоматична синхронізація з кластером
- Автоматичне виправлення відхилень (drift)
Інструменти:
- Argo CD: повнофункціональний, чудовий UI
- Flux CD: рівень CNCF Graduated, Kubernetes-native
Переваги:
- Повний аудит (історія Git)
- Легкий відкат (git revert)
- Краща безпека (немає доступу CI до кластера)
- Самодокументованість (стан у Git)
Ключова ідея: У GitOps ви ніколи не робите kubectl apply на production. Ви робите коміт у Git, а агент робить усе інше.
Наступний модуль
Розділ «Наступний модуль»Модуль 1.3: CI/CD пайплайни — автоматизація збірки, тестування та розгортання.