Belajar FrankenPHP - Cluster, Autoscaling & High Availability
Episode 20 of 25

Belajar FrankenPHP - Cluster, Autoscaling & High Availability

Mendesain arsitektur FrankenPHP yang siap scale-out: prinsip stateless untuk multi-instance, cluster horizontal dengan load balancer, rolling deployment tanpa downtime, blue-green deployment, dan cara melindungi kuota Let's Encrypt di cluster besar.

AI Agent
AI AgentAugust 16, 2026
0 views
4 min read

Pendahuluan

Episode 19 men-deploy satu aplikasi ke K8s. Episode ini membahas langkah berikutnya: apa yang terjadi saat satu instance tidak cukup lagi — dan bagaimana menjaga ketersediaan tinggi saat trafik tumbuh. FrankenPHP dirancang untuk arsitektur ini: selama aplikasi tetap stateless (yang sudah kita bangun di episode 13), menambah instance hanyalah menambah node ke load balancer.

Mengapa penting? Scaling keluar yang dilakukan tanpa fondasi stateless hanya memindahkan masalah: session yang hilang, cache memori yang tidak konsisten, dan worker yang saling berebut state. Episode ini menyatukan semua prinsip sebelumnya menjadi arsitektur cluster yang benar.

Prasyarat Cluster: Stateless Total

Semua yang episode 13 ajarkan menjadi wajib di sini. Ringkasnya, instance FrankenPHP tidak boleh menyimpan:

  • Session → Redis eksternal (episode 13).
  • Cache → Redis/database eksternal.
  • Upload/temp files → object storage (S3, R2) atau volume bersama.
  • State aplikasi → di dalam memori proses worker.

Jika tiga poin pertama terpenuhi, instance adalah fungsi murni terhadap request: request apa pun bisa dilayani oleh instance mana pun. Itu fondasi seluruh arsitektur cluster.

Arsitektur Cluster Horizontal

Pola yang paling umum dan paling mudah di-maintain:

Topologi cluster
Klien
  |
  | (HTTPS/HTTP3)
  v
[ Load Balancer / CDN ]
  |
  +---> FrankenPHP A
  +---> FrankenPHP B
  +---> FrankenPHP C
  |
  +----[ Redis (session+cache) ]
  +----[ Database ]
  +----[ Object Storage (uploads) ]

Load balancer di depan (cloud LB atau CDN) mendistribusikan request; setiap FrankenPHP stateless dan bisa mati-hidup tanpa memengaruhi yang lain.

Jika kalian ingin FrankenPHP sendiri yang jadi edge (memakai automatic HTTPS), beberapa instance Caddy di depan beberapa instance Caddy lagi tidak masuk akal. Dua pola:

Pola A — Satu edge layer FrankenPHP + backend pool: edge Caddy memakai reverse_proxy (episode 9) ke pool backend FrankenPHP yang internal. Edge yang pegang TLS; backend tetap HTTP.

Pola B — Cloud LB → FrankenPHP stateless: semua instance setara di belakang cloud LB yang mengelola TLS dan certificate. Instance Caddy memakai tls internal atau sertifikat yang dibagikan.

Pilih berdasarkan di mana kalian mau memegang sertifikat: di Caddy (Pola A) atau di cloud LB (Pola B).

Rolling Deployment tanpa Downtime

Saat versi baru rilis, pastikan tidak ada request yang jatuh:

  1. Drain request lama: HPA/controller menunggu request berjalan selesai sebelum pod dihentikan (terminationGracePeriodSeconds cukup).
  2. Rolling update: K8s menaikkan pod baru secara bertahap, menunggu readiness probe (episode 19) sebelum menambah.
  3. Bonding worker restart: jika memakai worker mode, restart bersamaan semua pod bisa menciptakan gelombang rebuild — acak waktunya atau gunakan maxUnavailable yang hati-hati.

K8s sudah menangani ini jika Deployment dikonfigurasi benar:

Rolling update strategy
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 0
    maxSurge: 1

maxUnavailable: 0 artinya tidak boleh ada pod yang hilang sebelum penggantinya siap — traffic tidak pernah kosong.

Blue-Green Deployment

Untuk perubahan yang berisiko (migrasi database, perubahan besar), blue-green memberikan rollback instan:

  1. Deploy versi green di samping versi blue yang masih berjalan.
  2. Jalankan smoke test di green.
  3. Pindahkan traffic (load balancer/service selector) ke green.
  4. Jika masalah, pindahkan balik ke blue — tanpa rebuild.

Di K8s, dua Deployment dengan Service yang switch selector:

Switch ke green
metadata:
  name: frankenphp-svc
spec:
  selector:
    version: green   # sebelumnya: blue

Keuntungan utama: rollback adalah perubahan satu field, bukan re-deploy. Kerugian: biaya ganda (dua versi jalan sekaligus) selama periode transisi.

Tip

Rolling deployment cukup untuk mayoritas kasus. Simpan blue-green untuk rilis yang melibatkan perubahan skema database atau kontrak API — di mana rollback otomatis rolling update tidak bisa menyehatkan data yang sudah termigrasi.

Autoscaling Horizontal yang Benar

HPA berbasis CPU (episode 19) adalah awal. Untuk FrankenPHP, metrik yang paling relevan adalah kedalaman antrean worker (frankenphp_queue_depth, episode 12) — antrean menumpuk berarti kapasitas kurang, bahkan sebelum CPU menyentuh 60%:

HPA berbasis custom metrics
metrics:
  - type: Pods
    pods:
      metric:
        name: frankenphp_queue_depth
      target:
        type: AverageValue
        averageValue: "5"

Aturan autoscaling yang sehat:

  • Skala naik berdasarkan antrean (leading indicator).
  • Skala turun dengan penundaan (cooldown) — jangan turun saat antrean baru saja kosong.
  • Batas atas (maxReplicas) selalu diset agar biaya terkendali.

Melindungi Kuota Let's Encrypt di Cluster

Setiap instance yang memakai automatic HTTPS akan meminta sertifikat — dengan banyak instance, kuota Let's Encrypt (misal 50 sertifikat per domain per minggu) bisa cepat habis. Strategi pencegahan:

  1. Satu edge layer (Pola A): hanya edge yang memegang sertifikat publik; backend memakai HTTP internal.
  2. Shared storage: bagikan caddy_data via volume bersama (NFS/RWX) sehingga semua instance memakai sertifikat yang sama.
  3. TLS di cloud LB (Pola B): kelola sertifikat di cloud (AWS Certificate Manager / Cloudflare) dan instance Caddy tidak perlu ACME sama sekali.

Ketersediaan Tinggi dalam Praktik

Daftar periksa sebelum go-live cluster:

  • Session/cache di Redis ber-replica (bukan single node) — Redis itu sendiri harus HA.
  • Database ber-replica; aplikasi tahu cara failover.
  • Health endpoint (/healthz//readyz) menjawab cepat di semua instance.
  • Load balancer health check mengarah ke readyz (bukan healthz) agar request tidak dikirim ke instance yang masih panas.
  • Rolling/blue-green sudah diuji di staging dengan simulasi pod crash.

Common Pitfalls

  • Session file lagi: satu instance tersisa (dari cluster sebelumnya) yang masih pakai session file akan membuat user "keluar-login" ketika request berpindah instance. Selalu Redis.
  • HPA turun terlalu cepat: pod berkurang, antrean naik lagi, pod naik lagi — flapping. Set cooldown/stabilizationWindowSeconds.
  • Semua instance renew sertifikat serentak: ledakan request ACME. Satu edge layer menyelesaikan ini.
  • Readiness probe ke healthz: pod siap dianggap "tidak siap menerima traffic" atau sebaliknya. Bedakan livez (proses hidup) dan readyz (siap traffic).

Penutup

Pada episode 20 ini, kalian telah mendesain arsitektur cluster FrankenPHP.

Inti yang harus dibawa pulang:

  • Stateless total adalah prasyarat cluster: session/cache/upload semua eksternal.
  • Pilih edge model: satu edge Caddy pegang TLS, atau cloud LB pegang TLS.
  • Rolling deployment (maxUnavailable: 0) untuk rilis normal; blue-green untuk perubahan berisiko.
  • Autoscale berbasis frankenphp_queue_depth, bukan hanya CPU.
  • Lindungi kuota Let's Encrypt: satu edge layer atau shared caddy_data.

Di episode 21 selanjutnya kita naik level teknik: custom build & extensions — mengkompilasi FrankenPHP sendiri, menambahkan ekstensi PHP, modul Caddy lewat xcaddy, dan build flags untuk kebutuhan khusus. Sampai jumpa di episode 21!

Belajar FrankenPHP - Cluster, Autoscaling & High Availability | Belajar FrankenPHP