Що насправді означає GitOps
GitOps — це операційний фреймворк, де Git є єдиним джерелом правди для вашої інфраструктури та конфігурації застосунку. Замість того щоб вручну запускати kubectl apply чи тригерити імперативні скрипти, ви оголошуєте бажаний стан у Git і дозволяєте оператору автоматично примиряти його.
Основні принципи прості:
- Декларативна конфігурація. Усе описано як код у Git.
- Контроль версій. Кожна зміна проходить через pull request з ревʼю.
- Автоматизоване примирення. Агент постійно забезпечує відповідність живого стану бажаному.
- Самовідновлення. Дрифт від бажаного стану виявляється і виправляється автоматично.
ArgoCD — найбільш широко використовуваний GitOps-оператор для Kubernetes. У цьому посібнику ми проходимо повне впровадження з нуля.
Встановлення ArgoCD
Розгорніть ArgoCD у вашому кластері за допомогою офіційних маніфестів або Helm:
# Option 1: Official manifests
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Option 2: Helm (recommended for production)
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm install argocd argo/argo-cd \
--namespace argocd \
--create-namespace \
--values argocd-values.yaml
Production Helm values:
# argocd-values.yaml
server:
replicas: 2
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 5
ingress:
enabled: true
ingressClassName: nginx
hosts:
- argocd.example.com
tls:
- secretName: argocd-tls
hosts:
- argocd.example.com
controller:
replicas: 2
resources:
requests:
memory: 512Mi
cpu: 250m
limits:
memory: 1Gi
repoServer:
replicas: 2
resources:
requests:
memory: 256Mi
cpu: 100m
redis-ha:
enabled: true
configs:
params:
server.insecure: false
application.instanceLabelKey: argocd.argoproj.io/instance
Отримайте початковий пароль адміністратора:
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
Структура репозиторію для GitOps
Ми рекомендуємо відокремлювати вихідний код застосунку від маніфестів розгортання. Це патерн, що масштабується:
# Application repo (app developers own this)
my-api/
├── src/
├── Dockerfile
├── .github/workflows/build.yml
└── ...
# Deployment repo (platform team + app developers)
k8s-deployments/
├── apps/
│ ├── my-api/
│ │ ├── base/
│ │ │ ├── deployment.yaml
│ │ │ ├── service.yaml
│ │ │ ├── hpa.yaml
│ │ │ └── kustomization.yaml
│ │ └── overlays/
│ │ ├── dev/
│ │ │ ├── kustomization.yaml
│ │ │ └── patch-replicas.yaml
│ │ ├── staging/
│ │ └── production/
│ └── another-service/
├── infrastructure/
│ ├── cert-manager/
│ ├── ingress-nginx/
│ └── monitoring/
└── projects/
└── platform.yaml
Kustomize Base та Overlays
База містить ваші маніфести за замовчуванням:
# apps/my-api/base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-api
spec:
replicas: 2
selector:
matchLabels:
app: my-api
template:
metadata:
labels:
app: my-api
spec:
containers:
- name: my-api
image: myregistry.com/my-api:latest
ports:
- containerPort: 8080
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
readinessProbe:
httpGet:
path: /readyz
port: 8080
Overlays середовища кастомізують конкретні значення:
# apps/my-api/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: production
resources:
- ../../base
patches:
- path: patch-replicas.yaml
images:
- name: myregistry.com/my-api
newTag: v1.4.2
# apps/my-api/overlays/production/patch-replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-api
spec:
replicas: 5
Створення ArgoCD Applications
Визначте свої застосунки як Kubernetes-ресурси (патерн "App of Apps"):
# projects/platform.yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: platform
namespace: argocd
spec:
description: Platform services
sourceRepos:
- "https://github.com/mycompany/k8s-deployments.git"
destinations:
- namespace: "*"
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: "*"
kind: "*"
# apps/my-api/argocd-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-api-production
namespace: argocd
labels:
app.kubernetes.io/part-of: platform
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: platform
source:
repoURL: https://github.com/mycompany/k8s-deployments.git
targetRevision: main
path: apps/my-api/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true
retry:
limit: 3
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Пояснення ключових налаштувань:
selfHeal: true-- ArgoCD скасовує ручні зміни, зроблені черезkubectl. Це забезпечує Git як єдине джерело правди.prune: true-- ресурси, видалені з Git, видаляються з кластера.PruneLast: true-- видалення відбувається після завершення всіх інших операцій синхронізації.
Інтеграція з CI/CD конвеєром
Ваш CI-конвеєр будує і пушить образи. Потім він оновлює репо розгортань, щоб тригерити ArgoCD:
# .github/workflows/build.yml (in the application repo)
name: Build and Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
outputs:
image_tag: ${{ steps.meta.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Build and push image
uses: docker/build-push-action@v5
with:
push: true
tags: myregistry.com/my-api:${{ github.sha }}
- name: Update deployment manifest
run: |
git clone https://x-access-token:${{ secrets.DEPLOY_TOKEN }}@github.com/mycompany/k8s-deployments.git
cd k8s-deployments
# Update the image tag in kustomization
cd apps/my-api/overlays/production
kustomize edit set image myregistry.com/my-api:${{ github.sha }}
git config user.name "github-actions"
git config user.email "[email protected]"
git add .
git commit -m "deploy: my-api ${{ github.sha }}"
git push
ArgoCD виявляє коміт, порівнює відрендерені маніфести з живим станом і виконує синхронізацію автоматично.
Прогресивна доставка з Argo Rollouts
Для продакшн-середовищ замінюйте стандартні Deployments на Argo Rollouts для canary або blue-green розгортань:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: my-api
namespace: production
spec:
replicas: 5
selector:
matchLabels:
app: my-api
template:
metadata:
labels:
app: my-api
spec:
containers:
- name: my-api
image: myregistry.com/my-api:v1.4.2
ports:
- containerPort: 8080
strategy:
canary:
steps:
- setWeight: 10
- pause: { duration: 5m }
- setWeight: 30
- pause: { duration: 5m }
- setWeight: 60
- pause: { duration: 5m }
analysis:
templates:
- templateName: success-rate
startingStep: 1
canaryService: my-api-canary
stableService: my-api-stable
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
metrics:
- name: success-rate
interval: 60s
successCondition: result[0] > 0.95
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(http_requests_total{service="my-api",status!~"5.."}[5m]))
/
sum(rate(http_requests_total{service="my-api"}[5m]))
Ця конфігурація прогресивно зміщує трафік з 10% до 30% до 60% до 100%, з автоматичним відкатом, якщо рівень успішності падає нижче 95%.
Управління кількома кластерами
ArgoCD може керувати кількома кластерами з єдиної панелі управління:
# Add a remote cluster
argocd cluster add my-staging-cluster --name staging
# Create an application targeting the remote cluster
argocd app create my-api-staging \
--repo https://github.com/mycompany/k8s-deployments.git \
--path apps/my-api/overlays/staging \
--dest-server https://staging-api.example.com \
--dest-namespace staging
Для управління багатьма застосунками між кластерами використовуйте ApplicationSets:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: my-api
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: production
url: https://kubernetes.default.svc
- cluster: staging
url: https://staging-api.example.com
template:
metadata:
name: "my-api-{{cluster}}"
spec:
project: platform
source:
repoURL: https://github.com/mycompany/k8s-deployments.git
targetRevision: main
path: "apps/my-api/overlays/{{cluster}}"
destination:
server: "{{url}}"
namespace: "{{cluster}}"
Найкращі операційні практики
- Використовуйте Projects, щоб забезпечувати RBAC. Обмежуйте, до яких репо та неймспейсів кожна команда може розгортати.
- Увімкніть сповіщення. ArgoCD має вбудований notification controller, який може надсилати повідомлення в Slack, оновлення статусу GitHub та webhook-виклики на події синхронізації.
- Моніторте сам ArgoCD. Він віддає Prometheus-метрики на
/metrics. Налаштуйте оповіщення на невдалі синхронізації та високий час примирення. - Встановлюйте ліміти ресурсів на компоненти ArgoCD. Зокрема repo-server може споживати значну кількість пам'яті при рендерингу великих маніфестів.
- Використовуйте sync windows, щоб запобігти розгортанням під час maintenance-вікон чи поза робочими годинами.
Висновок
GitOps з ArgoCD перетворює розгортання в Kubernetes з підверженого помилкам ручного процесу на автоматизовану, аудитовану та самовідновлювану систему. Поєднання декларативної конфігурації, автоматизованого примирення та прогресивної доставки дає командам впевненість часто розгортати без ризику.
У DevOpsVibe ми впроваджуємо GitOps-конвеєри, які переводять команди від ручних розгортань до повністю автоматизованої доставки в кількох кластерах. Чи ви впроваджуєте GitOps вперше, чи масштабуєте існуюче налаштування, ми можемо допомогти вам дістатися туди швидше. Дайте нам знати, як ми можемо допомогти.