GitOps ve ArgoCD: Modern Kubernetes Deployment Stratejisi
Kubernetes deployment'larını yönetmek karmaşık ve hata riski yüksek bir süreç olabilir. GitOps metodolojisi ve ArgoCD gibi araçlar, bu süreci Git tabanlı, otomatik ve güvenilir hale getirerek modern DevOps pratiklerinin merkezine yerleşti. Bu yazıda, GitOps prensiplerini ve ArgoCD'nin production ortamlarında nasıl kullanılacağını derinlemesine inceleyeceğiz.
İçindekiler
- GitOps Nedir ve Neden Önemli?
- ArgoCD'ye Giriş
- ArgoCD Kurulumu ve İlk Yapılandırma
- Application Tanımlama ve Deployment
- Multi-Environment Yönetimi (Dev/Staging/Prod)
- Secrets Yönetimi ve Güvenlik
- Progressive Delivery: Canary ve Blue-Green
- Monitoring ve Notifications
- Production Best Practices
- Troubleshooting ve Common Issues
GitOps Nedir ve Neden Önemli? {#gitops-nedir}
GitOps Prensipleri
GitOps, infrastructure ve application deployment'larını yönetmek için Git'i tek doğru kaynak (single source of truth) olarak kullanan bir metodoloji. Temel prensipleri:
1. Declarative Configuration
- Tüm sistem durumu Git repository'lerinde YAML/JSON olarak tanımlanır
- Imperative komutlar yerine desired state tanımlanır
2. Version Control
- Her değişiklik Git commit'i olarak kaydedilir
- Tam audit trail ve rollback yeteneği
- Code review süreçleri otomatik uygulanır
3. Automated Sync
- Git'teki değişiklikler otomatik olarak cluster'a uygulanır
- Cluster state sürekli Git ile senkronize edilir
- Drift detection: Cluster'daki manuel değişiklikler tespit edilir
4. Continuous Reconciliation
- Sistem sürekli olarak desired state'e çekilir
- Self-healing capabilities
GitOps vs Traditional CI/CD
| Aspect | Traditional CI/CD | GitOps |
|---|---|---|
| **Deployment Trigger** | CI pipeline push | Git commit |
| **Access Control** | CI tool cluster erişimi | Git permissions |
| **Audit** | CI logs | Git history |
| **Rollback** | Manual/script | Git revert |
| **State Drift** | Tespit edilemez | Otomatik tespit + düzeltme |
| **Security** | CI credentials | Pull-based (daha güvenli) |
GitOps'un Avantajları
✅ Tam Auditability: Kim, ne, ne zaman değiştirdi? → Git history
✅ Kolay Rollback: git revert ile anında geri alma
✅ Code Review: Deployment değişiklikleri PR review sürecinden geçer
✅ Disaster Recovery: Git clone → apply, cluster yeniden oluşur
✅ Security: Pull-based model, cluster credentials CI'da tutulmaz
✅ Developer Experience: Developers know Git, not kubectl commands
ArgoCD'ye Giriş {#argocd-giris}
ArgoCD Nedir?
ArgoCD, Kubernetes için declarative GitOps continuous delivery tool'u. CNCF graduated project statüsünde ve production-ready.
Temel Özellikler:
- Git repository'leri Kubernetes cluster'ı ile senkronize eder
- Web UI ve CLI ile kolay yönetim
- Multi-cluster support
- SSO/RBAC integration
- Automated sync, health monitoring
- Helm, Kustomize, Jsonnet support
ArgoCD Architecture
┌─────────────────────────────────────────────┐
│ Git Repository │
│ ┌──────────────────────────────────────┐ │
│ │ manifests/ │ │
│ │ ├── dev/ │ │
│ │ ├── staging/ │ │
│ │ └── production/ │ │
│ └──────────────────────────────────────┘ │
└────────────────┬────────────────────────────┘
│ Git Poll/Webhook
▼
┌─────────────────────────────────────────────┐
│ ArgoCD Control Plane │
│ ┌──────────────────────────────────────┐ │
│ │ API Server │ │
│ │ Repository Server │ │
│ │ Application Controller │ │
│ └──────────────────────────────────────┘ │
└────────────────┬────────────────────────────┘
│ Apply manifests
▼
┌─────────────────────────────────────────────┐
│ Kubernetes Cluster (Target) │
│ ┌──────────────────────────────────────┐ │
│ │ Deployments, Services, ConfigMaps │ │
│ │ Ingress, Secrets, etc. │ │
│ └──────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
Components:
- API Server: Web UI ve CLI için gRPC/REST API
- Repository Server: Git repo'lardan manifest'leri çeker
- Application Controller: Kubernetes controller, Git vs cluster state'i karşılaştırır
ArgoCD Kurulumu ve İlk Yapılandırma {#argocd-kurulum}
Kubernetes Cluster'a ArgoCD Kurulumu
Prerequisites:
- Kubernetes 1.21+ cluster
- kubectl access
- (Opsiyonel) Ingress controller
1. ArgoCD Namespace ve Core Components:
# ArgoCD namespace oluştur
kubectl create namespace argocd
# ArgoCD install (stable release)
kubectl apply -n argocd -f \
https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Installation durumunu kontrol et
kubectl get pods -n argocd
# Çıktı:
# NAME READY STATUS RESTARTS AGE
# argocd-application-controller-0 1/1 Running 0 2m
# argocd-dex-server-xxx 1/1 Running 0 2m
# argocd-redis-xxx 1/1 Running 0 2m
# argocd-repo-server-xxx 1/1 Running 0 2m
# argocd-server-xxx 1/1 Running 0 2m
2. ArgoCD CLI Kurulumu:
# Linux
curl -sSL -o argocd-linux-amd64 \
https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
rm argocd-linux-amd64
# macOS
brew install argocd
# Verify
argocd version
3. ArgoCD Server'a Erişim:
Option A: Port-Forward (Development)
kubectl port-forward svc/argocd-server -n argocd 8080:443
# Browser'da aç: https://localhost:8080
Option B: LoadBalancer (Cloud)
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
# External IP'yi al
kubectl get svc argocd-server -n argocd
Option C: Ingress (Production Recommended)
# argocd-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-ingress
namespace: argocd
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
ingressClassName: nginx
rules:
- host: argocd.tektik.tr
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
name: https
tls:
- hosts:
- argocd.tektik.tr
secretName: argocd-tls
kubectl apply -f argocd-ingress.yaml
4. İlk Login:
# Default admin password'u al (auto-generated)
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d; echo
# CLI ile login
argocd login argocd.tektik.tr
# Username: admin
# Password: <yukarıdaki output>
# Admin password'u değiştir (MUTLAKA!)
argocd account update-password
5. Initial Admin Secret'i Sil (Security Best Practice):
kubectl -n argocd delete secret argocd-initial-admin-secret
Application Tanımlama ve Deployment {#application-deployment}
Basit Bir Application Deploy Etmek
Senaryo: Nginx web uygulamasını GitOps ile deploy edeceğiz.
1. Git Repository Hazırlığı:
# Git repo oluştur
mkdir -p gitops-demo/apps/nginx
cd gitops-demo
git init
2. Kubernetes Manifest'leri Oluştur:
# apps/nginx/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80
targetPort: 80
# Commit ve push
git add .
git commit -m "Add nginx application manifests"
git remote add origin https://github.com/your-org/gitops-demo.git
git push -u origin main
3. ArgoCD Application Oluştur:
Method 1: CLI
argocd app create nginx-app \
--repo https://github.com/your-org/gitops-demo.git \
--path apps/nginx \
--dest-server https://kubernetes.default.svc \
--dest-namespace default \
--sync-policy automated \
--auto-prune \
--self-heal
Method 2: YAML (Declarative - Recommended)
# argocd-apps/nginx-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/your-org/gitops-demo.git
targetRevision: main
path: apps/nginx
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true # Git'ten silinen kaynaklar cluster'dan da silinir
selfHeal: true # Cluster'daki manuel değişiklikler otomatik düzeltilir
allowEmpty: false
syncOptions:
- CreateNamespace=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
kubectl apply -f argocd-apps/nginx-app.yaml
# Application durumunu kontrol et
argocd app get nginx-app
# Web UI'dan izle
# https://argocd.tektik.tr → Applications → nginx-app
4. Sync Durumunu İzle:
# CLI ile watch
argocd app sync nginx-app --watch
# Application health check
argocd app wait nginx-app --health
# Deployed resources
kubectl get deploy,svc -n default -l app=nginx
Application Self-Healing Testi
# Manuel olarak replica count'u değiştir (drift oluştur)
kubectl scale deployment nginx --replicas=5 -n default
# ArgoCD 3 dakika içinde (default polling interval) bunu tespit edip
# Git'teki desired state'e (replicas: 3) geri döndürecek
# Anında sync için:
argocd app sync nginx-app
Multi-Environment Yönetimi (Dev/Staging/Prod) {#multi-environment}
Kustomize ile Environment Separation
Repository Structure:
gitops-demo/
├── base/ # Ortak base manifests
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
├── overlays/ # Environment-specific overrides
│ ├── dev/
│ │ ├── kustomization.yaml
│ │ ├── replica-count.yaml
│ │ └── resources.yaml
│ ├── staging/
│ │ ├── kustomization.yaml
│ │ └── replica-count.yaml
│ └── production/
│ ├── kustomization.yaml
│ ├── replica-count.yaml
│ ├── hpa.yaml
│ └── ingress.yaml
└── argocd-apps/
├── dev-app.yaml
├── staging-app.yaml
└── prod-app.yaml
base/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1 # Override edilecek
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
base/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
overlays/production/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: production
bases:
- ../../base
replicas:
- name: nginx
count: 5
images:
- name: nginx
newTag: 1.25-alpine # Lightweight image for prod
resources:
- hpa.yaml
- ingress.yaml
commonLabels:
environment: production
managed-by: argocd
patches:
- path: resources.yaml
target:
kind: Deployment
name: nginx
overlays/production/resources.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
overlays/production/hpa.yaml:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
minReplicas: 5
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
ArgoCD Application for Production:
# argocd-apps/prod-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx-production
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/your-org/gitops-demo.git
targetRevision: main
path: overlays/production # Kustomize overlay path
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
App of Apps Pattern (Multi-App Management)
argocd-apps/app-of-apps.yaml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: app-of-apps
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/your-org/gitops-demo.git
targetRevision: main
path: argocd-apps # Tüm app definition'ları burada
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
Bu pattern ile tek bir ArgoCD Application, diğer tüm Application'ları yönetir. Yeni uygulama eklemek için sadece argocd-apps/ dizinine YAML eklersiniz.
Secrets Yönetimi ve Güvenlik {#secrets-management}
Problem: Git'te Secret Saklamak
❌ Asla Git'te plain-text secret saklamayın!
# ❌ YANLIŞ - Git'e commit etmeyin!
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
stringData:
username: admin
password: super-secret-password
Çözüm 1: Sealed Secrets (Bitnami)
Sealed Secrets, secret'ları encrypt ederek Git'te güvenle saklamanıza olanak tanır.
Kurulum:
# Sealed Secrets controller
kubectl apply -f \
https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
# CLI (kubeseal)
wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/kubeseal-0.24.0-linux-amd64.tar.gz
tar -xvzf kubeseal-0.24.0-linux-amd64.tar.gz
sudo install -m 755 kubeseal /usr/local/bin/kubeseal
Secret Encrypt Etme:
# Plain secret oluştur (local, Git'e commit etme!)
kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password=super-secret-password \
--dry-run=client -o yaml > secret.yaml
# Encrypt et → SealedSecret
kubeseal -f secret.yaml -w sealed-secret.yaml \
--controller-name=sealed-secrets-controller \
--controller-namespace=kube-system
# sealed-secret.yaml artık Git'e commit edilebilir!
cat sealed-secret.yaml
sealed-secret.yaml (Git'e commit edilebilir):
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: db-credentials
namespace: default
spec:
encryptedData:
username: AgBy3i4OJSWK+PiTySYZ... # Encrypted
password: AgAj5e8K2JN4P+qTyQw... # Encrypted
template:
metadata:
name: db-credentials
namespace: default
type: Opaque
ArgoCD Integration:
# ArgoCD automatically detects and applies SealedSecrets
# Controller decrypts them in-cluster → regular Secrets
Çözüm 2: External Secrets Operator (ESO)
External secrets'ı cloud provider secret stores'dan (AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault) çeker.
Kurulum:
helm repo add external-secrets \
https://charts.external-secrets.io
helm install external-secrets \
external-secrets/external-secrets \
-n external-secrets-system \
--create-namespace
AWS Secrets Manager Example:
# SecretStore tanımla (AWS Secrets Manager'a bağlan)
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-secretstore
namespace: default
spec:
provider:
aws:
service: SecretsManager
region: eu-west-1
auth:
jwt:
serviceAccountRef:
name: external-secrets-sa # IRSA configured
---
# ExternalSecret tanımla (AWS'den çek)
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
namespace: default
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secretstore
kind: SecretStore
target:
name: db-credentials # Oluşturulacak Kubernetes Secret adı
creationPolicy: Owner
data:
- secretKey: username
remoteRef:
key: production/database # AWS Secrets Manager key
property: username
- secretKey: password
remoteRef:
key: production/database
property: password
ESO bu ExternalSecret'ı okuyup, AWS Secrets Manager'dan çekip Kubernetes Secret olarak oluşturur. Git'te sadece ExternalSecret definition tutulur, actual secret values AWS'de.
ArgoCD RBAC Configuration
argocd-rbac-cm ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.default: role:readonly
policy.csv: |
# Developers: read-only access
p, role:developer, applications, get, */*, allow
p, role:developer, applications, sync, */dev/*, allow
g, developers-team, role:developer
# DevOps: full access to dev/staging
p, role:devops, applications, *, */dev/*, allow
p, role:devops, applications, *, */staging/*, allow
p, role:devops, applications, get, */production/*, allow
g, devops-team, role:devops
# Admins: full access
p, role:admin, applications, *, */*, allow
g, admins-team, role:admin
Progressive Delivery: Canary ve Blue-Green {#progressive-delivery}
Argo Rollouts ile Canary Deployment
Argo Rollouts Kurulumu:
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f \
https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
# Rollouts CLI
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64
sudo install -m 755 kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
Canary Rollout Definition:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: nginx-rollout
spec:
replicas: 10
revisionHistoryLimit: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
strategy:
canary:
steps:
- setWeight: 20 # %20 traffic to canary
- pause: {duration: 5m}
- setWeight: 40
- pause: {duration: 5m}
- setWeight: 60
- pause: {duration: 5m}
- setWeight: 80
- pause: {duration: 5m}
# Analysis başarılıysa %100'e geç
canaryService: nginx-canary # Canary pods için service
stableService: nginx-stable # Stable pods için service
trafficRouting:
nginx:
stableIngress: nginx-ingress # Stable ingress
annotationPrefix: nginx.ingress.kubernetes.io
AnalysisTemplate (Automated Canary Validation):
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
metrics:
- name: success-rate
interval: 1m
successCondition: result >= 0.95 # %95 success rate
failureLimit: 3
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(http_requests_total{status=~"2.."}[1m]))
/
sum(rate(http_requests_total[1m]))
Rollout ile Analysis Integration:
spec:
strategy:
canary:
steps:
- setWeight: 20
- pause: {duration: 2m}
- analysis:
templates:
- templateName: success-rate
args:
- name: service-name
value: nginx-canary
- setWeight: 50
# ...
Rollout Yönetimi:
# Image update (GitOps ile)
# Git'te image tag'i değiştir → ArgoCD sync → Canary rollout başlar
# Rollout durumu izle
kubectl argo rollouts get rollout nginx-rollout --watch
# Manual promotion
kubectl argo rollouts promote nginx-rollout
# Rollback
kubectl argo rollouts abort nginx-rollout
kubectl argo rollouts undo nginx-rollout
Monitoring ve Notifications {#monitoring-notifications}
Prometheus Metrics
ArgoCD metrics'i Prometheus ile expose edilir:
# ServiceMonitor (Prometheus Operator)
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-metrics
namespace: argocd
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-metrics
endpoints:
- port: metrics
Önemli Metrics:
argocd_app_info: Application metadataargocd_app_sync_total: Sync countsargocd_app_health_status: Health status (0=Missing, 1=Progressing, 2=Suspended, 3=Healthy, 4=Degraded)argocd_git_request_duration_seconds: Git fetch latency
Grafana Dashboard: Import ID 14584 (ArgoCD by Akuity)
Slack/Teams Notifications
argocd-notifications ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
service.slack: |
token: $slack-token
template.app-deployed: |
message: |
✅ Application {{.app.metadata.name}} deployed successfully!
🔗 {{.context.argocdUrl}}/applications/{{.app.metadata.name}}
📦 Image: {{range .app.status.summary.images}}{{.}}{{end}}
template.app-health-degraded: |
message: |
⚠️ Application {{.app.metadata.name}} is DEGRADED!
🔗 {{.context.argocdUrl}}/applications/{{.app.metadata.name}}
trigger.on-deployed: |
- when: app.status.operationState.phase == 'Succeeded'
send: [app-deployed]
trigger.on-health-degraded: |
- when: app.status.health.status == 'Degraded'
send: [app-health-degraded]
Secret (Slack Token):
kubectl create secret generic argocd-notifications-secret \
-n argocd \
--from-literal=slack-token=xoxb-your-slack-token
Application Annotation (Subscribe to Notifications):
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx-production
annotations:
notifications.argoproj.io/subscribe.on-deployed.slack: devops-channel
notifications.argoproj.io/subscribe.on-health-degraded.slack: alerts-channel
Production Best Practices {#best-practices}
1. Repository Structure
✅ Monorepo (Recommended for Small/Medium):
gitops-repo/
├── infrastructure/ # Cluster-wide resources
│ ├── cert-manager/
│ ├── ingress-nginx/
│ └── monitoring/
├── apps/ # Applications
│ ├── api/
│ ├── frontend/
│ └── worker/
└── argocd-apps/ # ArgoCD Application definitions
✅ Separate Repos (Large Organizations):
infrastructure-gitops: Cluster infrastructureapp-team-a-gitops: Team A appsapp-team-b-gitops: Team B apps
2. Branch Strategy
Option A: Environment Branches
main→ Productionstaging→ Stagingdev→ Development
Option B: Single Branch + Directories (Recommended)
- Single
mainbranch - Different directories for environments (
overlays/dev,overlays/prod) - Less complexity, easier to manage
3. Security Hardening
Disable Anonymous Access:
# argocd-cm ConfigMap
data:
users.anonymous.enabled: "false"
Enable SSO (Google/GitHub/OIDC):
# argocd-cm ConfigMap
data:
url: https://argocd.tektik.tr
dex.config: |
connectors:
- type: github
id: github
name: GitHub
config:
clientID: $dex.github.clientId
clientSecret: $dex.github.clientSecret
orgs:
- name: your-org
Network Policies:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: argocd-server
namespace: argocd
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: argocd-server
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
4. Resource Limits
# argocd-repo-server Deployment patch
spec:
template:
spec:
containers:
- name: argocd-repo-server
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
5. High Availability
3 Replicas for Critical Components:
kubectl scale deployment argocd-server --replicas=3 -n argocd
kubectl scale deployment argocd-repo-server --replicas=3 -n argocd
kubectl scale deployment argocd-dex-server --replicas=3 -n argocd
# Application Controller (StatefulSet)
kubectl scale statefulset argocd-application-controller --replicas=3 -n argocd
Redis HA:
# Use Redis Sentinel or Redis Cluster for production
helm install redis bitnami/redis \
--set sentinel.enabled=true \
--set master.persistence.enabled=true
6. Backup Strategy
Backup ArgoCD Application Definitions:
# Export all applications
kubectl get applications -n argocd -o yaml > argocd-apps-backup.yaml
# Restore
kubectl apply -f argocd-apps-backup.yaml
Backup ArgoCD Configuration:
kubectl get configmaps,secrets -n argocd -o yaml > argocd-config-backup.yaml
Automated Backup (Velero):
velero backup create argocd-backup \
--include-namespaces argocd \
--storage-location default
Troubleshooting ve Common Issues {#troubleshooting}
Issue 1: Application Stuck in "OutOfSync"
Sebep: Git'teki manifest geçersiz veya cluster'a apply edilemiyor.
Çözüm:
# Diff kontrol et
argocd app diff nginx-app
# Manifests'leri validate et
kubectl apply --dry-run=client -f apps/nginx/
# Force sync
argocd app sync nginx-app --force
# Prune eski resources
argocd app sync nginx-app --prune
Issue 2: "ComparisonError" - Manifest Generation Failed
Sebep: Kustomize/Helm build hatası.
Çözüm:
# Local olarak test et
kustomize build overlays/production
# ArgoCD logs
kubectl logs -n argocd deployment/argocd-repo-server -f
# Application events
kubectl describe application nginx-app -n argocd
Issue 3: Image Update Tespit Edilmiyor
Sebep: Auto-sync kapalı veya image tag değişmemiş (:latest kullanıyorsanız).
Çözüm:
# Specific image tags kullan (semantic versioning)
# ❌ image: nginx:latest
# ✅ image: nginx:1.25.3
# Image updater tool kullan (ArgoCD Image Updater)
kubectl apply -f \
https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml
Issue 4: Secrets Senkronize Olmuyor
Sebep: SealedSecrets controller çalışmıyor veya encryption key yanlış.
Çözüm:
# Sealed Secrets controller durumu
kubectl get pods -n kube-system | grep sealed-secrets
# Manually decrypt test
kubeseal --recovery-unseal --recovery-private-key key.pem \
< sealed-secret.yaml
# Re-encrypt with correct key
kubeseal --cert controller.pem < secret.yaml -w new-sealed-secret.yaml
Issue 5: Performance Degradation
Sebep: Çok fazla application, büyük manifests, frequent polling.
Çözüm:
# Webhook kullan (polling yerine)
# GitHub webhook: https://argocd.tektik.tr/api/webhook
# Application controller sharding
kubectl set env statefulset/argocd-application-controller \
-n argocd \
ARGOCD_CONTROLLER_REPLICAS=3
# Resource limits artır
kubectl set resources deployment argocd-repo-server \
-n argocd \
--limits=cpu=2,memory=2Gi \
--requests=cpu=1,memory=1Gi
Sonuç
GitOps ve ArgoCD, modern Kubernetes deployment'larının standart haline geldi. Git-based workflow, otomatik senkronizasyon, self-healing ve tam audit trail özellikleri ile production ortamlarında güvenilir ve ölçeklenebilir deployment sağlar.
Key Takeaways:
✅ Git is the single source of truth → All changes via Git
✅ Automated sync + self-heal → Cluster always matches Git
✅ Secrets management → Sealed Secrets or External Secrets Operator
✅ Progressive delivery → Argo Rollouts ile canary/blue-green
✅ Multi-environment → Kustomize overlays + App of Apps pattern
✅ Security + RBAC → SSO, network policies, least privilege
✅ Monitoring + Alerts → Prometheus metrics + Slack notifications
Bir sonraki adım: Kendi GitOps pipeline'ınızı kurun, başlangıçta basit tutun (tek uygulama, tek environment), sonra kademeli olarak genişletin (multi-env, secrets, progressive delivery).
TekTık Yazılım olarak GitOps ve ArgoCD konusunda danışmanlık, kurulum ve eğitim hizmetleri sunuyoruz. Kubernetes deployment süreçlerinizi modernize etmek için bizimle iletişime geçin: info@tektik.tr
Faydalı Kaynaklar: