Anti-Pattern Production #

Insiden production jarang disebabkan oleh hal yang tidak terduga — sebagian besar berasal dari pola konfigurasi yang diketahui berbahaya tapi diabaikan karena “nanti diperbaiki” atau “belum sempat”. Artikel ini mengkompilasi anti-pattern yang paling sering muncul di cluster production yang sudah mature, beserta dampak nyata yang ditimbulkan.

Anti-Pattern 1: Tidak Ada PodDisruptionBudget #

# ANTI-PATTERN: Deployment production tanpa PDB
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 3
  # Tidak ada PodDisruptionBudget
Skenario: tim infra sedang upgrade node Kubernetes

  kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data

  Kubernetes tidak cek berapa Pod yang masih available
  Jika ketigaa Pod api kebetulan ada di node-1 dan node-2:
  → Drain node-1: evict api-pod-1 dan api-pod-2 sekaligus
  → api hanya punya 1 Pod → traffic melonjak → latensi tinggi
  → Jika Pod itu satu-satunya di namespace tersebut, bisa 0 Pod selama drain

  Insiden ini terjadi di banyak cluster production yang sudah mature
  Solusinya sepele, tapi sering terlewat:
# BENAR: selalu buat PDB untuk service production
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: api-pdb
  namespace: production
spec:
  minAvailable: 2     # minimal 2 Pod api harus available saat drain
  selector:
    matchLabels:
      app: api

Anti-Pattern 2: HPA Tanpa Resources Requests #

# ANTI-PATTERN: HPA dikonfigurasi tapi Pod tidak punya resource requests
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-hpa
spec:
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 60

# Tapi di Deployment:
spec:
  containers:
  - name: api
    # Tidak ada resources block
    # → HPA tidak bisa hitung utilization %
    # → HPA stuck, tidak scale
Konsekuensi:
  HPA tidak bisa scale karena tidak tahu "60% dari apa"
  kubectl describe hpa api-hpa:
  "Warning: missing request for cpu"

  HPA benar-benar tidak melakukan apapun
  Traffic meningkat, tidak ada scale, Pod overwhelmed
  Engineer heran kenapa HPA tidak jalan

Anti-Pattern 3: minReplicas: 1 untuk Service Kritikal #

# ANTI-PATTERN
spec:
  minReplicas: 1
  maxReplicas: 20
Konsekuensi:
  HPA scale down ke 1 Pod saat traffic rendah (misalnya: malam hari)
  Satu Pod: crash, restart, liveness probe gagal
  Kubernetes hapus Pod, buat baru → downtime selama restart (~10-60 detik)

  Lebih buruk: rolling update dengan maxUnavailable: 1
  1 Pod → update dimulai → 0 Pod tersedia → downtime

  Untuk API yang harus selalu available:
  minReplicas: 2 atau 3 (bergantung traffic pattern)
  Biaya tambahan: harga 1-2 Pod kecil di malam hari
  Manfaat: tidak ada single point of failure

Anti-Pattern 4: Backup Tidak Pernah Di-test #

ANTI-PATTERN: "Kita punya backup, kok."

  Team menyiapkan Velero backup schedule
  Database backup CronJob berjalan setiap hari
  S3 bucket penuh dengan file backup

  Tapi tidak ada yang pernah mencoba restore.

  Saat disaster terjadi:
  "File backup ada, tapi format-nya berubah sejak upgrade PostgreSQL major version"
  "Restore procedure butuh downtime lebih panjang dari yang diperkirakan"
  "Oh, ada dependency di namespace lain yang tidak ikut di-backup"
  "Credential untuk akses S3 backup sudah expired"

Konsekuensi:
  RPO dan RTO yang diasumsikan ternyata tidak tercapai
  Recovery butuh 3x lebih lama dari estimasi
  Data yang seharusnya bisa di-restore ternyata corrupt
# Jadwalkan drill restore bulanan:
# 1. Restore backup ke namespace test
velero restore create test-restore \
  --from-backup daily-production-backup \
  --namespace-mappings production:restore-test

# 2. Verifikasi aplikasi berjalan
kubectl get pods -n restore-test
kubectl exec -n restore-test -it <pod> -- curl localhost/health

# 3. Verifikasi data integrity
# 4. Dokumentasikan berapa lama proses restore
# 5. Hapus namespace test setelah selesai
kubectl delete namespace restore-test

Anti-Pattern 5: Tidak Ada Resource Requests/Limits untuk Semua Workload #

ANTI-PATTERN: production cluster dengan banyak Pod tanpa resource spec

kubectl get pods -A -o json | \
  jq '.items[] | select(.spec.containers[].resources.requests == null) |
  {pod: .metadata.name, namespace: .metadata.namespace}'

# Hasilnya: banyak Pod system dan aplikasi tanpa requests/limits

Konsekuensi:
  → BestEffort QoS: Pod ini pertama di-evict saat node pressure
  → Tidak ada jaminan resource; bisa di-kill kapan saja
  → Scheduler tidak tahu berapa resource yang dibutuhkan
  → Satu Pod yang tidak terkontrol bisa mengambil semua CPU/memory node
  → Node pressure → cascade eviction → layanan lain terganggu

Anti-Pattern 6: Single-AZ Cluster di Production #

ANTI-PATTERN: semua node di satu availability zone

  kubectl get nodes -o wide | grep ZONE
  # Semua node: ap-southeast-1a

  GKE/EKS provider maintenance di ap-southeast-1a:
  → Semua node reboot
  → Seluruh cluster down selama 5-30 menit
  → Tidak ada failover, tidak ada warning sebelumnya

  Atau lebih umum: hardware failure di satu rack di AZ tersebut
  → Multiple node down sekaligus
  → Cluster kehilangan quorum (jika node control plane terdampak)

Solusi:
  Node pool multi-AZ: ap-southeast-1a, 1b, 1c
  Biaya hampir sama (node yang sama, AZ berbeda)
  Manfaat: satu AZ down = cluster tetap berjalan

Anti-Pattern 7: Cluster yang Tidak Pernah Di-upgrade #

ANTI-PATTERN: cluster production berjalan dengan versi Kubernetes yang sudah EOL

  kubectl version
  Server Version: v1.22.17   ← EOL sejak Oktober 2022

  Kubernetes mendukung N-2 minor versions
  v1.22 tidak mendapat security patch sejak lebih dari 2 tahun

  Risiko nyata:
  → Puluhan CVE yang sudah diketahui, bisa dieksploitasi
  → Public exploit tersedia untuk vulnerability lama
  → Incompatibility dengan tool modern yang butuh API versi baru
  → "Upgrade debt" yang menumpuk mempersulit upgrade di masa depan
    (v1.22 → v1.30 butuh beberapa langkah bertahap)

Pendekatan yang benar:
  → Upgrade sekali atau dua kali per tahun, satu minor version setiap kali
  → Gunakan managed Kubernetes dengan release channel yang diaktifkan
  → Test upgrade di staging dulu sebelum production
  → Jadwalkan sebagai maintenance window regular, bukan emergency

Ringkasan #

  • PDB untuk semua service production — tanpa PDB, node drain bisa membuat seluruh service down; satu konfigurasi sederhana mencegah insiden yang sangat umum ini.
  • HPA butuh resource requests — HPA berbasis CPU tidak bisa menghitung utilization percentage jika tidak ada requests; selalu set requests sebelum mengaktifkan HPA.
  • minReplicas minimal 2 untuk service kritikal — satu Pod adalah single point of failure; rolling update dengan satu Pod menyebabkan downtime; harga minimal 1 Pod ekstra jauh lebih murah dari insiden.
  • Test restore secara regular — backup yang tidak pernah di-test tidak bisa dipercaya; jadwalkan restore drill bulanan dan ukur RTO yang sebenarnya.
  • Multi-AZ untuk production — single-AZ adalah single point of failure di level infrastruktur; biaya hampir sama dengan multi-AZ, tapi availability jauh lebih baik.
  • Upgrade Kubernetes secara regular — jangan biarkan upgrade debt menumpuk; cluster yang 2+ versi di belakang punya banyak CVE yang sudah diketahui dan upgrade-nya semakin sulit.

← Sebelumnya: Multi-Tenancy   Kembali ke Halaman Utama →

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