L
Kubernetes & CI/CD • Literally Web ID

Zero-Downtime Deployment Pipeline dengan Kubernetes, ArgoCD, dan GitHub Actions

⏱️ 15 menit baca • 📅 13 Oct 2026 • 👁️ 1 views
Zero-Downtime Deployment Pipeline dengan Kubernetes, ArgoCD, dan GitHub Actions

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap arsitektur web modern, ekspektasi pengguna terhadap ketersediaan layanan (availability) berada di angka 99.99% atau setara dengan maksimal 52 menit downtime per tahun. Namun, kenyataannya di lapangan, proses deployment aplikasi mikrolayanan sering kali menjadi momok yang memicu gangguan layanan. Pendekatan konvensional seperti rolling update manual via SSH, skrip Bash kustom yang rapuh, atau eksekusi pipeline CI/CD yang terputus dari state riil di kluster Kubernetes kerap kali menyisakan celah kegagalan. Botol penanganan lalu lintas (traffic throttling), hilangnya koneksi WebSocket yang sedang aktif, kegagalan koneksi basis data akibat migrasi skema yang tidak sinkron, hingga hilangnya state sesi cache Redis adalah beberapa masalah klasik yang menyebabkan degradasi performa.

Secara arsitektural, akar masalah dari kegagalan ini adalah kurangnya sinkronisasi deterministik antara Desired State di repositori Git dengan Live State di kluster Kubernetes. Tanpa adanya pengontrol berbasis Continuous Delivery seperti ArgoCD yang dipadukan dengan strategi Rolling Update yang diorkestrasi secara presisi melalui Nginx/Traefik Ingress Controller, sistem akan rentan terhadap race condition. Ketika pod baru diluncurkan sementara pod lama belum sepenuhnya siap atau belum mengakhiri koneksi aktifnya, pengguna akan mengalami error 502 Bad Gateway atau 504 Gateway Timeout.

Perbandingan antara kondisi Sebelum dan Sesudah penerapan Zero-Downtime Deployment Pipeline dapat dilihat pada matriks berikut:

Metrik / Aspek Sebelum (Manual / Pipeline Tradisional) Sesudah (Kubernetes + ArgoCD + GitHub Actions) Dampak Bisnis
Waktu Downtime 2 - 15 menit per deployment 0 detik (Zero-Downtime Mutlak) Menghilangkan potensi kehilangan pendapatan (revenue loss) saat rilis fitur.
Konsistensi State Sering terjadi drift konfigurasi antara server dan Git Otomatis selaras berkat rekonsiliasi terus-menerus ArgoCD Menghilangkan inkonsistensi lingkungan (configuration drift).
Kecepatan Rollback Memerlukan intervensi manual SSH dan build ulang 1 klik di ArgoCD UI atau otomatis via Git Revert Memperkecil Mean Time to Recovery (MTTR) secara drastis.
Keamanan Kredensial Token akses tersebar di runner CI/CD eksternal Terenkripsi di Git (SOPS/Sealed Secrets) & ditarik aman oleh ArgoCD Memenuhi standar kepatuhan keamanan enterprise (SOC2/ISO27001).

2. Konsep Inti & Deep Dive Arsitektur

Arsitektur Zero-Downtime Deployment yang handal mengandalkan tiga pilar utama: GitHub Actions sebagai orkestrator CI (Continuous Integration) untuk kompilasi, pengujian, dan publikasi artifak (Docker Image), ArgoCD sebagai pengendali CD (Continuous Deployment) berbasis GitOps, serta Kubernetes Ingress Controller yang bekerja sama dengan Readiness dan Liveness Probes untuk mengatur lalu lintas jaringan secara dinamis.

Berikut adalah representasi visual dari alur kerja (workflow) arsitektur di balik layar:

+-----------------------+       +-----------------------+       +-------------------------------------+
|    Developer Push     | ----> |    GitHub Actions     | ----> | Build Docker Image & Push to Registry|
+-----------------------+       +-----------------------+       +-------------------------------------+
                                                                                  |
                                                                                  v
+-----------------------+       +-----------------------+       +-------------------------------------+
|   Kubernetes Pods     | <---- |    ArgoCD Sync Engine | <---- | Update Image Tag in Git (Manifests) |
|  (Rolling Update 0-D) |       |  (GitOps Controller)  |       +-------------------------------------+
+-----------------------+       +-----------------------+
           ^
           |
+-----------------------------------------------------------------------------------------------------+
| Ingress Controller -> Routing Traffic HANYA ke Pod yang PASS Readiness Probe (Terminating gracefully)|
+-----------------------------------------------------------------------------------------------------+

Alur Eksekusi Data (Under the Hood)

  1. Trigger Code Commit: Developer melakukan git push ke branch utama (misal: main).
  2. CI Pipeline (GitHub Actions):
    • Menjalankan unit test dan static code analysis.
    • Melakukan build multi-arch Docker image.
    • Melakukan scan vulnerability pada image menggunakan Trivy.
    • Melakukan push image ke container registry privat (misal: Amazon ECR / Harbor).
    • Melakukan otomatisasi pembaruan tag citra kontainer pada repositori Git terpisah yang khusus menyimpan Kubernetes Manifests.
  3. CD Pipeline (ArgoCD):
    • ArgoCD secara periodik memantau (polling/webhook) repositori Kubernetes Manifests.
    • Menemukan adanya perbedaan (drift) antara Desired State di Git dan Live State di kluster.
    • Memicu proses sinkronisasi otomatis (Auto-Sync).
  4. Kubernetes Orchestration & Zero-Downtime Rollout:
    • Kubernetes menerapkan strategi RollingUpdate dengan parameter maxSurge: 25% dan maxUnavailable: 0.
    • Pod baru dibuat. Ingress Controller dan Service secara otomatis mendeteksi keberadaan pod baru.
    • Kloset koneksi lama tetap dipertahankan (connection draining) sementara pod baru menjalani Readiness Probe.
    • Hanya ketika Readiness Probe mengembalikan status HTTP 200 OK, pod baru dimasukkan ke dalam endpoints pool load balancer.
    • Pod lama menerima sinyal SIGTERM, menghentikan penerimaan koneksi baru, menyelesaikan proses antrean yang sedang berjalan, dan akhirnya di-terminate dengan aman.

3. Perbandingan Komparatif / Analisis Pendekatan

Dalam membangun sistem deployment Kubernetes, terdapat beberapa pendekatan populer yang sering dibandingkan. Berikut adalah analisis mendalam antara ArgoCD (GitOps), Helm CLI via CI/CD Pipeline, dan FluxCD.

Parameter Perbandingan ArgoCD (GitOps) Helm CLI via GitHub Actions FluxCD (GitOps) Rekomendasi Penggunaan
Model Operasional Pull-based (ArgoCD agent di dalam kluster) Push-based (CI runner mengirim perintah helm upgrade) Pull-based (Flux controller di dalam kluster) ArgoCD untuk enterprise dengan kebutuhan UI yang kaya.
Visibilitas & UI Memiliki Web UI yang sangat interaktif & real-time Tergantung pada log output CLI pada CI Minimalis (berbasis CLI & kustomisasi dashboard) ArgoCD unggul untuk kolaborasi tim lintas fungsi.
Keamanan Kredensial Kluster tidak perlu membuka port akses keluar; in-cluster agent menarik data Kredensial kluster (kubeconfig) harus disimpan di secrets GitHub Actions Serupa dengan ArgoCD, berbasis agent internal Pendekatan Pull-based (ArgoCD/Flux) lebih aman untuk perimeter firewall.
Konsumsi Sumber Daya Tinggi (membutuhkan memori lebih untuk controller & UI) Rendah (hanya menggunakan sumber daya saat pipeline berjalan) Sangat Rendah & Efisien Flux untuk lingkungan edge atau kluster dengan sumber daya terbatas.
Manajemen Kompleksitas Sangat baik untuk mengelola ribuan manifest dan ApplicationSets Cukup sulit dikontrol jika skala aplikasi mikrolayanan meningkat Sangat baik, modular dengan arsitektur controller terpisah ArgoCD untuk kompleksitas tinggi dan kemudahan audit jejak rilis.

[!TIP] Gunakan pendekatan Pull-based (ArgoCD) untuk lingkungan produksi enterprise. Pendekatan ini menghilangkan kebutuhan untuk menyimpan kredensial akses kluster yang sensitif di platform pihak ketiga seperti GitHub Actions, sehingga meminimalisir permukaan serangan (attack surface).


4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum melangkah ke tahap implementasi teknis, pastikan spesifikasi lingkungan infrastruktur telah terpenuhi secara optimal:

  • Kluster Kubernetes: Versi 1.25+ (mendukung API stabilitas tinggi dan graceful termination yang matang).
  • Infrastruktur Jaringan: Ingress Controller (Nginx Ingress Controller atau Traefik) terpasang dan dikonfigurasi dengan Load Balancer eksternal.
  • Hak Akses (RBAC): Akses administratif (cluster-admin) untuk instalasi awal ArgoCD dan Ingress Controller.
  • Alat Pendukung di Local Machine / Runner:
    • kubectl (cli Kubernetes)
    • argocd CLI
    • helm v3+
    • gh (GitHub CLI)

Verifikasi kesiapan kluster dengan menjalankan perintah diagnostik berikut:

# Verifikasi konektivitas dan versi kluster kubectl version --client
kubectl cluster-info

# Verifikasi ketersediaan node dan status kesehatan sistem
kubectl get nodes -o wide
kubectl get pods -n kube-system

5. Panduan Implementasi Langkah demi Langkah

Langkah 1: Instalasi dan Konfigurasi ArgoCD di Kluster Kubernetes

Buat namespace khusus untuk ArgoCD dan lakukan instalasi manifest resmi:

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

Verifikasi bahwa seluruh pod ArgoCD berjalan dengan normal:

kubectl get pods -n argocd -w

Dapatkan kata sandi awal untuk akun administrator (admin):

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

Akses ArgoCD UI dengan melakukan port-forwarding lokal:

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

Langkah 2: Konfigurasi Deployment Mikrolayanan dengan Rolling Update

Buat file manifest Kubernetes untuk aplikasi web backend (misal: aplikasi berbasis Go / Node.js) dengan nama k8s/deployment.yaml. Perhatikan konfigurasi strategy, readinessProbe, dan livenessProbe yang mendefinisikan zero-downtime secara absolut.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: enterprise-web-app
  namespace: production
  labels:
    app: enterprise-web-app
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: enterprise-web-app
  template:
    metadata:
      labels:
        app: enterprise-web-app
    spec:
      containers:
      - name: web-app
        image: ghcr.io/organization/enterprise-web-app:v1.0.0
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          name: http
        resources:
          limits:
            cpu: "500m"
            memory: "512Mi"
          requests:
            cpu: "200m"
            memory: "256Mi"
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 2
          successThreshold: 1
          failureThreshold: 3
        livenessProbe:
          httpGet:
            path: /livez
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 10
          timeoutSeconds: 2
          failureThreshold: 3
        lifecycle:
          preStop:
            exec:
              command: ["sh", "-c", "sleep 10"]
---
apiVersion: v1
kind: Service
metadata:
  name: enterprise-web-app-svc
  namespace: production
  labels:
    app: enterprise-web-app
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: enterprise-web-app

Langkah 3: Konfigurasi Nginx Ingress Controller

Buat file manifest k8s/ingress.yaml untuk mengarahkan lalu lintas eksternal ke layanan mikrolayanan dengan dukungan enkripsi TLS dan optimasi connection draining.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: enterprise-web-ingress
  namespace: production
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
    nginx.ingress.kubernetes.io/upstream-keepalive-connections: "100"
spec:
  tls:
  - hosts:
    - app.enterprise.internal
    secretName: enterprise-tls-secret
  rules:
  - host: app.enterprise.internal
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: enterprise-web-app-svc
            port:
              number: 80

Langkah 4: Otomasi CI dengan GitHub Actions

Buat file workflow GitHub Actions di .github/workflows/ci-cd.yaml. Workflow ini bertanggung jawab melakukan build, pengujian, publikasi gambar ke GitHub Container Registry (GHCR), serta memperbarui tag gambar secara otomatis di repositori manifests.

name: Enterprise CI/CD Pipeline

on:
  push:
    branches: [ "main" ]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      packages: write

    steps:
    - name: Checkout Source Code
      uses: actions/checkout@v4

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3

    - name: Log in to Container Registry
      uses: docker/login-action@v3
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}

    - name: Extract Metadata (Tags, Labels)
      id: meta
      uses: docker/metadata-action@v5
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
        tags: |
          type=sha,format=long
          type=raw,value=latest

    - name: Build and Push Docker Image
      uses: docker/build-push-action@v5
      with:
        context: .
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=gha
        cache-to: type=gha,mode=max

    - name: Update Kubernetes Manifest in Git
      uses: aurelien-baudet/workflow-agit@v7
      with:
        msg: "Update image tag to ${{ steps.meta.outputs.tags }}"
        path: k8s/deployment.yaml
        token: ${{ secrets.GH_PAT_UPDATE }}

Langkah 5: Definisi ArgoCD Application Manifest

Buat file manifest argocd/application.yaml untuk mendaftarkan aplikasi ke ArgoCD agar melakukan rekonsiliasi otomatis dari repositori Git.

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

6. Bedah Kode & Penjelasan Detail Baris Kunci

Mari kita bedah beberapa parameter paling krusial yang menentukan keberhasilan strategi Zero-Downtime Deployment:

  1. strategy.rollingUpdate.maxSurge: 1 dan maxUnavailable: 0:

    • maxUnavailable: 0 memastikan bahwa tidak ada satupun pod lama yang dimatikan sebelum pod baru benar-benar siap dan menerima traffic. Ini adalah fondasi utama pencegahan downtime.
    • maxSurge: 1 mengizinkan pembuatan 1 pod tambahan di atas jumlah replika yang ditentukan (misalnya dari 3 menjadi 4 pod) selama proses pembaruan berlangsung.
  2. readinessProbe vs livenessProbe:

    • readinessProbe menentukan kapan sebuah pod siap menerima lalu lintas HTTP. Jika endpoint /healthz gagal mengembalikan status 200 OK, Kubernetes secara otomatis mengeluarkan pod tersebut dari endpoint Service tanpa mematikannya.
    • livenessProbe menentukan kapan sebuah pod harus dimulai ulang (restart) total karena mengalami deadlock atau macet internal. Pastikan durasi initialDelaySeconds pada liveness probe cukup panjang agar aplikasi tidak mengalami restart prematur saat proses startup yang lambat.
  3. lifecycle.preStop.exec dengan perintah sleep 10:

    • Ketika Kubernetes menghapus sebuah pod, terjadi jeda waktu antara saat perintah SIGTERM dikirimkan ke kontainer dan saat Nginx Ingress Controller memperbarui daftar endpoints dari Service. Perintah sleep 10 memberikan waktu bagi Ingress Controller untuk mencabut pod dari daftar load balancer, sehingga tidak ada permintaan masuk yang dikirim ke pod yang sedang dalam proses penghentian.

7. Skenario Produksi & Studi Kasus Dunia Nyata

Dalam sebuah studi kasus nyata pada platform e-commerce berskala besar dengan trafik puncak mencapai 50.000 Requests Per Second (RPS), proses deployment tradisional sering kali menyebabkan lonjakan error rate hingga 4.2% akibat race condition antara penutupan koneksi PHP-FPM / Node.js worker dan pembaruan aturan routing Ingress.

Dengan menerapkan arsitektur gabungan Kubernetes RollingUpdate (maxUnavailable: 0), ArgoCD GitOps sync, dan optimasi Nginx Ingress Keepalive Connections, tim insinyur berhasil mencapai:

  • 0% Error Rate selama jendela deployment di jam sibuk.
  • Waktu propagasi rilis dari commit Git hingga pod produksi aktif memakan waktu rata-rata 48 detik.
  • Peningkatan stabilitas koneksi WebSocket karena klien mendeteksi pemutusan koneksi secara halus (graceful close) dan melakukan reconnect otomatis tanpa kehilangan sesi transaksi pembayaran (checkout session).

8. Common Pitfalls, Anti-Patterns & Solusi

[!WARNING] Anti-Pattern 1: Mengabaikan Pengaturan Resource Limits dan Requests Tanpa alokasi CPU dan Memory yang jelas, Kubernetes dapat menjadwalkan pod baru pada node yang kelebihan beban (overcommitted), menyebabkan proses startup melambat drastis dan memicu kegagalan Readiness Probe. Solusi: Selalu tetapkan batasan resources.requests dan resources.limits yang akurat berdasarkan hasil load testing.

[!WARNING] Anti-Pattern 2: Tidak Menggunakan preStop Hook Mematikan kontainer seketika saat menerima SIGTERM akan memutus koneksi HTTP yang sedang berlangsung secara paksa, menghasilkan error 502/504 bagi pengguna akhir. Solusi: Selalu implementasikan graceful shutdown di level kode aplikasi (misalnya menangkap sinyal SIGTERM di server HTTP Go/Node.js) dipadukan dengan preStop: sleep X di manifest Kubernetes.

[!WARNING] Anti-Pattern 3: Auto-Sync ArgoCD tanpa Batasan (Prune Without Safeguards) Mengaktifkan penghapusan otomatis (auto-prune) tanpa membatasi scope namespace dapat berakibat fatal jika file manifest utama terhapus secara tidak sengaja di repositori. Solusi: Terapkan SyncPolicy yang ketat, gunakan perlindungan objek penting (resource hooks), dan pisahkan hak akses repositori manifest.


9. Benchmark, Metrik Kinerja & Tuning Performa

Untuk memvalidasi bahwa pipeline zero-downtime berjalan tanpa hambatan performa, lakukan pengujian beban (load testing) menggunakan perangkat k6 atau wrk secara simultan saat proses deployment berlangsung.

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

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

export const options = {
  stages: [
    { duration: '2m', target: 500 }, // Ramp-up hingga 500 pengguna
    { duration: '5m', target: 500 }, // Pertahankan beban selama 5 menit
    { duration: '2m', target: 0 },   // Ramp-down
  ],
};

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

Metrik Kunci yang Harus Dipantau via Prometheus & Grafana:

  • kube_pod_container_status_restarts_total: Memastikan tidak ada pod yang mengalami restart tak terduga.
  • `nginx_ingress_controller_requests{status=~"5.*\
🏷️ Tags: #Nginx #High Concurrency #Performance #Sysadmin #Web Server