Langsung ke konten
KamusNgoding
Mahir Cicd 6 menit baca

Panduan Lengkap Canary Deployment di Kubernetes

#kubernetes #canary deployment #devops #advanced #deployment

Panduan Lengkap Canary Deployment di Kubernetes

Pendahuluan

Bayangkan kamu sedang membangun platform e-commerce seperti Tokopedia atau Shopee, dan timmu baru saja selesai mengembangkan fitur pembayaran baru. Risiko meluncurkan langsung ke semua pengguna tentu sangat tinggi — satu bug kecil bisa membuat ribuan transaksi gagal. Di sinilah Canary Deployment hadir sebagai solusi.

Canary Deployment adalah strategi rilis bertahap di mana versi baru aplikasi (canary) diluncurkan hanya kepada sebagian kecil pengguna terlebih dahulu. Jika metrik menunjukkan hasil yang baik, traffic secara bertahap dipindahkan ke versi baru. Jika ada masalah, rollback dilakukan sebelum dampak meluas.

Nama ini berasal dari praktik lama penambang batu bara yang membawa burung kenari ke dalam tambang — jika kenari pingsan karena gas beracun, penambang tahu mereka harus segera keluar. Dalam dunia software, “kenari” kita adalah sekelompok kecil pengguna nyata yang memverifikasi bahwa versi baru aman sebelum diluncurkan ke semua orang.

Jika kamu sudah familiar dengan pipeline CI/CD dasar menggunakan Tutorial GitHub Actions untuk Pemula: Menjalankan Workflow Pertama Anda, artikel ini akan membawa pemahamanmu ke level berikutnya dengan implementasi deployment strategis di Kubernetes.


Prasyarat: Menyiapkan Environment Kubernetes

Sebelum mulai, pastikan environment-mu sudah siap:

  • Kubernetes cluster (lokal: minikube atau kind, atau cloud: GKE, EKS, AKS)
  • kubectl terinstal dan terkonfigurasi
  • Helm v3+ (opsional, untuk chart-based deployment)
  • Pengetahuan dasar tentang Deployment dan Service di Kubernetes

Verifikasi koneksi cluster:

kubectl cluster-info
kubectl get nodes

Buat namespace khusus untuk eksperimen ini:

kubectl create namespace canary-demo
kubectl config set-context --current --namespace=canary-demo

Strategi Canary Deployment: Manual vs. Otomatis

Ada dua pendekatan utama dalam canary deployment di Kubernetes:

AspekManual (Native K8s)Otomatis (Argo Rollouts / Flagger)
Kontrol trafficBerbasis rasio replicaBerbasis persentase presisi
Analisis metrikManual via PrometheusOtomatis dengan threshold
RollbackManualOtomatis jika metrik gagal
Kompleksitas setupRendahSedang–Tinggi
Cocok untukTim kecil, proyek awalTim besar, traffic tinggi

Untuk artikel ini, kita akan membahas keduanya dimulai dari pendekatan native Kubernetes.


Implementasi Canary Deployment dengan Service Manifest

Langkah 1: Deploy Versi Stabil (Stable)

Buat deployment versi v1 sebagai baseline:

# stable-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-stable
  labels:
    app: myapp
    version: stable
spec:
  replicas: 9
  selector:
    matchLabels:
      app: myapp
      version: stable
  template:
    metadata:
      labels:
        app: myapp
        version: stable
    spec:
      containers:
      - name: myapp
        image: myapp:v1.0.0
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

Langkah 2: Deploy Versi Canary

# canary-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-canary
  labels:
    app: myapp
    version: canary
spec:
  replicas: 1  # ~10% dari total (1 dari 10 pod)
  selector:
    matchLabels:
      app: myapp
      version: canary
  template:
    metadata:
      labels:
        app: myapp
        version: canary
    spec:
      containers:
      - name: myapp
        image: myapp:v2.0.0  # Versi baru
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

Langkah 3: Buat Service Tunggal

Service menggunakan label app: myapp tanpa memilah versi, sehingga traffic otomatis terdistribusi proporsional berdasarkan jumlah replica:

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp  # Match KEDUA deployment
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: ClusterIP
kubectl apply -f stable-deployment.yaml
kubectl apply -f canary-deployment.yaml
kubectl apply -f service.yaml

# Verifikasi distribusi pod
kubectl get pods -l app=myapp --show-labels

Contoh output yang diharapkan:

NAME                              READY   STATUS    LABELS
myapp-stable-7d4f8b9c6-abc12      1/1     Running   app=myapp,version=stable
myapp-stable-7d4f8b9c6-def34      1/1     Running   app=myapp,version=stable
myapp-stable-7d4f8b9c6-ghi56      1/1     Running   app=myapp,version=stable
myapp-stable-7d4f8b9c6-jkl78      1/1     Running   app=myapp,version=stable
myapp-stable-7d4f8b9c6-mno90      1/1     Running   app=myapp,version=stable
myapp-stable-7d4f8b9c6-pqr12      1/1     Running   app=myapp,version=stable
myapp-stable-7d4f8b9c6-stu34      1/1     Running   app=myapp,version=stable
myapp-stable-7d4f8b9c6-vwx56      1/1     Running   app=myapp,version=stable
myapp-stable-7d4f8b9c6-yza78      1/1     Running   app=myapp,version=stable
myapp-canary-5b8c9d7e4-bcd90      1/1     Running   app=myapp,version=canary

Dengan 9 pod stable dan 1 pod canary, sekitar 10% request akan diarahkan ke versi baru secara otomatis oleh kube-proxy.

Langkah 4: Tingkatkan Traffic ke Canary Secara Bertahap

# Setelah monitoring 30 menit — naikkan canary ke 30%
kubectl scale deployment myapp-canary --replicas=3
kubectl scale deployment myapp-stable --replicas=7

# Setelah 1 jam — naikkan ke 50%
kubectl scale deployment myapp-canary --replicas=5
kubectl scale deployment myapp-stable --replicas=5

# Full rollout — migrasi semua ke v2
kubectl scale deployment myapp-canary --replicas=10
kubectl scale deployment myapp-stable --replicas=0

Monitoring dan Analisis: Mengukur Keberhasilan Canary

Metrik kunci yang harus dipantau selama canary deployment:

# Cek error rate via log
kubectl logs -l version=canary --tail=100 | grep -i "error\|500\|panic"

# Resource usage
kubectl top pods -l app=myapp

# Describe untuk event anomali
kubectl describe deployment myapp-canary

Jika menggunakan Prometheus + Grafana, query berikut berguna untuk membandingkan error rate:

# Error rate per versi
sum(rate(http_requests_total{status=~"5..", version="canary"}[5m]))
/
sum(rate(http_requests_total{version="canary"}[5m]))

Threshold yang umum digunakan:

  • Error rate < 1% → aman dilanjutkan
  • P99 latency tidak meningkat > 20% → deployment sehat
  • CPU/Memory tidak melebihi limit → tidak ada memory leak

Automasi Rollout dan Rollback dengan Progressive Delivery

Untuk otomatisasi penuh, gunakan Argo Rollouts. Install terlebih dahulu:

kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f \
  https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

Buat Rollout manifest dengan analisis otomatis:

# argo-rollout.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: myapp-rollout
spec:
  replicas: 10
  strategy:
    canary:
      steps:
      - setWeight: 10    # 10% traffic ke canary
      - pause: {duration: 5m}
      - setWeight: 30    # 30% setelah 5 menit
      - pause: {duration: 10m}
      - setWeight: 60    # 60% setelah 10 menit
      - pause: {duration: 10m}
      - setWeight: 100   # Full rollout
      analysis:
        templates:
        - templateName: success-rate
        startingStep: 1
        args:
        - name: service-name
          value: myapp-service
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v2.0.0
        ports:
        - containerPort: 8080

Buat AnalysisTemplate untuk evaluasi otomatis:

# analysis-template.yaml
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
  - name: service-name
  metrics:
  - name: success-rate
    interval: 2m
    successCondition: result[0] >= 0.99  # 99% success rate
    failureLimit: 3
    provider:
      prometheus:
        address: http://prometheus.monitoring.svc.cluster.local:9090
        query: |
          sum(rate(http_requests_total{
            service="{{args.service-name}}",
            status!~"5.."
          }[2m])) /
          sum(rate(http_requests_total{
            service="{{args.service-name}}"
          }[2m]))
kubectl apply -f argo-rollout.yaml
kubectl apply -f analysis-template.yaml

# Monitor status rollout
kubectl argo rollouts get rollout myapp-rollout --watch

# Manual rollback jika diperlukan
kubectl argo rollouts abort myapp-rollout
kubectl argo rollouts undo myapp-rollout

Mirip dengan bagaimana Membangun Aplikasi Serverless dengan Cloudflare Workers: Tutorial Step-by-Step memungkinkan deployment tanpa downtime di edge, Argo Rollouts memberi kita mekanisme kontrol granular yang sama namun di level Kubernetes cluster.


Contoh Kasus Nyata

Jika kamu ingin membangun layanan ride-hailing seperti Gojek dengan jutaan request per hari, canary deployment bisa diimplementasikan dalam skenario ini:

Skenario: Tim pricing engine merilis algoritma surge pricing baru.

# Deploy canary hanya untuk region Jakarta
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pricing-canary-jkt
  annotations:
    deployment.region: "jakarta"
spec:
  replicas: 2
  selector:
    matchLabels:
      app: pricing-engine
      region: jakarta
      version: canary
  template:
    metadata:
      labels:
        app: pricing-engine
        region: jakarta
        version: canary
    spec:
      containers:
      - name: pricing
        image: pricing-engine:v2.1.0-surge-algo
        env:
        - name: FEATURE_FLAG_SURGE_V2
          value: "true"
EOF

Dengan pendekatan ini, hanya pengguna di Jakarta yang merasakan algoritma baru, sementara kota lain tetap menggunakan versi stabil.


Troubleshooting: Error yang Sering Muncul

Pod Canary Tidak Mendapat Traffic (Traffic Split Tidak Sesuai)

Penyebab: Label selector pada Service tidak match dengan kedua deployment, atau terjadi mismatch label antara spec.selector di Service dan metadata.labels di pod template.

Solusi:

# Verifikasi label pod yang berjalan
kubectl get pods --show-labels -l app=myapp

# Pastikan endpoint terdaftar di service
kubectl get endpoints myapp-service

# Debug selector service
kubectl describe service myapp-service | grep -A5 "Selector"

# Jika endpoint kosong, perbaiki label di deployment
kubectl patch deployment myapp-canary -p \
  '{"spec":{"template":{"metadata":{"labels":{"app":"myapp"}}}}}'

ImagePullBackOff pada Canary Pod

Penyebab: Image versi baru belum tersedia di registry, atau credentials registry tidak dikonfigurasi untuk namespace canary.

Solusi:

# Cek detail error
kubectl describe pod <nama-pod-canary>

# Buat secret registry jika belum ada
kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=YOUR_USERNAME \
  --docker-password=YOUR_PASSWORD \
  --namespace=canary-demo

# Tambahkan imagePullSecrets ke deployment
kubectl patch deployment myapp-canary -p '{
  "spec": {
    "template": {
      "spec": {
        "imagePullSecrets": [{"name": "regcred"}]
      }
    }
  }
}'

Argo Rollouts Analysis Selalu Gagal (AnalysisRun Failed)

Penyebab: Query Prometheus mengembalikan nilai NaN atau kosong karena metric belum terkumpul, atau format query tidak sesuai dengan label metric yang ada.

Solusi:

# Cek status AnalysisRun
kubectl get analysisrun
kubectl describe analysisrun <nama-analysisrun>

# Test query Prometheus secara manual
curl -g "http://prometheus:9090/api/v1/query" \
  --data-urlencode 'query=sum(rate(http_requests_total[2m]))'

# Tambahkan initialDelay agar metric sempat terkumpul
# Di AnalysisTemplate, tambahkan field berikut:
# initialDelay: 60s

Rollback Tidak Otomatis Setelah Error Threshold Terlampaui

Penyebab: failureLimit di AnalysisTemplate terlalu tinggi, atau progressDeadlineSeconds di Rollout belum dikonfigurasi.

Solusi:

# Perbaiki di AnalysisTemplate
metrics:
- name: success-rate
  failureLimit: 1       # Turunkan dari 3 ke 1
  consecutiveErrorLimit: 2
  interval: 1m

# Di Rollout spec, tambahkan:
spec:
  progressDeadlineSeconds: 600  # Timeout 10 menit
  strategy:
    canary:
      analysis:
        templates:
        - templateName: success-rate

Pertanyaan yang Sering Diajukan (FAQ)

Apa perbedaan Canary Deployment dengan Blue-Green Deployment?

Blue-Green deployment menjalankan dua environment identik (blue = lama, green = baru) dan melakukan switch traffic 0% → 100% secara instan. Canary deployment lebih gradual — traffic dipindahkan bertahap (10% → 30% → 60% → 100%), memungkinkan deteksi masalah lebih awal dengan risiko lebih kecil. Blue-Green membutuhkan dua kali resource, sementara canary lebih hemat karena hanya menambahkan sebagian kecil pod baru.

Bagaimana cara menentukan persentase awal traffic yang aman untuk canary?

Umumnya mulai dari 1–10% tergantung volume traffic dan toleransi risiko. Untuk aplikasi dengan traffic tinggi (jutaan request/jam), bahkan 1% sudah cukup untuk mendapat sampel data yang signifikan secara statistik. Untuk aplikasi dengan traffic rendah, mulai dari 20–30% agar periode monitoring lebih pendek. Faktor utama: jumlah sample yang cukup untuk analisis error rate yang valid.

Apa yang harus dipantau selama periode canary?

Fokus pada empat metrik utama: (1) Error rate — persentase request 5xx, (2) Latency P99 — waktu respons di persentil ke-99, (3) Resource utilization — CPU dan memory pod canary, dan (4) Business metrics — konversi, transaksi sukses, atau metrik bisnis spesifik aplikasimu. Jika salah satu melebihi threshold yang ditentukan, segera lakukan rollback.

Apakah canary deployment bisa digunakan untuk perubahan database schema?

Ini adalah salah satu tantangan terbesar canary deployment. Perubahan schema database harus backward compatible — versi lama dan baru harus bisa berjalan bersamaan dengan schema yang sama. Gunakan teknik expand-and-contract: pertama tambahkan kolom baru (tanpa hapus yang lama), deploy canary dan validasi selama beberapa jam, kemudian hapus kolom lama hanya setelah seluruh traffic bermigrasi penuh ke versi baru. Tools seperti Flyway atau Liquibase sangat membantu mengelola migrasi bertahap ini dengan aman dan terstruktur.

Berapa lama idealnya periode observasi sebelum menaikkan persentase canary?

Tidak ada angka pasti, namun panduan umum adalah minimal 30 menit per tahap untuk aplikasi dengan traffic sedang. Faktor yang memengaruhi: volume request (semakin tinggi, semakin cepat data terkumpul), kompleksitas fitur (fitur pembayaran butuh observasi lebih lama dari fitur tampilan), dan SLA bisnis. Untuk perubahan kritis seperti autentikasi atau transaksi finansial, pertimbangkan observasi 2–4 jam per tahap sebelum menaikkan persentase berikutnya.


Kesimpulan

Canary deployment adalah salah satu strategi paling efektif untuk merilis fitur baru dengan risiko minimal di lingkungan Kubernetes. Mulai dari pendekatan manual berbasis rasio replica hingga otomatisasi penuh dengan Argo Rollouts dan AnalysisTemplate, kamu kini memiliki toolset lengkap untuk mengimplementasikan progressive delivery di produksi. Selamat mencoba dan jangan ragu untuk bereksperimen — setiap deployment yang berhasil adalah bukti bahwa sistem yang kamu bangun semakin matang dan andal!

Artikel Terkait