Laporan pengguna biasanya hanya menyebut gejala terluar, misalnya halaman tidak terbuka atau permintaan API berakhir dengan error. Topik ini menyusun diagnosis menjadi alur pemeriksaan tiga lapisan, yaitu Pod, Service, dan Ingress, dengan pertanyaan konkret serta perintah pemeriksaan pada tiap lapisan. Setelah membacanya, gejala umum seperti ImagePullBackOff dan Connection refused dapat dihubungkan dengan penyebab yang benar pada lapisan yang tepat.
Urutan pemeriksaan dari dalam ke luar#
Tiga lapisan tersebut tersusun berlapis. Ingress meneruskan permintaan HTTP ke Service, dan Service meneruskan trafik ke Pod yang cocok dengan selector-nya. Ketergantungan ini menentukan arah diagnosis. Gejala selalu terlihat di ujung terluar, sedangkan penyebabnya sering berada di lapisan dalam, misalnya Service yang benar tetapi Pod yang belum siap. Karena itu pemeriksaan dimulai dari Pod, dilanjutkan ke Service, dan berakhir di Ingress, satu lapisan pada satu waktu.
Lapisan berikutnya hanya diperiksa apabila lapisan di bawahnya sudah sehat. Alasannya sederhana: perbaikan di lapisan dalam kadang menyelesaikan keluhan di lapisan luar tanpa mengubah satu baris konfigurasi. Diagram berikut meringkas alur tersebut beserta pertanyaan kunci pada tiap lapisan.
Lapisan Pod: container yang berjalan dan siap#
Pertanyaan pertama pada lapisan ini berbunyi: apakah fase Pod Running dan kolom READY menunjukkan 1/1? Selisih pada kolom READY menandakan kegagalan readiness probe, sehingga Pod berjalan tetapi belum dianggap melayani trafik. Pertanyaan kedua berbunyi: berapa jumlah RESTARTS dan apakah angkanya terus bertambah? Penambahan berulang menandakan container yang berakhir terus-menerus. Pertanyaan ketiga berbunyi: apa isi log container, termasuk log dari container yang berakhir sebelum restart terakhir?
# tidak-dijalankan
# memeriksa fase, kesiapan, dan jumlah restart semua Pod di namespace
kubectl get pods -n aplikasi-catatanNAME READY STATUS RESTARTS AGE
catatan-api-7d9c4b6d5f-xk2qz 1/1 Running 0 5m
laporan-bulanan-28471 0/1 Pending 0 90sKetiga pertanyaan dijawab dengan perintah yang sudah dibahas pada topik Perkakas Debugging kubectl, yaitu kubectl get pods, kubectl describe pod, dan kubectl logs. Bagian event di bawah keluaran describe biasanya langsung menyebut penyebabnya, misalnya pesan BackOff untuk container yang berulang kali berakhir atau FailedScheduling untuk Pod yang tidak kunjung dijalankan. Apabila lapisan Pod sehat dengan kolom READY penuh dan restart stabil, pemeriksaan naik ke lapisan Service.
Lapisan Service: selector dan endpoint#
Pod yang sehat belum menjamin trafik sampai kepadanya. Service memilih Pod tujuan melalui selector, yaitu sekumpulan label yang harus cocok dengan label Pod, dan alamat Pod yang terpilih dicatat pada endpoint Service. Pertanyaan pemeriksaannya berbunyi: apakah endpoint berisi alamat, apakah selector cocok dengan label Pod, dan apakah targetPort sesuai dengan port yang benar-benar dibuka aplikasi? Perintah kubectl describe service menjawab ketiganya dalam satu keluaran.
# tidak-dijalankan
# memeriksa selector, targetPort, dan endpoint Service
kubectl describe service catatan-api -n aplikasi-catatanName: catatan-api
Namespace: aplikasi-catatan
Selector: app=catatn,versi=v1
Type: ClusterIP
Port: http 80/TCP
TargetPort: 8080/TCP
Endpoints: <none>Pada keluaran di atas, Pod sehat tetapi Endpoints bernilai <none>. Kondisi ini hampir selalu berarti selector tidak cocok dengan label Pod mana pun, dan itulah kesalahan yang paling sering ditemukan pada lapisan Service.
Lapisan Ingress: host, path, dan controller#
Ingress meneruskan permintaan HTTP menurut aturan host dan path, dan penerusannya memerlukan ingress controller yang berjalan di dalam kluster. Pertanyaan pemeriksaannya berbunyi: apakah kolom ADDRESS terisi, apakah host dan path cocok dengan URL yang diminta pengguna, dan apakah backend mengarah ke Service serta port yang benar? Kolom ADDRESS yang kosong biasanya berarti ingress controller belum terpasang atau belum siap, sedangkan respons 404 atau 503 dari controller biasanya berarti aturan tidak cocok atau backend tidak sehat.
# tidak-dijalankan
# memeriksa alamat controller, aturan host, dan backend Ingress
kubectl describe ingress catatan-web -n aplikasi-catatanName: catatan-web
Namespace: aplikasi-catatan
Address: 192.168.49.2
Rules:
Host Path Backends
---- ---- --------
catatan.lab.lokal
/api catatan-api:80 (<error: endpoints "catatan-api" not found>)Pesan <error: endpoints "catatan-api" not found> pada backend bukan kesalahan aturan Ingress. Aturannya sudah benar, tetapi Service yang dituju tidak memiliki endpoint, sehingga penyebab sesungguhnya kembali ke lapisan Service. Pola seperti ini menjelaskan mengapa perbaikan sering berada di manifest Service, bukan di manifest Ingress.
Tabel gejala umum dan pemeriksaan pertamanya#
Empat gejala berikut mencakup sebagian besar laporan aplikasi yang tidak dapat diakses pada kluster kecil. Tabelnya memetakan gejala ke lapisan yang dicurigai dan pemeriksaan pertama yang paling informatif, sehingga urutan pemeriksaan tiga lapisan dapat dijalankan dengan cepat. Empat gejala tersebut tidak menutup kemungkinan penyebab lain, tetapi pemeriksaan pertamanya sudah mengarahkan penyelidikan ke lapisan yang tepat.
| Gejala | Lapisan yang dicurigai | Pemeriksaan pertama |
|---|---|---|
| ImagePullBackOff | Pod | kubectl describe pod, bagian event, baca nama image yang gagal ditarik |
| CrashLoopBackOff | Pod | kubectl logs dengan --previous untuk pesan sebelum container berakhir |
| OOMKilled | Pod | kubectl describe pod, periksa Last State beserta limit memori |
| Connection refused | Service | kubectl describe service, periksa Endpoints dan targetPort |
ImagePullBackOff dan CrashLoopBackOff hampir selalu berakar di lapisan Pod, yaitu image yang tidak dapat ditarik dan aplikasi yang berakhir segera setelah dijalankan. OOMKilled berarti container berakhir karena memorinya melebihi limit, sehingga nilai limit perlu ditinjau bersama metrik pemakaian. Connection refused berbeda karena muncul di sisi klien, tetapi penyebabnya sering berada di lapisan Service, misalnya endpoint kosong atau targetPort yang tidak sesuai dengan port aplikasi.
Diagnosis terpandu dengan data status#
Pertanyaan pada tiap lapisan dapat dijawab berurutan, dan jawabannya dapat dirangkum menjadi satu kesimpulan. Berkas berikut meniru bentuk status tiga lapisan yang ditarik dari kluster untuk satu kasus sederhana. Pod berjalan sehat, tetapi laporan pengguna menyebut aplikasi gagal diakses.
{
"kluster": "lab-catatan",
"namespace": "aplikasi-catatan",
"pod": {
"nama": "catatan-api-7d9c4b6d5f-xk2qz",
"fase": "Running",
"siap": true,
"restart": 0,
"labels": {
"app": "catatan",
"versi": "v1"
}
},
"service": {
"nama": "catatan-api",
"selector": {
"app": "catatn",
"versi": "v1"
},
"port": 80,
"targetPort": 8080,
"endpoints": []
},
"ingress": {
"nama": "catatan-web",
"host": "catatan.lab.lokal",
"alamat": "192.168.49.2",
"backendService": "catatan-api",
"backendPort": 80
}
}Skrip berikut membaca berkas tersebut dan mencetak kesimpulan tiap lapisan mengikuti urutan pemeriksaan yang sama.
import json
# membaca salinan status tiga lapisan dari berkas diagnostik.json
data = json.load(open("diagnostik.json", encoding="utf-8"))
pod, svc, ing = data["pod"], data["service"], data["ingress"]
# lapisan Pod: fase dan kesiapan container
pod_ok = pod["fase"] == "Running" and pod["siap"] and pod["restart"] == 0
print(f"Pod : {pod['nama']} fase {pod['fase']}, siap={pod['siap']}, restart {pod['restart']}")
print(" kesimpulan: " + ("sehat" if pod_ok else "perlu diperiksa lewat logs dan describe"))
# lapisan Service: kecocokan selector dengan label Pod dan isi endpoint
label_pod = pod["labels"]
selector = svc["selector"]
cocok = all(label_pod.get(k) == v for k, v in selector.items())
print(f"Service : {svc['nama']} selector {selector}, endpoint berisi {len(svc['endpoints'])} alamat")
if not cocok:
kunci_salah = [k for k, v in selector.items() if label_pod.get(k) != v]
print(f" kesimpulan: selector salah pada {kunci_salah}, trafik tidak mengalir")
elif len(svc["endpoints"]) == 0:
print(" kesimpulan: selector cocok tetapi endpoint kosong, Pod mungkin belum siap")
else:
print(" kesimpulan: trafik mengalir ke Pod yang sesuai")
# lapisan Ingress: alamat controller dan arah backend
print(f"Ingress : host {ing['host']} diarahkan ke service {ing['backendService']} port {ing['backendPort']}")
print(f" alamat controller {ing['alamat']} terisi")
if len(svc["endpoints"]) == 0:
print(" kesimpulan: rute sudah benar, tetapi tetap gagal karena Service tanpa endpoint")Pod : catatan-api-7d9c4b6d5f-xk2qz fase Running, siap=True, restart 0
kesimpulan: sehat
Service : catatan-api selector {'app': 'catatn', 'versi': 'v1'}, endpoint berisi 0 alamat
kesimpulan: selector salah pada ['app'], trafik tidak mengalir
Ingress : host catatan.lab.lokal diarahkan ke service catatan-api port 80
alamat controller 192.168.49.2 terisi
kesimpulan: rute sudah benar, tetapi tetap gagal karena Service tanpa endpointKesimpulan pada lapisan Service identik dengan temuan manual melalui kubectl describe service, yaitu selector yang berisi catatn alih-alih catatan. Perbaikannya berupa satu perubahan label pada selector, dan endpoint akan terisi kembali setelah controller Service menyaring ulang Pod yang cocok. Kasus ini juga menunjukkan nilai urutan pemeriksaan, karena rute Ingress yang sehat mengarahkan penyelidikan kembali ke lapisan Service.
Ringkasan#
- Diagnosis bergerak dari lapisan Pod ke Service lalu Ingress, dan lapisan berikutnya hanya diperiksa apabila lapisan di bawahnya sehat.
- Lapisan Pod diperiksa melalui fase, kolom READY, jumlah restart, dan log container.
- Lapisan Service diperiksa melalui kecocokan selector dengan label Pod dan isi endpoint, sedangkan lapisan Ingress diperiksa melalui alamat controller serta aturan host dan path.
- Tabel gejala umum memetakan ImagePullBackOff, CrashLoopBackOff, OOMKilled, dan Connection refused ke pemeriksaan pertama yang paling informatif.
Referensi#
- Debug Services — Kubernetes — Panduan resmi diagnosis Service, termasuk pemeriksaan endpoint dan selector.
- Debug Pods — Kubernetes — Panduan resmi diagnosis Pod yang tidak berjalan dengan benar.
- Debugging Clusters — Kubernetes — Panduan pemeriksaan kondisi kluster dan Node yang mendukung beban kerja.