Kodeloka
  1. Kodeloka
  2. Kelas Kubernetes
  3. Materi

7 · Operasi · Modul 11 dari 14

Diagnosis Masalah: Dari CrashLoopBackOff sampai Pending

Alur kerja sistematis untuk mendiagnosis pod yang bermasalah, beserta arti sebenarnya dari status-status yang paling sering muncul.

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
📌 Bagian Events adalah yang paling sering menjawab

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 codeArti
0Keluar normal — tetapi kontainer tidak boleh keluar. Biasanya perintahnya salah, misalnya proses berjalan di latar lalu shell selesai.
1Error aplikasi — periksa log
137SIGKILL — hampir selalu OOMKilled
139Segmentation fault
143SIGTERM — dimatikan dengan anggun
⚠️ Penyebab yang sering terlewat
  • 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 startupProbe untuk 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
PesanPenyebab
Insufficient cpu/memoryTidak ada node dengan kapasitas cukup untuk request-nya
node(s) had untolerated taintNode punya taint, pod tidak punya toleration
didn't match Pod's node affinityAturan affinity terlalu ketat
pod has unbound PersistentVolumeClaimsPVC belum ter-bind — periksa StorageClass
didn't match pod topology spread constraintsAturan 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 apply

Perintah 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