Health Check #
Salah satu fitur paling kuat dari Kubernetes adalah kemampuannya untuk mendeteksi kegagalan aplikasi secara mandiri dan memulihkannya secara otomatis (self-healing), serta melakukan perutean lalu lintas jaringan (service routing) secara dinamis. Namun, agar Kubernetes dapat melakukan tindakan ini secara akurat, ia harus mengetahui kondisi kesehatan aktual dari kontainer aplikasi yang sedang berjalan. Tanpa konfigurasi pemeriksaan kesehatan (Health Check) yang tepat, Kubernetes API Server hanya menilai Pod berdasarkan status siklus hidup kontainer yang dilaporkan oleh runtime kontainer. Kontainer yang mengalami kebuntuan (deadlock), kehabisan memori internal, atau terputus dari database utama akan tetap dianggap berjalan normal (Running) oleh Kubernetes, padahal aplikasi tersebut sudah tidak dapat melayani pengguna. Artikel ini membedah secara mendalam tiga tipe pemeriksaan kesehatan (probes) di Kubernetes beserta parameter konfigurasi optimalnya.
Siklus Hidup dan Alur Evaluasi Probe #
Kubernetes Kubelet di setiap node secara aktif mengevaluasi status kontainer menggunakan tiga jenis probe. Diagram berikut menunjukkan transisi keadaan kontainer dari mulai di-schedule hingga melayani lalu lintas dan dievaluasi terus-menerus di latar belakang.
flowchart TD
StartPod["1. Pod Mulai / Container Berjalan"] -->|"Mulai Evaluasi"| StartupLoop{"2. Apakah startupProbe Dikonfigurasi?"}
StartupLoop -- "Ya" --> ExecStartup{"3. Jalankan startupProbe"}
ExecStartup -- "Gagal" --> CheckStartupLimit{"4. Apakah failureThreshold Terlampaui?"}
CheckStartupLimit -- "Ya" --> RestartStartup["5. Restart Kontainer oleh Kubelet"]
CheckStartupLimit -- "Tidak" --> WaitStartup["Tunggu periodSeconds, Uji Lagi"] --> ExecStartup
StartupLoop -- "Tidak / Sukses" --> ActiveState["6. Kontainer Aktif (Liveness & Readiness Dimulai)"]
ExecStartup -- "Sukses" --> ActiveState
subgraph LivenessLoop["Siklus Liveness (Background)"]
direction TB
ExecLive{"Jalankan livenessProbe"}
ExecLive -- "Gagal N Kali" --> RestartLive["Restart Kontainer"]
ExecLive -- "Sukses" --> WaitLive["Tunggu periodSeconds"] --> ExecLive
end
subgraph ReadinessLoop["Siklus Readiness (Background)"]
direction TB
ExecReady{"Jalankan readinessProbe"}
ExecReady -- "Gagal N Kali" --> RemoveEndpoints["Keluarkan Pod IP dari Endpoints Service"]
ExecReady -- "Sukses" --> AddEndpoints["Tambahkan Pod IP ke Endpoints Service"]
RemoveEndpoints --> WaitReady["Tunggu periodSeconds"] --> ExecReady
AddEndpoints --> WaitReady
end
ActiveState --> LivenessLoop
ActiveState --> ReadinessLoop
Tiga Jenis Probe di Kubernetes #
Kubernetes menyediakan tiga jenis probe yang memiliki tujuan operasional dan konsekuensi kegagalan yang berbeda secara fundamental:
Tiga Jenis Probe Utama di Kubernetes:
1. Startup Probe:
- Tujuan: Mengetahui kapan aplikasi selesai melakukan proses startup dan inisialisasi awal.
- Perilaku: Selama startupProbe berjalan dan belum sukses, livenessProbe dan readinessProbe dinonaktifkan.
- Konsekuensi Gagal: Kubelet mematikan kontainer dan me-restart-nya.
- Use Case: Aplikasi Java yang lambat saat inisialisasi awal, atau aplikasi yang melakukan caching data besar saat mulai.
2. Liveness Probe:
- Tujuan: Mengetahui apakah kontainer aplikasi masih hidup dan berjalan normal secara internal.
- Perilaku: Mulai berjalan setelah startupProbe sukses (atau langsung berjalan jika startupProbe ditiadakan).
- Konsekuensi Gagal: Kubelet mematikan kontainer dan me-restart-nya untuk memulihkan keadaan.
- Use Case: Mendeteksi kebuntuan proses (deadlock), infinite loop, atau memori leak kritis.
3. Readiness Probe:
- Tujuan: Mengetahui apakah aplikasi sudah siap untuk menerima dan melayani lalu lintas jaringan (traffic).
- Perilaku: Dievaluasi terus-menerus selama pod berjalan.
- Konsekuensi Gagal: Pod IP dikeluarkan dari Endpoints Service (kontainer TIDAK direstart). Lalu lintas dialihkan ke pod lain.
- Use Case: Mendeteksi kegagalan koneksi database sementara, mematikan lalu lintas saat pod melakukan graceful shutdown.
Bahaya Kegagalan Berantai (Liveness Probe Cascade Failure) #
Memahami perbedaan antara Liveness dan Readiness sangat krusial. Salah satu bencana arsitektur yang paling sering ditemui di lingkungan produksi adalah Liveness Probe Cascade Failure (kegagalan berantai).
Skenario Bencana: Database Mengalami Gangguan Sementara
[Dengan Liveness Probe Memeriksa Database (SALAH)]
1. Database overload/down selama 30 detik.
2. Liveness probe di semua Pod aplikasi mendeteksi kegagalan koneksi database.
3. Kubelet mendeteksi liveness gagal di SEMUA Pod aplikasi secara bersamaan.
4. Kubelet me-restart seluruh Pod aplikasi secara serentak.
5. Saat aplikasi baru bangun, mereka melakukan inisialisasi ulang dan membombardir database yang baru pulih dengan koneksi baru.
6. Database mengalami overload kembali karena lonjakan koneksi startup.
7. Kluster stuck dalam siklus restart massal (CrashLoopBackOff).
[Dengan Readiness Probe Memeriksa Database (BENAR)]
1. Database overload/down selama 30 detik.
2. Readiness probe di semua Pod aplikasi mendeteksi kegagalan koneksi database.
3. Kubelet mengeluarkan IP seluruh Pod dari Endpoints Service.
4. Lalu lintas pengguna dihentikan sementara (Inbound Traffic Blocked) atau diarahkan ke static fallback page.
5. Kontainer aplikasi TIDAK direstart (tetap hidup).
6. Saat database pulih, readiness probe mendeteksi koneksi OK.
7. Pod kembali dimasukkan ke Endpoints Service secara otomatis.
8. Sistem pulih secara halus tanpa siklus CrashLoopBackOff.
Aturan Emas: Jangan pernah memeriksa dependensi eksternal (seperti database, cache Redis, atau API pihak ketiga) di dalam kueri Liveness Probe. Liveness probe hanya boleh menilai kesehatan internal kontainer itu sendiri.
Macam-Macam Probe Handler #
Kubernetes mendukung empat mekanisme (handlers) untuk mengeksekusi pemeriksaan kesehatan:
1. HTTP GET Request #
Kubelet mengirimkan request HTTP GET ke IP Pod pada port dan path tertentu. Respons dengan status code >= 200 dan < 400 dianggap sukses.
livenessProbe:
httpGet:
path: /health/live
port: 8080
httpHeaders:
- name: X-Custom-Header
value: kubelet-liveness
2. TCP Socket Connection #
Kubelet mencoba membuka koneksi TCP ke port kontainer. Jika port terbuka, probe dinyatakan sukses. Sangat berguna untuk non-HTTP services seperti database (PostgreSQL/MySQL) atau Redis.
readinessProbe:
tcpSocket:
port: 5432
3. gRPC Health Check #
Mulai dari Kubernetes v1.24, Kubelet mendukung pemeriksaan kesehatan gRPC secara native mengikuti gRPC Health Checking Protocol.
livenessProbe:
grpc:
port: 50051
service: billing-service
4. Exec Command #
Kubelet mengeksekusi perintah command di dalam ruang proses kontainer. Perintah dinyatakan sukses jika mengembalikan kode keluar (exit code) bernilai 0.
readinessProbe:
exec:
command:
- pg_isready
- -h
- localhost
- -U
- postgres
Menulis Endpoint Health Check yang Tepat (Multi-Language) #
Agar pemeriksaan kesehatan dapat bekerja secara optimal, kita harus menulis rute endpoint /health/live dan /health/ready yang terpisah di dalam kode aplikasi kita.
Berikut adalah perbandingan antara penulisan logika endpoint yang salah (satu endpoint gabungan) dengan implementasi endpoint yang benar dan aman di FastAPI (Python) dan Express (Node.js).
// ANTI-PATTERN (Node.js/Express): Satu endpoint '/health' untuk liveness dan readiness,
// serta mengeksekusi kueri database yang berat pada setiap panggilan.
// Hal ini membebani CPU database karena Kubelet memanggil endpoint ini setiap 5 detik.
app.get('/health', async (req, res) => {
const dbOk = await checkDatabaseConnection();
if (!dbOk) {
return res.status(500).send("Database Down"); // JANGAN: Liveness gagal akan memicu restart loop
}
res.status(200).send("OK");
});
// ==============================================================================
// BENAR: Memisahkan Liveness dan Readiness dengan Logika Terisolasi.
// File: server.js
const express = require('express');
const app = express();
let isGracefulShutdown = false;
// Tangkap sinyal terminasi dari Kubernetes untuk memulai mode shutdown
process.on('SIGTERM', () => {
isGracefulShutdown = true;
});
// 1. Liveness Endpoint: Hanya cek kesehatan internal (Thread/Memory)
app.get('/health/live', (req, res) => {
// Cek jika terjadi internal deadlock atau konsumsi memori melewati batas kritis
if (isAppDeadlocked()) {
return res.status(500).send("Internal Deadlock Detected");
}
res.status(200).send("Alive");
});
// 2. Readiness Endpoint: Cek ketersediaan koneksi eksternal dan mode shutdown
app.get('/health/ready', async (req, res) => {
// Jika pod sedang dalam proses terminasi (graceful shutdown), matikan readiness
// agar Kubernetes Ingress/Service berhenti mengirim request baru.
if (isGracefulShutdown) {
return res.status(503).send("Shutting Down");
}
try {
// Lakukan cek koneksi database ringan (SELECT 1)
await db.raw('SELECT 1');
res.status(200).send("Ready");
} catch (error) {
res.status(503).send("Database Connection Lost");
}
});
Parameter Waktu Konfigurasi Probe #
Kita harus menyetel parameter waktu pemeriksaan secara presisi untuk menghindari deteksi lambat atau restart prematur.
# Contoh Konfigurasi Probe yang Optimal
apiVersion: apps/v1
kind: Deployment
metadata:
name: billing-deployment
namespace: production
spec:
replicas: 3
template:
spec:
containers:
- name: app
image: billing:v1.2.0
ports:
- containerPort: 8080
name: http-port
# 1. Startup Probe: Beri toleransi waktu startup hingga 5 menit
startupProbe:
httpGet:
path: /health/live
port: http-port
failureThreshold: 30 # Coba hingga 30 kali
periodSeconds: 10 # Evaluasi setiap 10 detik (30 x 10s = 300 detik/5 menit)
timeoutSeconds: 5 # Batas waktu timeout response
# 2. Liveness Probe: Mulai setelah startup sukses
livenessProbe:
httpGet:
path: /health/live
port: http-port
periodSeconds: 15 # Cek setiap 15 detik
failureThreshold: 3 # Restart setelah 3 kegagalan berturut-turut (45 detik)
timeoutSeconds: 5
successThreshold: 1 # Cukup 1 sukses untuk kembali ke status sehat
# 3. Readiness Probe: Evaluasi terus-menerus untuk service routing
readinessProbe:
httpGet:
path: /health/ready
port: http-port
periodSeconds: 5 # Cek lebih sering (5 detik) untuk respons cepat
failureThreshold: 3 # Keluarkan dari Service jika 3 kali gagal (15 detik)
timeoutSeconds: 3
successThreshold: 1 # Langsung masukkan kembali ke Service jika 1 kali sukses
Hubungan Parameter: #
initialDelaySeconds: Sejak adanyastartupProbe, parameter ini harus diatur ke0(atau ditiadakan) untuk liveness dan readiness, karenastartupProbebertindak sebagai penunda evaluasi otomatis yang dinamis.successThreshold: Nilai ini wajib diatur ke1untuk liveness probe (tidak boleh diubah), untuk memastikan pemulihan status berjalan instan.
Anti-Pattern dalam Mengelola Health Checks #
Berikut adalah kesalahan konfigurasi kritis yang sering ditemui di kluster Kubernetes:
1. Menghubungkan Liveness Probe ke API Pihak Ketiga (Third-Party API) #
Jika aplikasi kita menggunakan gateway pembayaran pihak ketiga (misalnya Stripe/Midtrans) dan API mereka mengalami downtime, menghubungkan liveness probe ke API tersebut akan membuat kontainer aplikasi kita di-restart tanpa henti. Ini adalah kesalahan logika fatal.
2. Mengatur failureThreshold Terlalu Kecil (Nilai 1) #
Mengatur failureThreshold: 1 pada readiness probe. Jika terjadi fluktuasi jaringan internal kluster (network hiccup) selama 100 milidetik saja, Pod akan langsung dikeluarkan dari Service, memicu kepanikan sistem orkestrator secara tidak perlu. Gunakan batas aman minimum 3.
3. Tidak Memiliki Batas Sumber Daya pada Endpoint Health Check #
Menulis logika pemeriksaan kesehatan yang mengeksekusi perhitungan matematika berat atau enkripsi kompleks pada endpoint /health. Endpoint ini akan dipanggil oleh Kubelet secara konstan. Jika endpoint memakan banyak resource CPU, proses pemeriksaan kesehatan itu sendiri dapat menyebabkan penurunan performa aplikasi utama.
Checklist Audit Health Check Produksi #
Pastikan seluruh Pod beban kerja Anda memenuhi standar checklist berikut sebelum dideploy ke produksi:
RANCANGAN ENDPOINT KODE:
□ Endpoint '/health/live' dan '/health/ready' dibuat secara terpisah di dalam kode.
□ Endpoint '/health/live' hanya menguji kesehatan internal (memori, deadlock).
□ Endpoint '/health/ready' menguji koneksi database utama dan status startup cache.
□ Endpoint '/health/ready' mendeteksi sinyal SIGTERM untuk mematikan status siap selama graceful shutdown.
□ Logika endpoint didesain seringkas mungkin agar tidak membebani penggunaan CPU/Memori kontainer.
KONFIGURASI MANIFEST KUBERNETES:
□ Setiap kontainer di dalam Pod dikonfigurasikan dengan livenessProbe dan readinessProbe.
□ Aplikasi dengan waktu inisialisasi awal > 30 detik menggunakan 'startupProbe'.
□ Parameter 'initialDelaySeconds' diatur ke nilai '0' jika 'startupProbe' diaktifkan.
□ Parameter 'failureThreshold' diatur minimum ke nilai '3' untuk menyaring false positive.
□ Jenis handler probe yang digunakan sesuai karakteristik aplikasi (HTTP, TCP, gRPC, Exec).
□ Parameter 'timeoutSeconds' dikonfigurasi lebih rendah dari 'periodSeconds'.
Ringkasan #
- Liveness Mengevaluasi Internal, Readiness Mengevaluasi Kesiapan — Pahami perbedaan fungsionalnya; liveness memicu restart kontainer, sedangkan readiness mengarahkan lalu lintas Service.
- Jangan Cek Database di Liveness Probe — Menghubungkan liveness probe ke database memicu bencana cascade failure saat database down; gunakan readiness probe untuk mengecek koneksi database.
- startupProbe Menggantikan Delay Statis — Gunakan startupProbe untuk menampung startup aplikasi yang lambat daripada memperpanjang parameter delay liveness secara statis.
- Aktifkan Graceful Shutdown Melalui Readiness — Pastikan endpoint readiness mendengarkan sinyal SIGTERM untuk mengeluarkan pod dari Service sebelum aplikasi dimatikan.
- Set failureThreshold Minimal 3 — Hindari pengaturan batas toleransi kegagalan bernilai 1 untuk mencegah pengeluaran pod dari lalu lintas akibat gangguan jaringan sesaat.
- Pilih Handler yang Sesuai — Manfaatkan handler native gRPC untuk aplikasi berbasis gRPC microservices untuk mendapatkan akurasi pemeriksaan tanpa jembatan HTTP/Exec.
← Sebelumnya: Grafana Dashboard Berikutnya: Anti-Pattern Observability →