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-weight yang 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 →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact