Blue/Green Deployment #

Menjamin ketersediaan layanan 100% saat meluncurkan perubahan besar pada sistem adalah salah satu pencapaian tertinggi dalam praktik DevOps. Meskipun strategi bawaan Rolling Update sangat efisien dalam penggunaan resource, strategi tersebut memaksa dua versi aplikasi berjalan secara bersamaan dalam satu pool yang sama dan memotong trafik secara bertahap. Jika terjadi bug kritis pada versi baru, proses pembatalan rilis (rollback) akan memakan waktu beberapa menit untuk memutar balik replika Pod.

Strategi Blue/Green Deployment menawarkan pendekatan yang berbeda. Dengan menyediakan dua lingkungan identik secara paralel—lingkungan Blue sebagai versi stabil aktif saat ini (v1) dan lingkungan Green sebagai versi kandidat rilis baru (v2)—kita dapat menguji aplikasi baru secara penuh di lingkungan produksi yang sesungguhnya tanpa memengaruhi pengguna aktif sama sekali. Setelah pengujian dinyatakan lulus, kita memindahkan seluruh trafik pengguna secara instan (sub-detik) ke lingkungan Green. Jika anomali muncul pasca-rilis, proses rollback hanyalah masalah satu perintah yang selesai dalam hitungan detik.


Konsep dan Arsitektur Jaringan Blue/Green #

Filosofi dasar Blue/Green adalah pemisahan fisik antara lingkungan aktif dan lingkungan siaga (standby) di dalam cluster Kubernetes. Kita tidak mencampuradukkan Pod versi v1 dan v2 di bawah satu label selector Service yang sama selama proses update.

flowchart TD
    subgraph Before["SEBELUM SWITCH (BLUE AKTIF)"]
        User1["Pengguna Nyata"] --> ProdService1["Service: api-prod-service\n(Selector: version=blue)"]
        ProdService1 --> PodBlue1a["Pod v1 (Blue)"]
        ProdService1 --> PodBlue1b["Pod v1 (Blue)"]

        QA1["Tim QA / CI Pipeline"] --> TestService1["Service: api-test-service\n(Selector: version=green)"]
        TestService1 --> PodGreen1a["Pod v2 (Green)"]
        TestService1 --> PodGreen1b["Pod v2 (Green)"]
    end

    subgraph After["SETELAH SWITCH (GREEN AKTIF)"]
        User2["Pengguna Nyata"] --> ProdService2["Service: api-prod-service\n(Selector: version=green)"]
        ProdService2 --> PodGreen2a["Pod v2 (Green)"]
        ProdService2 --> PodGreen2b["Pod v2 (Green)"]

        PodBlue2a["Pod v1 (Blue)\n(Standby - Siaga Rollback)"]
        PodBlue2b["Pod v1 (Blue)\n(Standby - Siaga Rollback)"]
    end

Perpindahan lalu lintas (cutover) dari Blue ke Green dicapai dengan mengubah rujukan pemilih label (label selector) pada Service produksi utama. Karena manipulasi API object ini bersifat atomik di dalam etcd Kubernetes, API Server akan memperbarui daftar alamat IP (EndpointSlice) secara instan. Kube-proxy di setiap node worker akan memperbarui aturan iptables/IPVS dalam hitungan milidetik, mengalihkan paket data baru ke Pod Green tanpa memutus koneksi TCP yang sedang berjalan.


Taktik Implementasi A: Service Selector (Layer 4 Routing) #

Pendekatan ini adalah cara paling sederhana dan native di Kubernetes. Kita mendefinisikan dua objek Deployment secara mandiri (satu untuk Blue, satu untuk Green) dan mengontrol perutean trafik menggunakan konfigurasi pemilih label pada objek Service.

1. Manifes Deployment Blue (Versi Aktif Saat Ini / v1) #

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-service-blue
  namespace: e-commerce
  labels:
    app: api-service
    color: blue
spec:
  replicas: 4
  selector:
    matchLabels:
      app: api-service
      color: blue
  template:
    metadata:
      labels:
        app: api-service
        color: blue # Label unik pembeda lingkungan
    spec:
      containers:
      - name: api
        image: company/api-service:v1.10.0
        ports:
        - containerPort: 8080

2. Manifes Deployment Green (Versi Baru / v2) #

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-service-green
  namespace: e-commerce
  labels:
    app: api-service
    color: green
spec:
  replicas: 4
  selector:
    matchLabels:
      app: api-service
      color: green
  template:
    metadata:
      labels:
        app: api-service
        color: green # Label unik pembeda lingkungan
    spec:
      containers:
      - name: api
        image: company/api-service:v1.11.0 # Versi baru
        ports:
        - containerPort: 8080

3. Manifes Service Produksi Utama #

apiVersion: v1
kind: Service
metadata:
  name: api-prod-service
  namespace: e-commerce
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: api-service
    color: blue # ← Mengarahkan trafik aktif ke versi Blue (v1)

Taktik Implementasi B: Ingress Controller (Layer 7 Routing) #

Jika aplikasi kita memerlukan fitur routing yang lebih kompleks (seperti pengalihan lalu lintas berdasarkan header HTTP, cookie sesi pengguna, atau TLS termination), kita harus memindahkan kendali perutean ke level Ingress Controller. Pada pola ini, kita membuat dua objek Service terpisah (satu untuk Blue, satu untuk Green) dan mengarahkan Ingress ke Service yang diinginkan.

# Service Pendukung Lingkungan Blue
apiVersion: v1
kind: Service
metadata:
  name: api-service-blue
  namespace: e-commerce
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: api-service
    color: blue
---
# Service Pendukung Lingkungan Green
apiVersion: v1
kind: Service
metadata:
  name: api-service-green
  namespace: e-commerce
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: api-service
    color: green
---
# Ingress Produksi Utama
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  namespace: e-commerce
spec:
  rules:
  - host: api.company.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service-blue # ← Ubah nilai ini ke 'api-service-green' untuk cutover
            port:
              number: 80

Panduan Langkah-Demi-Langkah (Step-by-Step Production Guide) #

Menerapkan Blue/Green secara aman di produksi membutuhkan orkestrasi yang disiplin. Berikut adalah alur proses lengkap yang biasa kita jalankan melalui pipeline CI/CD:

flowchart TD
    Start["1. Rilis Kode Baru (v2)"] --> Step1["2. Deploy Deployment 'Green' dengan replicas penuh"]
    Step1 --> Step2["3. Jalankan Smoke Test terisolasi ke Green"]
    Step2 --> Dec1{"Apakah Smoke Test<br>Lulus 100%?"}
    
    Dec1 -- "Tidak" --> RollbackEarly["4a. Hapus Deployment Green<br/>'(Rilis Dibatalkan, Blue tetap aman)'"]
    Dec1 -- "Ya" --> Step3["4b. Lakukan Cutover Trafik via Patch Service / Ingress"]
    
    Step3 --> Step4["5. Monitor Metrik Produksi (SLA, HTTP Error Rate)"]
    Step5["6. Decommission: Scale Down Deployment Blue ke 0"] <-- "Setelah Masa Stabilisasi Selesai (N Jam)" --> Step4
    
    style RollbackEarly stroke:#d32f2f,stroke-width:2px
    style Step3 stroke:#0288d1,stroke-width:2px
    style Step5 stroke:#388e3c,stroke-width:2px

Langkah 1: Deploy Versi Green #

Kirimkan manifes Deployment Green (api-service-green) ke cluster. Pastikan replika diatur ke jumlah penuh (identik dengan kapasitas Blue).

Langkah 2: Jalankan Smoke Testing Terisolasi #

Sebelum mengarahkan trafik pengguna asli, kita wajib melakukan verifikasi mandiri terhadap lingkungan Green. Kita dapat menggunakan Service pengujian (api-test-service) yang khusus mengarah ke color: green.

# Contoh menjalankan automated smoke test via Job Kubernetes
kubectl apply -f - <<EOF
apiVersion: batch/v1
kind: Job
metadata:
  name: smoke-test-green-v11
  namespace: e-commerce
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: test-runner
        image: company/smoke-tester:latest
        env:
        - name: TARGET_URL
          value: "http://api-service-green.e-commerce.svc.cluster.local/healthz"
EOF

# Tunggu hingga Job selesai dengan sukses
kubectl wait --for=condition=complete job/smoke-test-green-v11 -n e-commerce --timeout=5m

Langkah 3: Eksekusi Cutover Trafik #

Jika smoke test berhasil, jalankan perintah patch atomik pada Service produksi utama untuk memindahkan perutean trafik ke lingkungan Green.

# Perintah patch atomik selector Service menggunakan kubectl
kubectl patch service api-prod-service -n e-commerce \
  -p '{"spec":{"selector":{"app":"api-service","color":"green"}}}'

Langkah 4: Monitor Performa Pasca-Rilis #

Pantau dashboard monitoring (seperti Grafana) dengan fokus pada metrik error rate HTTP 5xx dan latensi transaksi. Jika terdeteksi anomali kritis, segera batalkan rilis dengan melakukan rollback instan:

# Rollback instan kembali ke Blue jika terjadi anomali pasca-cutover
kubectl patch service api-prod-service -n e-commerce \
  -p '{"spec":{"selector":{"app":"api-service","color":"blue"}}}'

Langkah 5: Decommission Lingkungan Lama #

Setelah masa pemantauan stabilisasi terlewati secara aman (misalnya 1-2 jam di bawah beban trafik nyata), kita dapat mematikan (scale down) Deployment Blue ke 0 replika untuk membebaskan kapasitas resource cluster.

# Scale down Deployment Blue ke nol replika untuk menghemat biaya
kubectl scale deployment api-service-blue --replicas=0 -n e-commerce

Manajemen State dan Shared Resources #

Salah satu tantangan terbesar dari strategi Blue/Green (dan alasan mengapa strategi ini tidak selalu dapat diterapkan secara instan) adalah pengelolaan State dan Shared Resources seperti Database dan User Session Cache.

1. Backward Compatibility Database #

Kedua lingkungan (Blue dan Green) biasanya berinteraksi dengan database fisik yang sama. Ketika kita mendeploy versi Green (v2), struktur database mungkin perlu mengalami migrasi skema (misalnya penambahan kolom baru).

[!CAUTION] Larangan Breaking Database Schema: Jangan pernah menerapkan perubahan skema database yang merusak kompatibilitas mundur (non-backward compatible migration) saat melakukan Blue/Green. Jika versi Green mengubah atau menghapus kolom yang masih dibaca oleh versi Blue yang sedang aktif melayani pengguna, versi Blue akan langsung crash seketika, menyebabkan downtime fatal. Selalu gunakan pola Expand-Contract Pattern untuk migrasi database.

2. User Session Affinity (Sticky Sessions) #

Jika aplikasi kita menyimpan status login atau data keranjang belanja di dalam memori kontainer (stateful memory), pemindahan trafik secara instan dari Blue ke Green akan menyebabkan seluruh pengguna aktif ter-logout secara massal dan kehilangan data transaksi mereka.

Solusi Terbaik #

  • Externalize Session State: Pindahkan session state keluar dari memori kontainer ke dalam database cache terdistribusi seperti Redis Cluster atau Memcached. Baik Pod Blue maupun Green membaca data sesi dari Redis yang sama, sehingga saat cutover terjadi, pengguna tidak merasakan transisi apa pun.
  • Ingress Session Draining: Jika menggunakan Ingress L7, konfigurasi fitur session draining (atau graceful connection shedding) yang membiarkan sesi pengguna aktif di lingkungan Blue selesai secara alami selagi mengarahkan seluruh sesi pengguna baru ke lingkungan Green.

Optimasi Biaya dan Kapasitas Cluster #

Mengoperasikan Blue/Green membutuhkan kapasitas sisa (headroom) cluster minimal 100% tambahan selama proses deployment berlangsung. Jika cluster kita sudah berjalan di atas limitasi utilisasi CPU/Memory 70%, pembuatan Deployment Green dengan replika penuh akan gagal karena keterbatasan kapasitas penjadwalan node (insufficient CPU/memory resources).

Taktik Penghematan Biaya Produksi: #

  1. Menggunakan Horizontal Pod Autoscaler (HPA): Alih-alih mengunci replika Green secara penuh sejak awal, aktifkan HPA pada Deployment Green. Mulai dengan jumlah replika minimal (misalnya 1 atau 2 Pod). Jalankan pengujian smoke test. Ketika cutover trafik dilakukan, HPA akan mendeteksi peningkatan beban pada kontainer Green dan melakukan scaling up secara otomatis sesuai kebutuhan trafik nyata.
  2. Scale Down Cepat ke 1 Replika (Bukan 0): Jika kita khawatir membutuhkan rollback cepat sewaktu-waktu di kemudian hari, alih-alih melakukan scale down Blue ke 0, kita dapat menurunkannya ke 1 replika saja. Satu Pod Blue yang standby ini tidak memakan banyak resource cluster, tetapi siap untuk langsung di-scale up secara instan jika kita harus membatalkan rilis.
  3. Cluster Autoscaler: Gunakan fitur Cluster Autoscaler di cloud provider (AWS EKS, GCP GKE). Cluster akan secara dinamis menyewa node worker virtual tambahan saat proses Blue/Green sedang berlangsung, dan secara otomatis mematikan node tambahan tersebut (downscale) setelah lingkungan Blue dinonaktifkan.

Anti-Pattern vs Solusi Terbaik #

Mari kita pelajari kesalahan umum saat menerapkan Blue/Green di lingkungan produksi beserta perbaikannya.

Anti-Pattern 1: Melakukan Cutover Trafik Tanpa Pemanasan Cache (Cold Start Anomaly) #

Melakukan pemindahan trafik 100% secara instan ke lingkungan Green yang baru saja selesai dideploy tanpa melakukan pemanasan cache (cache warming) atau pemanasan JVM (Java Virtual Machine warming). Ketika beban trafik massal masuk secara tiba-tiba, Pod Green akan mengalami kelumpuhan sementara (latency spike) karena harus memuat koneksi database baru dan mengompilasi runtime memori dari kondisi dingin (cold start).

Solusi Terbaik #

Jalankan pengujian beban (load testing) skala kecil atau skrip pemanasan (pre-warming scripts) ke Service pengujian Green sebelum mengarahkan trafik produksi utama.

# ✓ SOLUSI: Skrip pemanasan endpoint sebelum cutover dilakukan
for i in {1..100}; do 
  curl -s -o /dev/null "http://api-service-green.e-commerce.svc.cluster.local/api/bootstrap"
done
echo "✓ Pemanasan cache selesai. Aman untuk melakukan cutover."

Anti-Pattern 2: Menghapus Lingkungan Blue Segera Setelah Cutover Berhasil #

Menghapus Deployment Blue langsung setelah tombol cutover ditekan di dashboard CI/CD, demi membebaskan kapasitas cluster secepat mungkin. Jika bug tersembunyi baru muncul setelah 15 menit (misalnya kebocoran memori lambat), kita kehilangan kemampuan rollback instan dan harus melakukan deployment ulang dari awal.

Solusi Terbaik #

Terapkan Masa Stabilisasi (Graceful Coexistence Period). Pertahankan lingkungan Blue dalam kondisi standby penuh (replika utuh) selama minimal 30 hingga 60 menit pasca-cutover. Setelah dipastikan tidak ada lonjakan error log atau komplain pengguna, barulah jalankan pembersihan (cleanup) secara otomatis.


Manifes Lengkap Produksi Blue/Green #

Berikut adalah visualisasi manifes deklaratif lengkap yang mengelola siklus rilis Blue/Green secara aman di kluster:

# 1. Deployment untuk Lingkungan BLUE (Aktif)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-processor-blue
  namespace: order-system
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-processor
      color: blue
  template:
    metadata:
      labels:
        app: order-processor
        color: blue
    spec:
      containers:
      - name: processor
        image: company/order-processor:v1.5.0
        resources:
          requests:
            cpu: "200m"
            memory: "256Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"
---
# 2. Deployment untuk Lingkungan GREEN (Siaga / Versi Baru)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-processor-green
  namespace: order-system
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-processor
      color: green
  template:
    metadata:
      labels:
        app: order-processor
        color: green
    spec:
      containers:
      - name: processor
        image: company/order-processor:v1.6.0 # Versi Baru
        resources:
          requests:
            cpu: "200m"
            memory: "256Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"
---
# 3. Service Produksi Utama (Mengarahkan Trafik Pengguna Nyata)
apiVersion: v1
kind: Service
metadata:
  name: order-processor-prod
  namespace: order-system
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: order-processor
    # Untuk mengarahkan trafik ke versi baru, ganti 'color: blue' menjadi 'color: green'
    color: blue
---
# 4. Service Uji (Khusus untuk Pengujian Tim QA / CI Pipeline)
apiVersion: v1
kind: Service
metadata:
  name: order-processor-test
  namespace: order-system
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: order-processor
    # Selalu arahkan ke versi kandidat rilis baru (green) untuk smoke testing
    color: green

Checklist Audit Rilis Blue/Green #

Sebelum melakukan pemindahan trafik produksi secara instan, pastikan sistem kita memenuhi checklist kesiapan berikut:

KONSISTENSI STATE & DATABASE:
  □ Skema database yang dideploy bersifat backward-compatible dengan kode versi lama (v1).
  □ Data sesi pengguna (session state) telah dipindahkan ke database cache eksternal (Redis).
  □ Koneksi database pool pada lingkungan baru telah disesuaikan agar tidak membebani kapasitas maksimal database server.

PENGUJIAN & VALIDASI:
  □ Smoke testing otomatis ke Service pengujian (Green) telah dijalankan dan lulus 100%.
  □ Pod Green telah melalui fase pemanasan cache (pre-warming) untuk menghindari anomali cold start.
  □ Mekanisme pemantauan metrik HTTP 5xx dan latensi siap mendeteksi anomali pasca-cutover.

MANAJEMEN RESOURCE & BIAYA:
  □ Cluster memiliki kapasitas resource (headroom) minimal 100% sisa untuk menjalankan kedua Deployment secara paralel.
  □ Pipeline CI/CD dikonfigurasi untuk menurunkan replika lingkungan lama (Blue) setelah masa stabilisasi selesai.
  □ Prosedur rollback instan (perintah patch Service selector) telah diuji coba dan bekerja dalam hitungan detik.

Ringkasan #

  • Gunakan Service selector untuk cutover instan — Pemindahan trafik dari Blue ke Green dicapai dengan mengubah nilai color: blue menjadi color: green pada manifes Service produksi utama, yang berlaku sub-detik secara atomik.
  • Wajib jalankan smoke testing — Selalu manfaatkan Service pengujian internal (api-test-service) untuk memverifikasi fungsionalitas versi baru (Green) sebelum mengarahkan trafik pengguna nyata.
  • Pelihara masa stabilisasi — Jangan langsung menghapus lingkungan lama (Blue) setelah rilis; pertahankan minimal selama 30-60 menit sebagai jaminan rollback instan jika muncul bug tersembunyi.
  • Desain database backward-compatible — Terapkan pola Expand-Contract pada database agar versi Blue dan Green dapat membaca data secara bersamaan tanpa crash.
  • Pindahkan status sesi pengguna — Amankan session state ke Redis eksternal agar pengguna tidak ter-logout secara mendadak saat proses pemindahan trafik terjadi.
  • Gunakan HPA untuk efisiensi resource — Aktifkan HPA di lingkungan Green agar jumlah replika bertambah secara elastis mengikuti volume trafik nyata setelah cutover.

← Sebelumnya: Rolling Update   Berikutnya: Canary Deployment →

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