Canary Deployment #
Canary deployment mengambil pendekatan berbeda dari Blue/Green: bukan memilih antara semua pengguna mendapat versi baru atau tidak satu pun, tapi mulai dengan porsi kecil (misalnya 5%), pantau metrik, dan secara bertahap tambah porsinya jika semua terlihat baik. Nama “canary” merujuk pada canary bird yang dulu digunakan penambang untuk mendeteksi gas beracun — Pod canary adalah “penambang” yang masuk duluan untuk mendeteksi masalah sebelum semua pengguna terkena dampaknya.
Prinsip Dasar #
Progressive traffic shift dengan monitoring:
Tahap 1: v1 (95%) + v2 (5%) → pantau 15 menit, metrik OK?
Tahap 2: v1 (75%) + v2 (25%) → pantau 15 menit, metrik OK?
Tahap 3: v1 (50%) + v2 (50%) → pantau 15 menit, metrik OK?
Tahap 4: v1 (25%) + v2 (75%) → pantau 15 menit, metrik OK?
Tahap 5: v2 (100%) → deployment selesai
Jika di tahap mana pun metrik memburuk:
→ Rollback: kembalikan semua traffic ke v1
→ Investigasi sebelum mencoba lagi
Implementasi Sederhana dengan Pod Replicas #
Cara paling mudah di Kubernetes: kontrol persentase traffic dengan jumlah Pod.
# Deployment stable (v1) — 9 Pod = 90% traffic
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-stable
namespace: production
spec:
replicas: 9
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
track: stable
spec:
containers:
- name: api
image: my-api:v1
---
# Deployment canary (v2) — 1 Pod = ~10% traffic
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-canary
namespace: production
spec:
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
track: canary
spec:
containers:
- name: api
image: my-api:v2
---
# Service memilih SEMUA Pod berlabel app=api (stable + canary)
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
selector:
app: api # ← tidak ada filter by track → semua Pod masuk
ports:
- port: 80
targetPort: 8080
# Progress canary: naikkan porsi v2
# 10% → 30%: ubah replicas canary 1 → 3, stable 9 → 7
kubectl scale deployment api-canary --replicas=3 -n production
kubectl scale deployment api-stable --replicas=7 -n production
# 50%: canary=5, stable=5
kubectl scale deployment api-canary --replicas=5 -n production
kubectl scale deployment api-stable --replicas=5 -n production
# 100%: canary selesai
kubectl scale deployment api-stable --replicas=0 -n production
kubectl scale deployment api-canary --replicas=10 -n production
# Rollback: kembalikan semua ke stable
kubectl scale deployment api-canary --replicas=0 -n production
kubectl scale deployment api-stable --replicas=10 -n production
Keterbatasan pendekatan ini: distribusi traffic berdasarkan jumlah Pod, bukan persentase yang tepat. Untuk 5%, kamu butuh 1 canary dari 20 total Pod.
Implementasi dengan Ingress Weight #
Beberapa Ingress Controller mendukung traffic splitting berdasarkan weight yang lebih presisi:
# NGINX Ingress: traffic splitting via annotations
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10" # 10% ke canary
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-canary-service
port:
number: 80
# Naikkan weight secara bertahap
kubectl annotate ingress api-canary -n production \
nginx.ingress.kubernetes.io/canary-weight="25" --overwrite
# Lanjut ke 50%
kubectl annotate ingress api-canary -n production \
nginx.ingress.kubernetes.io/canary-weight="50" --overwrite
# Selesai: hapus canary Ingress, update stable ke v2
kubectl delete ingress api-canary -n production
kubectl set image deployment/api-stable api=my-api:v2 -n production
Metric-Driven Canary: Argo Rollouts #
Untuk canary yang lebih sophisticated dengan analisis metrik otomatis, gunakan Argo Rollouts — controller khusus untuk progressive delivery.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: api
namespace: production
spec:
replicas: 10
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: my-api:v2
strategy:
canary:
canaryService: api-canary-svc # Service untuk Pod canary
stableService: api-stable-svc # Service untuk Pod stable
trafficRouting:
nginx:
stableIngress: api-ingress
steps:
- setWeight: 5 # 5% traffic ke canary
- pause: {duration: 10m} # tunggu 10 menit
- analysis: # analisis metrik
templates:
- templateName: success-rate
- setWeight: 25
- pause: {duration: 10m}
- analysis:
templates:
- templateName: success-rate
- setWeight: 50
- pause: {} # pause manual — perlu approval
- setWeight: 100
---
# AnalysisTemplate — definisikan metrik yang dianalisis
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
metrics:
- name: success-rate
interval: 1m
successCondition: result[0] >= 0.95 # harus ≥ 95% success rate
failureLimit: 3
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(http_requests_total{
deployment="api",
status!~"5.."
}[5m])) /
sum(rate(http_requests_total{
deployment="api"
}[5m]))
Jika success rate turun di bawah 95% selama analisis, Argo Rollouts otomatis menghentikan canary dan rollback ke stable.
Metric yang Dipantau Selama Canary #
Metrik wajib:
→ Error rate: persentase response 5xx
→ Latensi: p99 response time (bukan hanya average)
→ Availability: apakah Pod healthy dan menerima traffic
Metrik tambahan tergantung aplikasi:
→ Business metrics: conversion rate, checkout success rate
→ Downstream error: apakah canary menyebabkan error di service lain
→ Resource usage: apakah v2 menggunakan lebih banyak CPU/memory
→ Database load: apakah query pattern berubah drastis
Perbandingan yang berarti:
→ Bandingkan canary vs stable dalam window waktu yang sama
→ Gunakan statistical significance agar tidak misleading
→ Canary dengan traffic sangat sedikit mungkin butuh waktu lebih lama
untuk mendapat sampel yang cukup
Ringkasan #
- Canary untuk validasi bertahap dengan risiko terkontrol — ekspos versi baru ke 5-10% traffic dulu, pantau metrik, baru naik porsi; masalah hanya berdampak ke sebagian kecil pengguna.
- Implementasi sederhana via Pod replicas — rasio Pod stable:canary mengontrol distribusi traffic; mudah tapi kurang presisi dan butuh banyak Pod untuk persentase kecil.
- Ingress weight annotations untuk presisi lebih baik — NGINX Ingress mendukung
canary-weightyang bisa set ke persentase tepat tanpa bergantung pada jumlah Pod.- Argo Rollouts untuk automated progressive delivery — analisis metrik Prometheus otomatis; rollback otomatis jika success rate turun; approval gate untuk tahap tertentu.
- Pantau latensi p99, bukan hanya average — error yang mempengaruhi sebagian kecil request mungkin tidak terlihat di rata-rata tapi sangat terasa di p99.
- Durasi canary bergantung pada volume traffic — canary dengan traffic sangat sedikit butuh waktu lebih lama untuk mendapat sinyal yang statistik signifikan; jangan terburu-buru naik porsi.
← Sebelumnya: Blue/Green Deployment Berikutnya: Recreate Deployment →