L
Kubernetes & CI/CD • Literally Web ID

Zero-Downtime Deployment Strategies with Kubernetes and ArgoCD

⏱️ 15 menit baca • 📅 19 Oct 2026 • 👁️ 2 views
Zero-Downtime Deployment Strategies with Kubernetes and ArgoCD

Zero-Downtime Deployment Strategies with Kubernetes and ArgoCD

1. Konteks Industri & Analisis Akar Masalah

Di lanskap infrastruktur web modern, ketersediaan tinggi (high availability) dan pengiriman fitur yang cepat (rapid feature delivery) bukan lagi sekadar kemewahan, melainkan kebutuhan bisnis yang mutlak. Dalam arsitektur web tradisional yang mengandalkan server monolitik, proses deployment aplikasi sering kali melibatkan downtime yang signifikan. Bayangkan sebuah platform e-commerce dengan arsitektur PHP-FPM di belakang Nginx atau aplikasi Go berkinerja tinggi yang mendadak harus menghentikan layanan (stop service) untuk melakukan sinkronisasi aset statis, pembaruan skema database relasional MySQL, dan restart proses backend. Saat proses rilis memakan waktu 5 hingga 15 menit, kerugian finansial yang dialami bisnis bisa mencapai angka yang masif.

Bottleneck klasik dalam operasional sistem berbasis web meliputi:

  • Sesi Pengguna Terputus: Ketika proses rilis mematikan instance server secara mendadak, koneksi HTTP keep-alive, WebSocket persisten, dan antrean job di background (Redis/RabbitMQ) terpotong secara kasar tanpa penanganan graceful termination.
  • Konfigurasi Drift: Perubahan manual pada file konfigurasi Nginx, parameter PHP.ini, atau secret database via SSH langsung ke server produksi menciptakan perbedaan keadaan (drift) antara dokumentasi infrastruktur dan kenyataan di server.
  • Human Error: Eksekusi skrip deployment manual di terminal sering berujung pada kesalahan pengetikan, salah urutan eksekusi migrasi database, atau kegagalan rollback saat bug kritis lolos ke tahap produksi.

Sebelum penerapan Kubernetes dan ArgoCD, arsitektur deployment web biasanya mengandalkan skrip Bash kustom yang di-trigger melalui Jenkins atau GitLab CI/CD, yang melakukan SSH ke beberapa virtual machine, mengunduh artefak, dan melakukan reload pada web server. Pendekatan ini rapuh dan sulit diskalakan.

Setelah adopsi Kubernetes dengan prinsip GitOps melalui ArgoCD, seluruh status infrastruktur dan aplikasi didefinisikan secara deklaratif di dalam repositori Git. Deployment tidak lagi menjadi sebuah event yang menegangkan, melainkan proses sinkronisasi otomatis yang transparan, dapat di-rollback secara instan, dan terisolasi dengan aman dari intervensi manual langsung ke cluster produksi.

2. Konsep Inti & Deep Dive Arsitektur

ArgoCD bekerja berdasarkan prinsip GitOps, di mana Git berfungsi sebagai satu-satunya sumber kebenaran (single source of truth) untuk deklarasi sistem. Arsitektur ini memisahkan proses build (pembuatan container image oleh CI pipeline seperti GitHub Actions) dari proses deployment (sinkronisasi state oleh ArgoCD ke dalam klaster Kubernetes).

+-------------------------------------------------------------+
|                        DEVELOPER                            |
+-------------------------------------------------------------+
                               |
                         Git Push Code
                               v
+-------------------------------------------------------------++
|                     GIT REPOSITORY                          |
|  +-----------------------+     +-------------------------+  |
|  | Application Source    |     | Kubernetes Manifests    |  |
|  +-----------------------+     +-------------------------+  |
+-------------------------------------------------------------+
                                         |
                           Polled / Webhook Trigger
                                         v
+-------------------------------------------------------------+
|                      ARGOCD CONTROLLER                      |
|  +-----------------------+     +-------------------------+  |
|  | Application Controller| <-> | Git Repositories        |  |
|  +-----------------------+     +-------------------------+  |
+-------------------------------------------------------------+
                                         |
                           Reconciles (kubectl apply)
                                         v
+-------------------------------------------------------------+
|                    KUBERNETES CLUSTER                       |
|  +-------------------+   +--------------------+             |
|  | Ingress (Nginx)   |-> | Service (ClusterIP)|             |
|  +-------------------+   +--------------------+             |
|                                    |
|                   +----------------+----------------+
|                   v                                 v
|         +-------------------+             +-------------------+
|         | Pod (v1 - Old)    |             | Pod (v2 - New)    |
|         +-------------------+             +-------------------+
+-------------------------------------------------------------+

Alur Eksekusi di Bawah Hood:

  1. State Declaration: Developer memperbarui versi tag container image di repositori Git manifest (misal: dari v1.0.0 ke v1.1.0).
  2. Detection: ArgoCD mendeteksi perubahan tersebut baik melalui periodic polling atau webhook yang dikirimkan oleh Git provider.
  3. Comparison: ArgoCD membandingkan status aktual (live state) di dalam klaster Kubernetes dengan status yang diinginkan (desired state) yang tercatat di repositori Git.
  4. Reconciliation: Jika ditemukan perbedaan, ArgoCD melakukan sinkronisasi secara otomatis atau manual (tergantung konfigurasi sync policy), menerapkan perubahan menggunakan mekanisme deklaratif Kubernetes API.

3. Perbandingan Komparatif / Analisis Pendekatan

Untuk mencapai zero-downtime, Kubernetes menyediakan beberapa strategi deployment utama. Tabel berikut membandingkan strategi Rolling Update dan Canary Deployment secara mendalam dari berbagai parameter teknis.

Parameter Komparasi Rolling Updates (Default) Canary Deployments (Argo Rollouts) Blue/Green Deployments
Kompleksitas Implementasi Rendah (Bawaan Kubernetes) Tinggi (Membutuhkan Argo Rollouts & Ingress Controller) Sedang
Penggunaan Sumber Daya (CPU/RAM) Sedang (MaxSurge alokasi ekstra) Tinggi (Menjalankan dua versi paralel) Sangat Tinggi (Duplikasi penuh lingkungan)
Mitigasi Risiko Kegagalan Rendah-Sedang (Bergantung Liveness/Readiness probe) Sangat Tinggi (Traffic dialirkan bertahap: 5% -> 50% -> 100%) Sangat Tinggi (Instan switch, instant rollback)
Latency Overhead Minimal Rendah (Selama fase traffic splitting) Tidak ada
Skenario Ideal Aplikasi stateless standar dengan traffic stabil Aplikasi mission-critical berskala besar dengan risiko regresi tinggi Migrasi mayor database/arsitektur dengan risiko tinggi

4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum membangun alur kerja Zero-Downtime Deployment, pastikan infrastruktur pendukung Anda memenuhi spesifikasi minimum berikut:

  • Kubernetes Cluster: Versi 1.25 atau lebih baru (mendukung API stabilitas tinggi dan fitur ingress modern).
  • CLI Tools: kubectl, argocd CLI, dan helm terinstal di mesin lokal.
  • Ingress Controller: Nginx Ingress Controller atau Traefik yang dikonfigurasi dengan dukungan WebSocket dan upstream keep-alive.
  • Storage & Database: Koneksi eksternal yang mendukung migrasi backward-compatible (misalnya, migrasi skema MySQL yang tidak merusak versi sebelumnya).

Verifikasi akses klaster Anda dengan perintah:

kubectl cluster-info
kubectl get nodes

Pastikan namespace untuk ArgoCD telah tersedia:

kubectl create namespace argocd

Instal ArgoCD menggunakan manifest resmi:

kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Ambil kata sandi awal untuk akun admin ArgoCD:

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
echo

Port-forward UI ArgoCD untuk akses lokal:

kubectl port-forward svc/argocd-server -n argocd 8080:443

5. Panduan Implementasi Langkah demi Langkah

Kita akan mengimplementasikan aplikasi web berbasis Go dengan strategi Rolling Update yang disetel secara presisi menggunakan Liveness/Readiness Probe, serta integrasi ArgoCD Application Manifest.

A. Manifest Deployment Kubernetes (deployment.yaml)

[!IMPORTANT] Pastikan parameter maxSurge dan maxUnavailable diatur dengan benar pada strategi RollingUpdate untuk mencegah kekurangan sumber daya saat proses pergantian pod.

apiVersion: apps/v1
kind: Deployment
metadata: 
  name: web-backend-app
  namespace: production
  labels:
    app: web-backend
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: web-backend
  template:
    metadata:
      labels:
        app: web-backend
    spec:
      containers:
      - name: web-app
        image: registry.internal.net/apps/web-backend:v1.2.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
          name: http
        resources:
          requests:
            cpu: "250m"
            memory: "256Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
          timeoutSeconds: 2
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 3
          periodSeconds: 5
          timeoutSeconds: 2
          successThreshold: 1
          failureThreshold: 2
        lifecycle:
          preStop:
            exec:
              command: ["sh", "-c", "sleep 10"]

B. Manifest Service Kubernetes (service.yaml)

apiVersion: v1
kind: Service
metadata:
  name: web-backend-service
  namespace: production
  labels:
    app: web-backend
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: web-backend

C. Manifest ArgoCD Application (argocd-application.yaml)

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: production-web-backend
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: 'https://github.com/company/k8s-gitops-manifests.git'
    targetRevision: HEAD
    path: apps/production/web-backend
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
      - ApplyOutOfSyncOnly=true

6. Bedah Kode & Penjelasan Detail Baris Kunci

  1. maxUnavailable: 0 dan maxSurge: 1: Pengaturan ini menjamin bahwa selama proses rolling update, jumlah pod yang berjalan tidak akan pernah kurang dari jumlah yang diminta (replicas: 4). Kubernetes akan membuat 1 pod baru terlebih dahulu (maxSurge: 1), menunggu pod tersebut siap, baru kemudian mematikan 1 pod lama. Ini adalah kunci utama zero-downtime.

  2. readinessProbe vs livenessProbe:

    • Readiness Probe: Menentukan kapan sebuah pod siap menerima traffic dari Service. Jika endpoint /ready mengembalikan error HTTP (misalnya karena koneksi ke database MySQL belum sepenuhnya tersambung), Kubernetes mencabut pod dari Load Balancer secara otomatis tanpa mematikan prosesnya.
    • Liveness Probe: Menentukan kapan sebuah pod harus direstart total. Jika endpoint /healthz gagal berulang kali (failureThreshold: 3), Kubelet akan mengakhiri container dan membuat yang baru.
  3. lifecycle.preStop hook: Baris command: ["sh", "-c", "sleep 10"] sangat krusial. Ketika sebuah pod dijadwalkan untuk dihentikan, Kubernetes mengirimkan sinyal SIGTERM dan secara paralel mencabut endpoint dari Service. Namun, Nginx Ingress atau kube-proxy terkadang membutuhkan waktu beberapa detik untuk memperbarui tabel routing internal mereka. Perintah sleep 10 menahan penghentian proses aplikasi selama 10 detik agar koneksi HTTP yang sedang berjalan dapat diselesaikan dengan sempurna (graceful termination).

7. Skenario Produksi & Studi Kasus Dunia Nyata

Pada sistem skala enterprise dengan jutaan request per hari, sebuah aplikasi Node.js atau Go yang terhubung ke Redis untuk caching dan MySQL untuk persistensi data menghadapi tantangan konkurensi tinggi. Ketika deployment berjalan, lonjakan trafik (traffic spikes) bersamaan dengan proses inisialisasi aplikasi dapat membebani database.

Studi Kasus: Sebuah platform media berita mengalami lonjakan trafik hingga 50.000 request per detik saat berita breaking news dirilis. Tim teknik perlu mendorong pembaruan patch keamanan pada backend Go tanpa satupun dropped connection (HTTP 502/504).

Solusi Penerapan:

  1. Koneksi Database Pool Tuning: Di dalam aplikasi Go, parameter SetMaxOpenConns dan SetMaxIdleConns diatur secara ketat agar saat 4 pod baru dibuat bersamaan, mereka tidak membuka ribuan koneksi baru ke MySQL secara serentak yang dapat memicu connection exhaustion.
  2. Graceful Shutdown di Kode Aplikasi:
// Contoh penanganan graceful shutdown di Go
server := &http.Server{Addr: ":8080", Handler: mux}

go func() {
    if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
        log.Fatalf("HTTP server ListenAndServe: %v", err)
    }
}()

// Menunggu sinyal interupsi sistem
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutting down server...")

ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
    log.Fatalf("Server forced to shutdown: %v", err)
}
log.Println("Server exiting")
  1. ArgoCD Automated Sync: Dengan mengaktifkan selfHeal: true, jika ada operator yang secara tidak sengaja mengubah konfigurasi langsung di klaster menggunakan kubectl edit, ArgoCD secara otomatis mendeteksi drift tersebut dan mengembalikannya sesuai dengan status yang dideklarasikan di repositori Git.

8. Common Pitfalls, Anti-Patterns & Solusi

  • Anti-Pattern 1: Menggunakan Tag Image latest di Produksi Dampak: ArgoCD tidak dapat mendeteksi perubahan versi jika tag image tidak berubah, dan rollback menjadi mustahil dilakukan karena latest menunjuk ke entitas yang terus berubah. Solusi: Selalu gunakan tag berbasis semantic versioning (misal: v1.2.1) atau SHA digest dari container image.

  • Anti-Pattern 2: Mengabaikan Pengaturan Resource Request & Limits Dampak: Kubernetes penjadwal (scheduler) menempatkan pod baru pada Node yang kehabisan memori, memicu peristiwa OOM (Out of Memory) Killer yang mematikan pod secara paksa, menyebabkan error 502 Bad Gateway. Solusi: Tetapkan batasan sumber daya yang realistis berdasarkan hasil benchmark beban kerja nyata.

  • Pitfall 3: Migrasi Database yang Breaking Changes dalam Rolling Update Dampak: Ketika pod versi baru berjalan, ia mengubah skema tabel database (misalnya menghapus kolom yang masih dibutuhkan oleh pod versi lama yang sedang proses terminasi). Solusi: Terapkan prinsip Expand and Contract pattern. Pisahkan migrasi database menjadi beberapa tahap: (1) Tambahkan kolom baru tanpa menghapus yang lama, (2) Deploy aplikasi yang mendukung kolom baru, (3) Hapus kolom lama pada rilis berikutnya.

9. Benchmark, Metrik Kinerja & Tuning Performa

Untuk memvalidasi bahwa strategi zero-downtime berjalan tanpa degradasi latensi, pengujian beban (load testing) wajib dilakukan menggunakan tool seperti k6 atau wrk di lingkungan staging yang menyerupai produksi.

Skrip pengujian beban menggunakan k6 (load-test.js):

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '1m', target: 200 }, // Ramp-up ke 200 virtual users
    { duration: '3m', target: 200 }, // Pertahankan beban selama deployment
    { duration: '1m', target: 0   }, // Ramp-down
  ],
  thresholds: {
    http_req_duration: ['p(99)<250'], // 99% request harus di bawah 250ms
    http_req_failed: ['rate<0.01'],   // Error rate harus di bawah 1%
  },
};

export default function () {
  const res = http.get('http://web-backend-service.production.svc.cluster.local/healthz');
  check(res, {
    'status is 200': (r) => r.status === 200,
  });
  sleep(1);
}

Interpretasi Hasil: Selama pengujian beban di atas, jalankan pembaruan versi image aplikasi melalui Git commit. Amati grafik metrik pada Prometheus dan Grafana:

  • Request Success Rate: Harus tetap di angka 100% atau minimal 99.99%.
  • Pod CPU/Memory Utilization: Tidak mengalami lonjakan drastis yang memicu pembatasan CPU (CPU throttling).
  • Latency Spike: Pastikan latensi p(99) tidak melonjak tajam melebihi batas SLA yang ditentukan selama pergantian pod.

10. Checklist Penerapan Produksi & Kesimpulan

Sebelum meluncurkan arsitektur GitOps dan Zero-Downtime Deployment ke lingkungan produksi klaster Kubernetes Anda, pastikan seluruh item dalam checklist berikut telah terpenuhi:

  • Strategi RollingUpdate dikonfigurasi dengan maxSurge: 1 dan maxUnavailable: 0.
  • Liveness probe dan Readiness probe telah diuji secara menyeluruh dan mengarah ke endpoint yang benar (/healthz dan /ready).
  • Hook preStop dengan perintah sleep telah diterapkan untuk mendukung graceful termination.
  • Aplikasi tingkat backend mendukung penanganan sinyal SIGTERM untuk menutup koneksi database dan server HTTP secara bersih.
  • ArgoCD dikonfigurasi dengan kebijakan sinkronisasi yang aman (selfHeal dan prune diatur dengan verifikasi RBAC yang ketat).
  • Repositori Git manifest terisolasi dengan akses kontrol (Branch Protection Rules) yang mewajibkan Pull Request dan Code Review.
  • Metrik pemantauan (Prometheus/Grafana) dan sistem alert (Alertmanager) aktif memantau error rate dan status pod secara real-time.

Dengan memadukan orkestrasi kontainer Kubernetes yang tangguh dan otomatisasi deklaratif berbasis GitOps dari ArgoCD, organisasi Anda dapat mencapai efisiensi operasional yang maksimal, menghilangkan risiko kesalahan manusia, serta memastikan layanan web tetap tersedia bagi pengguna tanpa gangguan sedetik pun.

🏷️ Tags: #Nginx #High Concurrency #Performance #Sysadmin #Web Server