Belajar Kubernetes #5: Pod, Unit Terkecil Kubernetes
Pod Kubernetes adalah unit terkecil yang bisa kamu deploy di sebuah cluster. Bukan container. Ini poin yang sering bikin pemula bingung, karena di Docker kita terbiasa berpikir dalam satuan container. Di Kubernetes, container tidak pernah berdiri sendiri. Container selalu dibungkus dalam pod, dan pod itulah yang dijadwalkan ke node, diberi alamat IP, dan dikelola oleh cluster.
Di artikel ini kita akan membuat pod pertama, membedahnya dengan kubectl describe, memahami lifecycle-nya, membuktikan bahwa container dalam satu pod berbagi network, lalu sengaja membuat error ImagePullBackOff dan CrashLoopBackOff supaya kamu tahu cara mendiagnosanya. Artikel ini bagian kelima dari seri Belajar Kubernetes dari Nol, jadi kalau kamu baru masuk di tengah, mampir dulu ke halaman hub itu untuk lihat urutan lengkapnya.
Prasyarat Sebelum Praktik
Kamu butuh Minikube yang sudah jalan dan kubectl yang sudah terhubung ke cluster. Di seri ini saya memakai Minikube v1.36 dengan Kubernetes v1.33. Pastikan juga kamu sudah nyaman dengan perintah dasar seperti kubectl get dan kubectl describe. Kalau belum, baca dulu Belajar Kubernetes #4: Perintah Dasar kubectl karena semua perintah di artikel ini dibangun dari sana.
Cek dulu cluster kamu hidup:
kubectl get nodes
Output yang diharapkan:
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 10d v1.33.1
Kenapa Pod, Bukan Container, yang Jadi Unit Terkecil
Kubernetes tidak menjadwalkan container satu per satu. Kubernetes menjadwalkan pod. Satu pod adalah satu “kapsul” berisi satu atau lebih container yang selalu hidup bersama di node yang sama, berbagi alamat IP yang sama, dan bisa berbagi volume yang sama.
Kenapa perlu lapisan ekstra ini? Karena ada kasus di mana dua proses harus benar-benar nempel: dijadwalkan bareng, mati bareng, dan saling akses lewat localhost. Kalau unit terkecilnya container, Kubernetes tidak punya cara menjamin dua container selalu ada di node yang sama. Dengan pod, jaminan itu otomatis.
Kapan Satu Pod Berisi Lebih dari Satu Container
Praktiknya, mayoritas pod berisi satu container. Satu aplikasi, satu container, satu pod. Pola lebih dari satu container dipakai untuk kasus khusus yang biasa disebut sidecar, misalnya:
- Container log shipper yang membaca file log dari container utama lalu mengirimnya ke sistem logging terpusat.
- Proxy seperti Envoy yang duduk di samping aplikasi untuk mengatur trafik (ini fondasi service mesh seperti Istio).
- Container helper yang men-sync file konfigurasi atau konten secara berkala untuk dipakai container utama.
Aturan praktisnya sederhana. Kalau dua proses bisa di-scale terpisah, pisahkan ke pod berbeda. Kalau dua proses tidak ada gunanya hidup tanpa satu sama lain, baru pertimbangkan satu pod.
Praktik: Membuat Pod Nginx dengan kubectl run
Cara paling cepat membuat pod adalah perintah imperatif kubectl run:
kubectl run web-nginx --image=nginx:1.27
Output:
pod/web-nginx created
Cek statusnya:
kubectl get pods
NAME READY STATUS RESTARTS AGE
web-nginx 1/1 Running 0 15s
Kolom READY 1/1 artinya 1 dari 1 container di pod ini siap. Sekarang bedah pod-nya:
kubectl describe pod web-nginx
Outputnya panjang, tapi ada empat bagian yang paling sering saya baca saat debugging di proyek klien:
- Node: di node mana pod ini dijadwalkan. Di Minikube selalu
minikube, di cluster produksi ini penting saat ada node bermasalah. - IP: alamat IP pod. Setiap pod dapat IP sendiri di jaringan internal cluster.
- Containers: image apa yang dipakai, port apa yang dibuka, dan state container saat ini.
- Events: riwayat kejadian dari scheduler sampai container jalan. Ini tempat pertama mencari petunjuk saat pod bermasalah.
Bagian Events untuk pod yang sehat terlihat seperti ini:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 40s default-scheduler Successfully assigned default/web-nginx to minikube
Normal Pulling 40s kubelet Pulling image "nginx:1.27"
Normal Pulled 31s kubelet Successfully pulled image "nginx:1.27"
Normal Created 31s kubelet Created container: web-nginx
Normal Started 31s kubelet Started container web-nginx
Urutan ini menceritakan alur hidup pod: dijadwalkan ke node, image ditarik dari registry, container dibuat, lalu dijalankan.
Lifecycle Pod: Pending, Running, Succeeded, Failed
Setiap pod punya fase (phase) yang bisa kamu lihat di kolom STATUS. Ini fase resminya:
| Fase | Artinya |
|---|---|
| Pending | Pod sudah diterima cluster tapi container belum jalan. Biasanya sedang menunggu jadwal atau menunggu image ditarik. |
| Running | Pod sudah menempel di node dan minimal satu container sedang berjalan. |
| Succeeded | Semua container selesai dengan sukses dan tidak akan di-restart. Umum untuk pod tipe job atau task sekali jalan. |
| Failed | Semua container berhenti dan minimal satu berakhir dengan error. |
Kamu mungkin juga melihat status seperti ContainerCreating, ImagePullBackOff, atau CrashLoopBackOff di kolom STATUS. Itu bukan fase resmi, melainkan alasan detail yang ditampilkan kubectl supaya lebih informatif. ContainerCreating misalnya, muncul saat pod masih di fase Pending dan kubelet sedang menyiapkan container.
Pod Bersifat Sekali Pakai
Ini konsep yang wajib tertanam sejak awal: pod itu ephemeral, alias sekali pakai. Kalau pod mati atau dihapus, Kubernetes tidak menghidupkan pod yang sama. Tidak ada “restart pod” dalam arti pod lama bangkit lagi. Yang ada hanyalah pod baru dengan identitas baru dan IP baru. Buktikan:
kubectl delete pod web-nginx
pod "web-nginx" deleted
Jalankan kubectl get pods lagi. Kosong. Tidak ada yang menghidupkan ulang pod itu, karena kita membuatnya langsung tanpa controller. Fakta inilah yang nanti menjelaskan kenapa Deployment itu penting. Simpan dulu, kita bahas di akhir artikel.
Container dalam Satu Pod Berbagi Network dan Storage
Sekarang kita buktikan klaim tadi: semua container dalam satu pod berbagi network namespace yang sama. Artinya mereka saling akses lewat localhost tanpa perlu tahu IP siapa pun.
Buat file pod-duo.yaml berisi pod dengan dua container, nginx sebagai container utama dan sebuah sidecar berisi curl:
apiVersion: v1
kind: Pod
metadata:
name: pod-duo
spec:
containers:
- name: web
image: nginx:1.27
- name: sidecar
image: curlimages/curl:8.8.0
command: ["sleep", "infinity"]
Jangan pusing dulu dengan struktur YAML-nya, kita bedah lengkap di bagian berikutnya dari seri ini. Terapkan:
kubectl apply -f pod-duo.yaml
kubectl get pods
NAME READY STATUS RESTARTS AGE
pod-duo 2/2 Running 0 20s
Perhatikan READY 2/2. Dua container, satu pod. Sekarang eksekusi curl dari dalam container sidecar ke localhost:
kubectl exec pod-duo -c sidecar -- curl -s localhost
Output:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
Container sidecar berhasil mengakses nginx lewat localhost padahal nginx berjalan di container lain. Ini bukti dua container itu berbagi satu network namespace. Flag -c sidecar menentukan container mana yang menjalankan perintah, karena pod ini punya lebih dari satu container.
Selain network, container dalam satu pod juga bisa berbagi storage lewat volume yang di-mount ke masing-masing container. Topik volume kita dalami di bagian tersendiri, yang penting sekarang kamu tahu kemampuannya ada. Bersihkan dulu:
kubectl delete pod pod-duo
Troubleshooting: Error Pod yang Pasti Ditemui Pemula
Dua error ini hampir pasti kamu temui di minggu pertama belajar Kubernetes. Kita sengaja reproduksi supaya kamu kenal wajahnya.
ImagePullBackOff: Image Tidak Bisa Ditarik
Buat pod dengan nama image yang typo:
kubectl run salah-ketik --image=ngincx:1.27
Tunggu beberapa detik lalu cek:
kubectl get pods
NAME READY STATUS RESTARTS AGE
salah-ketik 0/1 ImagePullBackOff 0 30s
Penyebab paling umum: nama image salah ketik, tag tidak ada, atau image berada di registry privat tanpa kredensial. Cara diagnosa, baca Events:
kubectl describe pod salah-ketik
Di bagian Events akan ada baris seperti ini:
Failed to pull image "ngincx:1.27": ... repository does not exist or may require 'docker login'
Pesannya jujur: repository tidak ditemukan. Solusinya perbaiki nama image. Karena field image bisa diedit langsung, tidak perlu hapus pod:
kubectl set image pod/salah-ketik salah-ketik=nginx:1.27
Beberapa saat kemudian pod akan Running. Kata BackOff sendiri artinya Kubernetes menunggu makin lama di tiap percobaan ulang, mulai beberapa detik sampai maksimal lima menit, supaya registry tidak dihujani request.
CrashLoopBackOff: Aplikasi Mati Terus
Sekarang buat container yang langsung exit dengan kode error:
kubectl run crash-demo --image=busybox:1.36 -- sh -c "echo boom; exit 1"
kubectl get pods
NAME READY STATUS RESTARTS AGE
crash-demo 0/1 CrashLoopBackOff 3 (25s ago) 1m
Polanya: container jalan, mati, di-restart, mati lagi, dan jeda restart makin lama. Bedanya dengan ImagePullBackOff, di sini image berhasil ditarik tapi prosesnya sendiri yang mati. Penyebab umum di dunia nyata: aplikasi gagal konek ke database, environment variable wajib belum di-set, atau memang ada bug yang bikin proses exit.
Langkah diagnosa selalu sama. Pertama describe untuk lihat exit code, kedua baca log aplikasi:
kubectl logs crash-demo
boom
Kalau container sudah terlanjur di-restart dan kamu butuh log dari proses yang mati sebelumnya, pakai flag --previous:
kubectl logs crash-demo --previous
Di pengalaman tim kami menangani backend Go dan Laravel milik klien, hampir semua CrashLoopBackOff ujungnya ketahuan dari kubectl logs. Jadi biasakan urutannya: get pods untuk lihat gejala, describe untuk konteks, logs untuk akar masalah. Bersihkan kedua pod percobaan:
kubectl delete pod salah-ketik crash-demo
Pod Nyangkut di Pending
Satu lagi yang sering muncul: pod diam di status Pending lama sekali. Artinya scheduler belum menemukan node yang muat. Di Minikube ini biasanya terjadi kalau kamu meminta resource lebih besar dari kapasitas VM. Diagnosa tetap sama, kubectl describe pod lalu baca Events. Biasanya ada pesan Insufficient cpu atau Insufficient memory. Solusinya turunkan permintaan resource pod, atau besarkan Minikube dengan minikube start --cpus=4 --memory=4096.
Kenapa di Dunia Nyata Kita Jarang Membuat Pod Langsung
Setelah semua praktik di atas, ini pelajaran penutupnya: pod telanjang (bare pod) hampir tidak pernah dipakai di produksi. Alasannya balik ke sifat sekali pakai tadi. Kalau node tempat pod berjalan mati, pod ikut hilang dan tidak ada yang menggantikannya. Tidak ada self-healing, tidak ada scaling, tidak ada rolling update.
Di dunia nyata, pod selalu dikelola oleh controller seperti Deployment. Kamu mendeklarasikan “saya mau 3 replika aplikasi ini”, lalu Deployment yang memastikan selalu ada 3 pod hidup. Pod mati satu, dibuatkan penggantinya secara otomatis. Ini pola yang tim Arrazy pakai saat membangun sistem aplikasi untuk klien: tidak ada satu pun bare pod, semuanya lewat Deployment atau controller lain.
Lalu kenapa kita belajar pod duluan? Karena Deployment pada dasarnya hanyalah mesin pengelola pod. Semua skill hari ini, membaca describe, membaca Events, membaca logs, akan kamu pakai persis sama saat pod-nya dikelola Deployment.
Rangkuman dan Lanjut ke Mana
Hari ini kamu sudah pegang konsep paling fundamental di Kubernetes. Pod adalah unit terkecil yang bisa di-deploy, container di dalamnya berbagi network dan storage, lifecycle-nya berjalan dari Pending sampai Running atau Failed, dan sifatnya sekali pakai sehingga butuh controller untuk produksi. Kamu juga sudah kenal dua error klasik, ImagePullBackOff dan CrashLoopBackOff, lengkap dengan cara diagnosanya.
Sejauh ini kita banyak memakai perintah imperatif seperti kubectl run. Cara itu cepat untuk belajar, tapi tidak cocok untuk kerja tim karena tidak ada catatan konfigurasi yang bisa di-review dan di-versioning. Solusinya menulis manifest YAML, dan itu tepat bahasan berikutnya: “Belajar Kubernetes #6: Cara Membuat File YAML Kubernetes”. Bagian itu terbit menyusul, pantau daftarnya di halaman hub Belajar Kubernetes dari Nol.
Referensi
Artikel Lainnya di Kategori Kubernetes
Kubernetes 15 Agustus 2026
Belajar Kubernetes #3: Arsitektur Kubernetes Cluster
Bedah arsitektur Kubernetes: control plane vs worker node, tugas tiap komponen dengan analogi kantor, plus praktik bedah komponen langsung di Minikube.
Baca Artikel
Kubernetes 3 Agustus 2026
Belajar Kubernetes #1: Kubernetes Adalah + Install Minikube
Kubernetes adalah orkestrator container. Pahami konsepnya lewat analogi sederhana, install kubectl dan Minikube, lalu jalankan cluster pertamamu.
Baca Artikel
Kubernetes 9 Agustus 2026
Belajar Kubernetes #2: Perbedaan Docker dan Kubernetes
Docker membungkus aplikasi jadi container, Kubernetes mengaturnya di banyak mesin. Pahami bedanya lewat praktik self-healing langsung di Minikube.
Baca ArtikelIngin Membaca Artikel Lainnya?
Temukan lebih banyak insight dan tips tentang teknologi dan bisnis digital.
Lihat Semua Artikel