Urutan Diagnosis yang Selalu Berhasil
1. kubectl get pods → apa statusnya? 2. kubectl describe pod NAMA → bagian Events di bawah 3. kubectl logs NAMA → log aplikasi 4. kubectl logs NAMA --previous → log dari kontainer yang MATI 5. kubectl get events --sort-by=.lastTimestamp 6. kubectl exec -it NAMA -- sh → periksa dari dalam
Orang cenderung langsung membaca log aplikasi, padahal bagian Events di bawah keluaran describe biasanya sudah menyebutkan penyebabnya dengan jelas: gagal menarik image, tidak ada node yang cocok, volume gagal ditempelkan, probe gagal. Baca itu dulu.
CrashLoopBackOff
Artinya kontainer menyala lalu mati berulang kali, dan Kubernetes menunggu semakin lama sebelum mencoba lagi (10 detik, 20, 40, sampai 5 menit).
kubectl logs NAMA --previous # ← kunci utamanya kubectl describe pod NAMA | grep -A10 "Last State"
| Exit code | Arti |
|---|---|
| 0 | Keluar normal — tetapi kontainer tidak boleh keluar. Biasanya perintahnya salah, misalnya proses berjalan di latar lalu shell selesai. |
| 1 | Error aplikasi — periksa log |
| 137 | SIGKILL — hampir selalu OOMKilled |
| 139 | Segmentation fault |
| 143 | SIGTERM — dimatikan dengan anggun |
- Konfigurasi hilang. Aplikasi gagal menyala karena variabel lingkungan wajib tidak ada — periksa apakah ConfigMap atau Secret yang dirujuk benar-benar ada.
- Liveness probe terlalu agresif. Aplikasi butuh 40 detik untuk menyala, tetapi probe mulai memeriksa pada detik ke-10 dan membunuhnya sebelum sempat siap. Gunakan
startupProbeuntuk aplikasi yang lambat menyala. - Izin berkas. Berjalan sebagai non-root tetapi mencoba menulis ke direktori milik root.
- Dependensi belum siap. Aplikasi mati karena tidak bisa terhubung ke database saat menyala — sebaiknya aplikasi mencoba lagi alih-alih langsung menyerah.
Pending
kubectl describe pod NAMA | grep -A20 Events
| Pesan | Penyebab |
|---|---|
Insufficient cpu/memory | Tidak ada node dengan kapasitas cukup untuk request-nya |
node(s) had untolerated taint | Node punya taint, pod tidak punya toleration |
didn't match Pod's node affinity | Aturan affinity terlalu ketat |
pod has unbound PersistentVolumeClaims | PVC belum ter-bind — periksa StorageClass |
didn't match pod topology spread constraints | Aturan penyebaran tidak bisa dipenuhi |
ImagePullBackOff
kubectl describe pod NAMA | grep -i "failed to pull"
- Nama atau tag salah ketik. Penyebab paling umum, dan paling memalukan.
- Registry privat tanpa kredensial. Butuh
imagePullSecrets. - Arsitektur tidak cocok. Image arm64 di node amd64 — sering terjadi bila image dibangun di laptop Apple Silicon.
- Batas laju registry. Docker Hub membatasi tarikan anonim.
kubectl create secret docker-registry regcred \ --docker-server=registry.contoh.com \ --docker-username=USER --docker-password=PASS # lalu di spec pod: imagePullSecrets: - name: regcred
Pod Running tapi Tidak Ready
kubectl get pod NAMA -o jsonpath='{.status.conditions}' | jq
kubectl describe pod NAMA | grep -A5 Readiness
Readiness probe gagal. Periksa: apakah path dan port-nya benar? Apakah aplikasi butuh waktu lebih lama dari initialDelaySeconds? Apakah endpoint kesehatan itu sendiri memeriksa dependensi yang sedang bermasalah?
Perkakas Diagnosis Lanjutan
# Kontainer sementara di dalam pod yang sedang berjalan — # sangat berguna untuk image distroless yang tidak punya shell kubectl debug -it pod/NAMA --image=nicolaka/netshoot --target=api # Salinan pod dengan perintah diganti — berguna bila pod terus crash kubectl debug pod/NAMA -it --copy-to=debug-pod --container=api -- sh # Shell di node itu sendiri kubectl debug node/node-1 -it --image=busybox # Semua log dari sebuah Deployment sekaligus kubectl logs -l app=layanan-pesanan --all-containers --tail=200 -f # Melihat manifest lengkap termasuk field yang diisi Kubernetes kubectl get pod NAMA -o yaml # Menguji perubahan tanpa menerapkannya kubectl apply -f manifest.yaml --dry-run=server kubectl diff -f manifest.yaml
kubectl diff sebelum applyPerintah ini menampilkan persis apa yang akan berubah bila manifest diterapkan. Menjadikannya kebiasaan mencegah kejutan seperti pengurangan replika yang tidak disengaja atau perubahan yang ternyata membuat seluruh pod dibuat ulang di jam sibuk.
Ketika Node yang Bermasalah
kubectl get nodes kubectl describe node node-1 # Perhatikan bagian Conditions: # MemoryPressure True ← node kehabisan memori # DiskPressure True ← disk hampir penuh # PIDPressure True ← terlalu banyak proses # Ready False ← kubelet tidak melapor kubectl top nodes kubectl get pods -A --field-selector spec.nodeName=node-1