L
Kubernetes & CI/CD • Literally Web ID

Zero-Downtime Deployment dengan Kubernetes dan GitOps ArgoCD

⏱️ 18 menit baca • 📅 15 Oct 2026 • 👁️ 1 views
Zero-Downtime Deployment dengan Kubernetes dan GitOps ArgoCD

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap arsitektur web modern yang menuntut ketersediaan layanan 24/7/365, downtime sekecil apa pun pada aplikasi web, baik itu backend berbasis Go, Node.js, PHP-FPM, maupun layanan front-end berbasis Single Page Application (SPA), berdampak langsung terhadap kerugian finansial, reputasi merek, dan penurunan metrik SEO. Masalah klasik yang sering dihadapi oleh DevOps Engineers dan Infrastructure Architects di lingkungan enterprise adalah bagaimana cara merilis versi kode baru (deployment) tanpa menghentikan koneksi aktif dari klien, tanpa memutus aliran transaksi database (MySQL/MariaDB), serta tanpa membuat cache Redis menjadi tidak sinkron atau terhapus secara tiba-tiba.

Secara historis, deployment aplikasi web dilakukan secara manual atau menggunakan skrip shell sederhana yang mematikan proses web server (Nginx/Apache), menarik kode sumber terbaru, memperbarui dependensi, dan menghidupkan kembali layanan. Pendekatan ini menghasilkan downtime yang nyata (hard downtime), di mana pengguna akan menemui halaman HTTP 502 Bad Gateway atau HTTP 503 Service Unavailable. Di tingkat infrastruktur yang lebih modern, deployment berbasis VM dengan blue-green deployment manual sering kali memakan waktu, rawan human error, dan sulit diskalakan secara otomatis.

Dengan adopsi Kubernetes (K8s) sebagai standar orkestrasi kontainer industri, masalah downtime seharusnya dapat diatasi melalui pengelolaan siklus hidup pod yang tepat. Namun, kenyataannya banyak tim masih salah mengonfigurasi strategi rolling update, mengabaikan liveness dan readiness probe, serta melakukan deployment secara manual menggunakan perintah kubectl apply langsung dari mesin lokal atau pipeline CI/CD yang rentan terhadap drift configuration. Hal ini menyebabkan dropped connections, lonjakan latensi yang tidak wajar, hingga kegagalan propagasi DNS dan routing dari Cloudflare ke Load Balancer internal.

Untuk mengatasi hal ini secara komprehensif, kita memerlukan kombinasi antara Kubernetes Rolling Update & Probe yang presisi dengan GitOps menggunakan ArgoCD. GitOps memastikan bahwa repositori Git menjadi satu-satunya sumber kebenaran (single source of truth) untuk seluruh infrastruktur dan aplikasi, sementara ArgoCD secara otomatis menyinkronkan status aktual di klaster K8s dengan status yang diinginkan (desired state) di Git, memfasilitasi otomatisasi penuh, auditibilitas tinggi, dan rollback instan.

Perbandingan Kondisi: Sebelum vs Sesudah Penerapan

Parameter Sebelum (Manual / Skrip Tradisional) Sesudah (Kubernetes + ArgoCD GitOps)
Waktu Downtime 30 detik hingga 15 menit per rilis Nol detik (Zero-Downtime)
Metode Rilis Menghentikan proses lalu menjalankan ulang Pembuatan pod baru, verifikasi probe, terminasi pod lama secara bertahap
Manajemen Konfigurasi Manual via SSH, rentan inkonsistensi lingkungan Deklaratif di Git, otomatis sinkronisasi oleh ArgoCD
Kecepatan Rollback Manual, memakan waktu pemulihan (MTTR tinggi) Otomatis via ArgoCD UI/CLI atau Git Revert (MTTR < 30 detik)
Audit Trail Tidak ada catatan terpusat yang jelas Riwayat commit Git yang transparan dan akuntabel

2. Konsep Inti & Deep Dive Arsitektur

Untuk mencapai zero-downtime deployment, kita harus memahami bagaimana lalu lintas jaringan (traffic) dirutekan dari pengguna hingga ke kode aplikasi yang berjalan di dalam kontainer. Alur ini melibatkan DNS, CDN/WAF (Cloudflare), Ingress Controller (Nginx Ingress / Traefik), Service Kubernetes, Endpoint/EndpointsSlices, hingga Pod aplikasi.

Alur Eksekusi & Data Flow (ASCII Diagram)

[ Pengguna / Browser ]
         │
         ▼ (HTTPS / HTTP/2)
[ Cloudflare CDN & WAF ]
         │
         ▼ (Proxy / SSL Termination)
[ Kubernetes Ingress Controller ]
         │
         ▼ (Cluster IP / Routing)
[ Kubernetes Service (ClusterIP) ]
         │
         ├───────► [ Pod A (v1.0 - Running & Ready) ]  <-- Menerima Traffic
         ├───────► [ Pod B (v1.1 - Initializing / Probe) ] <-- Belum Menerima Traffic
         └───────► [ Pod C (v1.1 - Ready & Serving) ]   <-- Menerima Traffic

Ketika sebuah deployment diperbarui (misalnya dari versi v1.0 ke v1.1), Kubernetes API Server menerima instruksi perubahan manifes (baik langsung atau didorong oleh ArgoCD). Berdasarkan konfigurasi rollingUpdate (maxSurge dan maxUnavailable), Kubernetes akan:

  1. Membuat Pod Baru (v1.1): Pod baru dibuat dengan spesifikasi kontainer yang diperbarui.
  2. Menjalankan Startup & Readiness Probe: Kubernetes tidak akan langsung mengarahkan lalu lintas ke pod baru sebelum probe mengembalikan status HTTP 200 OK.
  3. Mendaftarkan ke EndpointSlice: Setelah Readiness Probe sukses, pod baru ditambahkan ke daftar endpoint aktif di balik Service Kubernetes.
  4. Mengeluarkan Pod Lama (v1.0) dari EndpointSlice: Pod lama ditandai sebagai Terminating, dan Kubernetes mengirimkan sinyal SIGTERM ke proses utama di dalam kontainer.
  5. Graceful Shutdown: Aplikasi (Go/Node/PHP-FPM/Nginx) menerima SIGTERM, menghentikan penerimaan koneksi baru, menyelesaikan permintaan (request) yang sedang berjalan, lalu keluar dengan kode 0.
  6. Penghapusan Pod Lama: Setelah masa tenggara habis (terminationGracePeriodSeconds), kontainer dihentikan sepenuhnya.

ArgoCD bertindak sebagai pengawas (controller) di dalam klaster yang terus-menerus memindai repositori Git. Jika ada perubahan pada manifes YAML, ArgoCD menerapkan perubahan tersebut ke klaster Kubernetes secara otomatis atau manual (bergantung pada mode sync yang dikonfigurasi).


3. Perbandingan Komparatif / Analisis Pendekatan

Dalam membangun strategi zero-downtime, terdapat beberapa metode deployment yang umum digunakan di industri. Berikut adalah analisis mendalam mengenai trade-off, penggunaan sumber daya (CPU, RAM), dan latensi dari masing-masing pendekatan:

Strategi Deployment Kelebihan Kekurangan Konsumsi Sumber Daya Latency Impact
Rolling Update (Default) Hemat sumber daya, otomatisasi bawaan Kubernetes, bertahap. Membutuhkan konfigurasi probe yang sangat teliti; jika salah, traffic bisa masuk ke pod yang belum siap. Sedang (Membutuhkan ekstra 25%-50% resource selama proses surge). Rendah jika probe akurat; tinggi jika pod prematur menerima traffic.
Blue/Green Deployment Pembalikan instan (instant rollback), pengujian isolasi penuh pada lingkungan Green. Membutuhkan duplikasi penuh sumber daya infrastruktur (CPU & RAM melonjak 2x lipat sementara). Tinggi (100% resource tambahan selama transisi). Sangat Rendah (Peralihan router/service instan).
Canary Deployment Risiko kegagalan sangat kecil karena diuji pada sebagian kecil pengguna (misal 5%). Membutuhkan arsitektur router tingkat lanjut (Service Mesh seperti Istio/Linkerd atau Ingress dengan pembobotan). Rendah-Sedang (Bergantung pada persentase traffic canary). Minimal, dapat dioptimalkan dengan edge routing.

[!TIP] Untuk sebagian besar arsitektur web enterprise, Rolling Update dengan parameter maxSurge: 1 dan maxUnavailable: 0 adalah pilihan paling efisien secara biaya infrastruktur, asalkan dikombinasikan dengan Readiness Probe yang valid dan Graceful Shutdown di level aplikasi.


4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum mengimplementasikan konfigurasi ini, pastikan lingkungan infrastruktur Anda memenuhi spesifikasi minimum berikut:

  • Kubernetes Cluster: Versi 1.25 atau lebih tinggi (mendukung fitur API apps/v1 stabil dan manajemen terminasi tingkat lanjut).
  • ArgoCD: Versi 2.8+ terinstal di namespace argocd.
  • Ingress Controller: Nginx Ingress Controller atau Traefik yang dikonfigurasi dengan backend keep-alive yang optimal.
  • Akses CLI: kubectl dan argocd CLI terkonfigurasi dengan hak akses cluster-admin atau namespace-level yang memadai.

Verifikasi kesiapan klaster dengan menjalankan perintah berikut di terminal:

# Memeriksa versi klaster Kubernetes
kubectl version --short

# Memeriksa status pod ArgoCD di namespace argocd
kubectl get pods -n argocd

# Memeriksa ketersediaan Ingress Controller
kubectl get deployment -n ingress-nginx

5. Panduan Implementasi Langkah demi Langkah

Berikut adalah implementasi nyata dari manifes Kubernetes lengkap yang mencakup Deployment, Service, HorizontalPodAutoscaler, dan konfigurasi Rolling Update beserta Probes. Manifes ini dirancang untuk aplikasi backend web modern (misalnya layanan berbasis Go atau Node.js).

Langkah 1: Membuat Manifes Aplikasi (deployment.yaml)

Simpan kode berikut sebagai deployment.yaml. Perhatikan bagaimana parameter strategy, livenessProbe, readinessProbe, dan lifecycle didefinisikan secara eksplisit.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: enterprise-web-app
  namespace: production
  labels:
    app.kubernetes.io/name: enterprise-web-app
    app.kubernetes.io/part-of: core-infrastructure
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1       # Maksimal 1 pod tambahan di atas jumlah replicas selama update
      maxUnavailable: 0 # Tidak boleh ada pod yang mati sebelum pod baru siap (Zero Downtime)
  selector:
    matchLabels:
      app.kubernetes.io/name: enterprise-web-app
  template:
    metadata:
      labels:
        app.kubernetes.io/name: enterprise-web-app
    spec:
      terminationGracePeriodSeconds: 60 # Waktu tunggu bagi aplikasi untuk memproses sisa koneksi
      containers:
      - name: web-backend
        image: registry.internal.corp/repo/web-backend:v1.0.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
          name: http
        resources:
          limits:
            cpu: "500m"
            memory: "512Mi"
          requests:
            cpu: "200m"
            memory: "256Mi"
        # Lifecycle hook untuk menangani graceful shutdown di dalam kontainer
        lifecycle:
          preStop:
            exec:
              command: ["sh", "-c", "sleep 10"]
        # Liveness Probe: Memastikan aplikasi tidak mengalami deadlock
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 10
          timeoutSeconds: 3
          failureThreshold: 3
        # Readiness Probe: Menentukan kapan pod siap menerima traffic
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 2
          successThreshold: 1
          failureThreshold: 2
        env:
        - name: APP_ENV
          value: "production"
        - name: REDIS_HOST
          value: "redis-master.production.svc.cluster.local"
        - name: DB_HOST
          value: "mariadb-cluster.production.svc.cluster.local"
---
apiVersion: v1
kind: Service
metadata:
  name: enterprise-web-app-svc
  namespace: production
  labels:
    app.kubernetes.io/name: enterprise-web-app
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app.kubernetes.io/name: enterprise-web-app

Langkah 2: Konfigurasi ArgoCD Application Manifest (argocd-app.yaml)

Manifes ini mendefinisikan bagaimana ArgoCD memantau repositori Git tempat manifes Kubernetes di atas disimpan. Simpan sebagai argocd-app.yaml.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: enterprise-web-app-gitops
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: 'https://github.com/enterprise-org/k8s-manifests.git'
    targetRevision: HEAD
    path: 'apps/production/enterprise-web-app'
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: 'production'
  syncPolicy:
    automated:
      prune: true     # Menghapus sumber daya di klaster jika dihapus dari Git
      selfHeal: true  # Memperbaiki drift jika ada perubahan manual via kubectl
    syncOptions:
      - CreateNamespace=true
      - ApplyOutOfSyncOnly=true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

Terapkan aplikasi ArgoCD ini ke klaster menggunakan perintah CLI:

kubectl apply -f argocd-app.yaml

6. Bedah Kode & Penjelasan Detail Baris Kunci

Mari kita bedah parameter paling krusial dalam konfigurasi di atas yang menjadi penentu keberhasilan zero-downtime deployment:

  1. maxUnavailable: 0 dan maxSurge: 1:

    • maxUnavailable: 0 melarang Kubernetes mematikan pod lama sebelum pod baru berhasil dibuat dan dinyatakan sehat. Ini adalah kunci utama agar kapasitas layanan tidak pernah berkurang di bawah jumlah replika yang ditentukan.
    • maxSurge: 1 memungkinkan Kubernetes membuat 1 pod ekstra di atas kapasitas normal (replicas: 4 menjadi maksimal 5 pod sementara waktu) guna menampung traffic baru selama masa transisi.
  2. readinessProbe vs livenessProbe:

    • Liveness Probe bertugas mendeteksi apakah aplikasi mengalami deadlock atau macet total. Jika gagal, Kubernetes akan merestart kontainer. Jangan menyertakan pemeriksaan database eksternal yang lambat pada liveness probe agar pod tidak mengalami restart loop yang tidak perlu.
    • Readiness Probe bertugas mendeteksi apakah aplikasi siap melayani lalu lintas HTTP. Jika endpoint /ready mengembalikan selain status 200, Kubernetes secara otomatis mencabut pod tersebut dari EndpointSlice Service, sehingga tidak ada traffic yang masuk ke pod yang sedang warming up atau kehilangan koneksi cache Redis.
  3. lifecycle.preStop dan terminationGracePeriodSeconds: 60:

    • Saat pod dihentikan, Kubernetes mengirim SIGTERM. Namun, terkadang Ingress atau EndpointSlice membutuhkan waktu beberapa detik untuk memperbarui tabel perutean mereka. Perintah sleep 10 pada blok preStop memberikan jeda waktu agar Ingress berhenti mengirimkan request baru ke pod tersebut sebelum proses aplikasi benar-benar menerima sinyal terminasi.

7. Skenario Produksi & Studi Kasus Dunia Nyata

[!IMPORTANT] Pada lingkungan produksi dengan beban tinggi (misal 50.000 req/sec di balik Cloudflare), kegagalan memperhitungkan terminationGracePeriodSeconds akan mengakibatkan lonjakan error HTTP 502 sesaat setelah deployment dimulai.

Studi Kasus: Sebuah platform e-commerce enterprise dengan beban transaksi tinggi melakukan rilis pembaruan backend Go yang terhubung ke klaster MariaDB dan cache Redis.

  • Masalah Awal: Tanpa preStop hook, pod lama langsung mati saat menerima SIGTERM. Pada saat yang sama, Ngress controller masih mengirimkan 200 request bersamaan ke IP pod yang sudah mati tersebut, menghasilkan error Connection Refused bagi pengguna.
  • Solusi Penerapan: Dengan menerapkan konfigurasi rollingUpdate (maxUnavailable: 0), jeda preStop selama 10 detik, dan sinkronisasi otomatis via ArgoCD, proses rilis berjalan mulus di tengah lonjakan traffic flash sale. ArgoCD mendeteksi commit baru di GitHub, melakukan sinkronisasi secara otomatis, sementara Kubernetes mengganti pod satu per satu tanpa ada satu pun request pengguna yang gagal.

8. Common Pitfalls, Anti-Patterns & Solusi

  1. Anti-Pattern: Menggunakan imagePullPolicy: Always tanpa pembatasan tag versi (latest).

    • Dampak: Kubernetes akan menarik image terbaru secara acak yang dapat merusak konsistensi lingkungan dan mempersulit proses rollback di ArgoCD.
    • Solusi: Selalu gunakan tag semantik yang spesifik (misalnya v1.0.1) di dalam manifes Git.
  2. Pitfalls: Mengabaikan Koneksi Database Persisten pada Graceful Shutdown.

    • Dampak: Koneksi terbuka ke database terputus paksa, menyebabkan transaksi checkout atau kueri SQL gagal di tengah jalan.
    • Solusi: Pastikan kode aplikasi backend mendengarkan sinyal SIGTERM secara eksplisit (misalnya signal.Notify di Go atau process.on('SIGTERM') di Node.js) untuk menutup koneksi database secara tertib setelah menyelesaikan request yang sedang aktif.
  3. Anti-Pattern: Sinkronisasi Manual dengan kubectl apply di atas ArgoCD.

    • Dampak: Terjadi Configuration Drift, di mana status klaster berbeda dengan repository Git, mengakibatkan ArgoCD terus-menerus melaporkan status OutOfSync atau menimpa perubahan manual saat sinkronisasi otomatis berikutnya.
    • Solusi: Terapkan aturan ketat: Semua perubahan infrastruktur dan aplikasi wajib melalui Pull Request ke repository Git, tidak boleh ada perubahan langsung via kubectl edit atau kubectl apply di produksi.

9. Benchmark, Metrik Kinerja & Tuning Performa

Untuk memastikan konfigurasi zero-downtime berjalan sempurna di bawah tekanan, lakukan pengujian beban (load testing) menggunakan tool seperti k6 atau wrk secara berbarengan dengan eksekusi deployment ArgoCD.

Skrip Pengujian k6 (load-test.js)

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

export const options = {
  stages: [
    { duration: '2m', target: 100 }, // Ramp-up ke 100 virtual users
    { duration: '5m', target: 100 }, // Pertahankan beban selama 5 menit (lakukan deployment di fase ini)
    { duration: '1m', target: 0   }, // Ramp-down
  ],
  thresholds: {
    http_req_failed: ['rate<0.01'], // Tingkat error harus di bawah 1%
    http_req_duration: ['p(95)<250'], // 95% request harus selesai di bawah 250ms
  },
};

export default function () {
  const res = http.get('https://app.enterprise.internal/healthz');
  check(res, {
    'status is 200': (r) => r.status === 200,
  });
  sleep(1);
}

Jalankan pengujian di terminal:

k6 run load-test.js

Selama skrip k6 berjalan, lakukan pendorongan kode baru ke repositori Git dan amati metrik di ArgoCD serta Prometheus/Grafana. Pastikan metrik http_req_failed tetap berada di angka 0% selama proses Rolling Update berlangsung.


10. Checklist Penerapan Produksi & Kesimpulan

Sebelum meluncurkan arsitektur GitOps dan Zero-Downtime Deployment ini ke lingkungan produksi tingkat enterprise, pastikan Anda telah mencentang seluruh poin dalam checklist berikut:

  • Konfigurasi strategy.type diatur ke RollingUpdate dengan maxUnavailable: 0 dan maxSurge: 1.
  • Liveness Probe dan Readiness Probe telah diuji secara terpisah dan mengembalikan status HTTP yang benar.
  • Skrip aplikasi backend mendukung penanganan sinyal SIGTERM untuk Graceful Shutdown.
  • Hook preStop dikonfigurasi dengan jeda waktu yang cukup untuk membersihkan routing tabel Ingress.
  • ArgoCD diset dengan kebijakan sinkronisasi yang aman (selfHeal: true, prune: true).
  • Repositori Git dilindungi dengan aturan Branch Protection dan Pull Request Review wajib.
  • Uji beban (load test) berhasil dijalankan tanpa adanya lonjakan error 5xx saat deployment berlangsung.

Dengan mengikuti panduan komprehensif ini, Anda telah membangun fondasi infrastruktur web enterprise yang sangat tangguh, otomatis, transparan, dan yang terpenting: benar-benar bebas dari downtime (zero-downtime).

🏷️ Tags: #Devops #Kubernetes #Infrastructure #Gitops #Argocd