Junior DevOps perspektifinden — gerçek lab ortamında, adım adım
Giriş: "Her Deploy Bir Kumar mı Olmalı?"
Bir düşün: üretim ortamına yeni bir versiyon deploy ediyorsun. **kubectl set image** komutunu çalıştırıyorsun ve Kubernetes tüm pod'ları bir anda değiştiriyor. 10 saniye sonra telefon çalıyor — kullanıcılar uygulamaya erişemiyor.
Bu senaryo gerçek. Ve bunun için klasik **Deployment** kaynağı yetersiz kalıyor.
Bu yazıda Argo Rollouts ile canary deployment yapacağız: yeni versiyonu önce trafiğin %20'sine gönder, sağlıklıysa kademeli artır, sorun çıkarsa tek komutla geri dön. Gerçek bir Kubernetes lab ortamında, tüm adımlarıyla.
Ortam
| Bileşen | Detay |
|---|---|
| Kubernetes | v1.29.15 (kubeadm) |
| Nodes | 1 master (px-master) + 1 worker (px-worker) |
| Helm | v3.19.5 |
| Argo Rollouts | v1.9.0 |
Neden Canary? Neden Argo Rollouts?
Klasik Deployment'ın Sorunu
Standart bir Deployment ile image güncellediğinde Kubernetes RollingUpdate stratejisi kullanır. Varsayılan ayarlarla pod'ların %25'i aynı anda değişir. Hızlıdır ama kontrolsüzdür.
Klasik RollingUpdate:
v1 v1 v1 v1 v1
↓
v2 v2 v2 v2 v2 ← hepsi bir anda değişiyor
Bir şeyler patlarsa? Tüm kullanıcılar etkileniyor.
Argo Rollouts ile Canary
Argo Rollouts, Deployment kaynağının üzerine inşa edilmiş bir controller. Kendi CRD'siyle (Rollout) gelir ve trafik split'i, manuel onay kapıları, metrik bazlı otomatik rollback gibi özellikler sunar.
Canary Deployment:
Adım 1: %20 canary
v1 v1 v1 v1 | v2 ← sadece 1 pod yeni versiyon
Adım 2: %40 canary
v1 v1 v1 | v2 v2
Adım 3: %60 canary
v1 v1 | v2 v2 v2
Adım 4: %80 canary
v1 | v2 v2 v2 v2
Adım 5: %100 — Tamamlandı
v2 v2 v2 v2 v2
Her adımda dur, izle, onay ver veya geri dön.
Kurulum
1. Argo Rollouts Controller
Helm reposunu ekle ve controller'ı kur:
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm install argo-rollouts argo/argo-rollouts \
--namespace argo-rollouts \
--create-namespace \
--set dashboard.enabled=true
Controller'ın ayağa kalkmasını bekle:
kubectl rollout status deployment/argo-rollouts -n argo-rollouts
# deployment "argo-rollouts" successfully rolled out
2. kubectl Plugin
Rollout'ları yönetmek için Argo'nun kubectl plugin'ini kur. Bu plugin sayesinde kubectl argo rollouts komutunu kullanabilirsin:
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64
chmod +x kubectl-argo-rollouts-linux-amd64
sudo mv kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
kubectl argo rollouts version
# kubectl-argo-rollouts: v1.9.0+838d4e7
Adım 1: Standart Deployment ile Başla
Önce klasik yöntemi kuralım — farkı görmek için:
kubectl create namespace rollouts-demo
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: rollouts-demo
namespace: rollouts-demo
spec:
replicas: 5
selector:
matchLabels:
app: rollouts-demo
template:
metadata:
labels:
app: rollouts-demo
spec:
containers:
- name: rollouts-demo
image: argoproj/rollouts-demo:blue
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: rollouts-demo-svc
namespace: rollouts-demo
spec:
selector:
app: rollouts-demo
ports:
- port: 80
targetPort: 8080
EOF
5 pod çalışıyor:
NAME READY STATUS RESTARTS AGE
rollouts-demo-84b7c468f-h65kc 1/1 Running 0 38s
rollouts-demo-84b7c468f-hvfdg 1/1 Running 0 38s
rollouts-demo-84b7c468f-nsx86 1/1 Running 0 38s
rollouts-demo-84b7c468f-vbxgg 1/1 Running 0 38s
rollouts-demo-84b7c468f-xxzl4 1/1 Running 0 38s
Adım 2: Deployment → Rollout'a Geçiş
Şimdi aynı uygulamayı Rollout kaynağıyla yeniden tanımlıyoruz. Yapı neredeyse aynı — tek fark spec.strategy bloğu:
kubectl delete deployment rollouts-demo -n rollouts-demo
cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1 # ← artık argoproj CRD'si
kind: Rollout # ← Deployment değil
metadata:
name: rollouts-demo
namespace: rollouts-demo
spec:
replicas: 5
selector:
matchLabels:
app: rollouts-demo
template:
metadata:
labels:
app: rollouts-demo
spec:
containers:
- name: rollouts-demo
image: argoproj/rollouts-demo:blue
ports:
- containerPort: 8080
strategy:
canary:
steps:
- setWeight: 20 # trafiğin %20'si canary'e
- pause: {} # elle onay bekle
- setWeight: 40
- pause: {duration: 30} # 30sn otomatik bekle
- setWeight: 60
- pause: {duration: 30}
- setWeight: 80
- pause: {duration: 30}
EOF
Strategy'yi anlamak:
steps:
setWeight: 20 → 1 pod yeni versiyon (5 pod × %20 = 1)
pause: {} → DUR, elle onay bekle
setWeight: 40 → 2 pod yeni versiyon
pause: 30s → 30 saniye bekle, sonra devam et
...
pause: {} ile pause: {duration: 30} arasındaki fark kritik:
pause: {}→ manuel onay kapısı,promotekomutu gelene kadar beklerpause: {duration: 30}→ otomatik timer, 30 saniye sonra kendi geçer
Rollout durumunu kontrol et:
kubectl argo rollouts get rollout rollouts-demo -n rollouts-demo
Name: rollouts-demo
Status: ✔ Healthy
Strategy: Canary
Step: 8/8
SetWeight: 100
ActualWeight: 100
Images: argoproj/rollouts-demo:blue (stable)
NAME KIND STATUS AGE
⟳ rollouts-demo Rollout ✔ Healthy 48s
└──# revision:1
└──⧉ rollouts-demo-84dc9dcb7d ReplicaSet ✔ Healthy 48s stable
├──□ rollouts-demo-84dc9dcb7d-crw7l Pod ✔ Running 48s
├──□ rollouts-demo-84dc9dcb7d-fc94q Pod ✔ Running 48s
├──□ rollouts-demo-84dc9dcb7d-g224w Pod ✔ Running 48s
├──□ rollouts-demo-84dc9dcb7d-kl6kr Pod ✔ Running 48s
└──□ rollouts-demo-84dc9dcb7d-zhvgs Pod ✔ Running 48s
revision:1 — ilk deploy. 5 pod stable etiketli, sistem sağlıklı.
Adım 3: Canary Deploy — blue → yellow
Yeni versiyon geliyor. Image'ı yellow ile güncelle:
kubectl argo rollouts set image rollouts-demo \
rollouts-demo=argoproj/rollouts-demo:yellow \
-n rollouts-demo
Hemen sonrasında:
⟳ rollouts-demo Rollout ॥ Paused 110s
├──# revision:2
│ └──⧉ rollouts-demo-78857fdfbb ReplicaSet ✔ Healthy 20s canary
│ └──□ rollouts-demo-78857fdfbb-99gf2 Pod ✔ Running 20s ready:1/1
└──# revision:1
└──⧉ rollouts-demo-84dc9dcb7d ReplicaSet ✔ Healthy 110s stable
├──□ rollouts-demo-84dc9dcb7d-crw7l Pod ✔ Running 110s ready:1/1
├──□ rollouts-demo-84dc9dcb7d-g224w Pod ✔ Running 110s ready:1/1
├──□ rollouts-demo-84dc9dcb7d-kl6kr Pod ✔ Running 110s ready:1/1
└──□ rollouts-demo-84dc9dcb7d-zhvgs Pod ✔ Running 110s ready:1/1
Ne oluyor?
┌─────────────────────────────────────────────┐
│ Trafik Dağılımı │
│ │
│ revision:1 (blue) ████████████ %80 │
│ revision:2 (yellow) ███ %20 │
│ │
│ Status: ॥ Paused — elle onay bekleniyor │
└─────────────────────────────────────────────┘
Rollout ilk pause: {} adımında durdu. Seni bekliyor. Bu an gerçek hayatta "metriklere bak" anıdır — hata oranı arttı mı? Latency bozuldu mu?
Manuel Onay
Metrikler iyiyse onay ver:
kubectl argo rollouts promote rollouts-demo -n rollouts-demo
Rollout kendi kendine ilerlemeye başlar:
# ~20 saniye sonra
revision:2 → 2 pod (canary) %40
revision:1 → 3 pod (stable) %60
# ~50 saniye sonra
revision:2 → 3 pod (canary) %60
revision:1 → 2 pod (stable) %40
# ~80 saniye sonra
revision:2 → 4 pod (canary) %80
revision:1 → 1 pod (stable) %20
Tamamlandı
⟳ rollouts-demo Rollout ✔ Healthy
├──# revision:2
│ └──⧉ rollouts-demo-78857fdfbb ReplicaSet ✔ Healthy stable
│ ├──□ rollouts-demo-78857fdfbb-99gf2 Pod ✔ Running
│ ├──□ rollouts-demo-78857fdfbb-w7df4 Pod ✔ Running
│ ├──□ rollouts-demo-78857fdfbb-427mg Pod ✔ Running
│ ├──□ rollouts-demo-78857fdfbb-fqfqs Pod ✔ Running
│ └──□ rollouts-demo-78857fdfbb-gvszz Pod ✔ Running
└──# revision:1
└──⧉ rollouts-demo-84dc9dcb7d ReplicaSet • ScaledDown
5 pod tamamen yellow'a geçti. revision:1 (blue) scale down edildi. Sıfır downtime.
Adım 4: Bozuk Versiyon + Rollback
Asıl soru şu: "Ya yeni versiyon bozuksa?" Bunu simüle ediyoruz.
kubectl argo rollouts set image rollouts-demo \
rollouts-demo=argoproj/rollouts-demo:bad \
-n rollouts-demo
⟳ rollouts-demo Rollout ◌ Progressing
├──# revision:3
│ └──⧉ rollouts-demo-86f7547f69 ReplicaSet ◌ Progressing canary
│ └──□ rollouts-demo-86f7547f69-dcgbn Pod ⚠ ErrImagePull
├──# revision:2
│ └──⧉ rollouts-demo-78857fdfbb ReplicaSet ✔ Healthy stable
│ ├──□ rollouts-demo-78857fdfbb-99gf2 Pod ✔ Running
│ ├──□ rollouts-demo-78857fdfbb-w7df4 Pod ✔ Running
│ ├──□ rollouts-demo-78857fdfbb-427mg Pod ✔ Running
│ ├──□ rollouts-demo-78857fdfbb-fqfqs Pod ✔ Running
│ └──□ rollouts-demo-78857fdfbb-9mpnd Pod ✔ Running
Canary seni koruyor:
┌──────────────────────────────────────────────────────┐
│ revision:3 (bad) ⚠ ErrImagePull → %20 │
│ revision:2 (yellow) ✔ Running → %80 │
│ │
│ Kullanıcıların %80'i hâlâ sağlıklı versiyonda! │
└──────────────────────────────────────────────────────┘
Klasik RollingUpdate olsaydı şu an tüm pod'lar bozuk versiyona geçmeye çalışıyor olacaktı.
Rollback
kubectl argo rollouts abort rollouts-demo -n rollouts-demo
⟳ rollouts-demo Rollout ✖ Degraded
├──# revision:3
│ └──⧉ rollouts-demo-86f7547f69 ReplicaSet • ScaledDown ← bozuk versiyon kapatıldı
├──# revision:2
│ └──⧉ rollouts-demo-78857fdfbb ReplicaSet ✔ Healthy stable
│ ├──□ ...5 pod Running...
abort canary pod'larını kapattı, tüm trafik revision:2'ye döndü. Degraded durumu "abort edildi" anlamında — sistem çalışıyor.
Son olarak Rollout'u temizle:
kubectl argo rollouts undo rollouts-demo -n rollouts-demo
⟳ rollouts-demo Rollout ✔ Healthy
├──# revision:4
│ └──⧉ rollouts-demo-78857fdfbb ReplicaSet ✔ Healthy stable
│ ├──□ ...5 pod Running...
├──# revision:3
│ └──⧉ rollouts-demo-86f7547f69 ReplicaSet • ScaledDown
└──# revision:1
└──⧉ rollouts-demo-84dc9dcb7d ReplicaSet • ScaledDown
✔ Healthy — sistem temiz. Bozuk versiyon tarihte kaldı.
Özet: Ne Öğrendik?
| Komut | Ne Yapar |
|---|---|
helm install argo-rollouts |
Controller'ı cluster'a kurar |
kubectl argo rollouts set image |
Yeni versiyonu canary olarak başlatır |
kubectl argo rollouts get rollout |
Adım adım durumu gösterir |
kubectl argo rollouts promote |
Manuel pause kapısını açar |
kubectl argo rollouts abort |
Canary'i durdurur, trafiği stable'a çeker |
kubectl argo rollouts undo |
Degraded → Healthy'e getirir |
Canary deployment'ın verdiği güvence:
Klasik deploy: Bir şey patlarsa → %100 kullanıcı etkilenir
Canary deploy: Bir şey patlarsa → %20 kullanıcı etkilenir, abort et → %0
Sırada Ne Var?
Bu yazıda manuel canary yaptık — "metriklere bak, onay ver" adımını elle gerçekleştirdik. Bir sonraki seviye Analysis Templates: Prometheus metriklerine bakarak Rollout otomatik olarak "hata oranı %5'i geçtiyse abort et" kararını kendi verebilir.