Series MapLesson 05 / 35
Start HereOrdered learning track

Learn Kubernetes Deployment Model Part 005 Pods Container Contract

20 min read3809 words
PrevNext
Lesson 0535 lesson track0106 Start Here

title: Learn Kubernetes, Deployment Model, and Cloud Native Platform Engineering - Part 005 description: Deep dive Pod sebagai unit eksekusi Kubernetes, container runtime contract, lifecycle, probes, sidecars, termination, debugging, dan failure modelling. series: learn-kubernetes-deployment-model seriesTitle: Learn Kubernetes, Deployment Model, and Cloud Native Platform Engineering order: 5 partTitle: Pods and the Container Runtime Contract tags:

  • kubernetes
  • pods
  • container-runtime
  • workload
  • deployment
  • reliability
  • sre
  • series date: 2026-07-01

Part 005 — Pods and the Container Runtime Contract

Tujuan part ini adalah membuat kita melihat Pod bukan sebagai “container yang dijalankan Kubernetes”, tetapi sebagai unit scheduling, lifecycle, network identity, resource accounting, dan failure isolation terkecil dalam Kubernetes.

Di Docker, kita sering berpikir dalam bentuk container individual. Di Kubernetes, unit dasar bukan container, melainkan Pod. Sebuah Pod dapat berisi satu atau lebih container yang berbagi konteks eksekusi tertentu: network namespace, IP address, volume, dan lifecycle scheduling. Kubernetes men-schedule Pod ke Node, kubelet menjaga Pod tersebut di Node, dan controller seperti Deployment/ReplicaSet/StatefulSet/Job menciptakan atau mengganti Pod berdasarkan desired state.

Mental model terpenting:

Pod is not a durable server.
Pod is an ephemeral execution cell produced by a higher-level controller.

Kalau kita memperlakukan Pod seperti VM kecil yang stabil, desain kita akan rapuh. Kalau kita memperlakukan Pod sebagai cell sementara yang bisa mati, diganti, dipindah, atau dibuat ulang kapan saja, desain kita akan lebih dekat dengan cara Kubernetes benar-benar bekerja.


1. Kaufman Deconstruction: Skill yang Harus Dikuasai

Menguasai Pod berarti menguasai beberapa sub-skill kecil:

Sub-skillPertanyaan yang Harus Bisa Dijawab
Pod identityApa yang stabil dan tidak stabil dari sebuah Pod?
Pod lifecycleApa arti Pending, Running, Succeeded, Failed, Unknown?
Container lifecycleApa beda waiting, running, terminated, restart count, dan last state?
Init containerKapan kita butuh initialization yang harus selesai sebelum app start?
Sidecar containerKapan supporting process harus hidup bersama app container?
Probe designKapan pakai startup, readiness, dan liveness probe?
Shutdown designBagaimana proses menerima traffic stop, SIGTERM, drain, dan exit?
Resource boundaryBagaimana Pod meminta CPU/memory dan bagaimana Node melakukan eviction?
DebuggingBagaimana membaca Pod yang Pending, CrashLoopBackOff, ImagePullBackOff, OOMKilled, atau stuck Terminating?
Deployment implicationKenapa update Pod template menghasilkan Pod baru, bukan patch container lama?

Sub-skill di atas lebih penting daripada hafal field YAML. YAML hanya manifestasi dari contract. Yang harus dikuasai adalah contract dan failure semantics.


2. Pod sebagai Scheduling Atom

Pod adalah unit yang Kubernetes jadwalkan ke Node. Scheduler tidak menempatkan container satu per satu; scheduler memilih Node untuk Pod. Setelah Pod terikat ke Node, kubelet di Node tersebut bertanggung jawab membuat Pod sandbox, menarik image, menjalankan container, memantau status, menjalankan probe, dan melaporkan status kembali ke API server.

Implikasinya besar:

  1. Semua container dalam Pod colocated pada Node yang sama.
  2. Semua container dalam Pod berbagi lifecycle scheduling.
  3. Resource request Pod adalah agregasi resource container dengan aturan tertentu untuk init container.
  4. Pod IP diberikan ke Pod, bukan ke container individual.
  5. Jika Pod diganti, identitas runtime berubah: UID, IP, restart count, status, event history.

Rule of thumb:

Masukkan container ke Pod yang sama hanya jika mereka harus hidup, mati, diskalakan, dan ditempatkan bersama.

Kalau dua proses bisa diskalakan berbeda, rollout berbeda, atau gagal secara independen, biasanya mereka tidak seharusnya berada dalam Pod yang sama.


3. Apa yang Dibagi oleh Container dalam Pod?

Container dalam Pod bukan container yang sepenuhnya independen. Mereka berbagi beberapa namespace dan resource.

AreaShared?Implikasi
Network namespaceYaSemua container dalam Pod berbagi IP dan port space. localhost antar container mengarah ke Pod yang sama.
Pod IPYaService memilih Pod, bukan container.
VolumesBisaContainer dapat berbagi file melalui volume yang sama.
Lifecycle placementYaSemua container ditempatkan di Node yang sama.
CPU/memory limitsPer container, dihitung pada level Pod jugaResource pressure dapat mempengaruhi semua container di Pod.
Process namespaceDefault tidak, bisa dikonfigurasiDengan shareProcessNamespace, container dapat melihat proses satu sama lain.
Filesystem rootTidakTiap container punya filesystem image masing-masing.
Environment variablesTidak otomatisHarus didefinisikan per container.

Contoh praktis:

apiVersion: v1
kind: Pod
metadata:
  name: payments-api-demo
  labels:
    app.kubernetes.io/name: payments-api
    app.kubernetes.io/component: api
spec:
  containers:
    - name: app
      image: registry.example.com/payments-api:1.8.3
      ports:
        - containerPort: 8080
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/app
    - name: log-shipper
      image: registry.example.com/log-shipper:2.1.0
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/app
  volumes:
    - name: shared-logs
      emptyDir: {}

Di sini app dan log-shipper berbagi volume. Tetapi mereka juga berbagi fate: jika Pod dihapus, keduanya hilang. Jika traffic diarahkan ke Pod, readiness Pod dipengaruhi oleh readiness container sesuai konfigurasi.


4. Anatomy Pod: metadata, spec, status

Pod tetap mengikuti object model Kubernetes:

apiVersion: v1
kind: Pod
metadata:
  name: inventory-api-abc123
  namespace: production
  labels:
    app.kubernetes.io/name: inventory-api
    app.kubernetes.io/instance: inventory-api-prod
    app.kubernetes.io/version: "2.4.1"
spec:
  serviceAccountName: inventory-api
  restartPolicy: Always
  containers:
    - name: app
      image: registry.example.com/inventory-api:2.4.1
      resources:
        requests:
          cpu: "250m"
          memory: "512Mi"
        limits:
          memory: "1Gi"
      readinessProbe:
        httpGet:
          path: /ready
          port: 8080
      livenessProbe:
        httpGet:
          path: /live
          port: 8080
status:
  phase: Running
  podIP: 10.42.3.17
  conditions:
    - type: Ready
      status: "True"
  containerStatuses:
    - name: app
      ready: true
      restartCount: 0

Bagian penting:

FieldSiapa yang MenulisMakna
metadatauser/controller/API serverIdentitas object, label, annotation, owner reference, UID.
specuser/controller/platform toolDesired state: container apa, image apa, resource apa, probe apa.
statuskubelet/controllerActual observed state: phase, condition, IP, container status.

Jangan menulis automation yang mengambil keputusan hanya dari spec. Dalam operasi production, keputusan harus membaca kombinasi:

metadata + spec + status + events + controller state + node state

5. Pod Bukan Deployment Unit yang Ideal

Kita bisa membuat Pod langsung, tetapi dalam production biasanya tidak. Alasannya: Pod langsung tidak punya controller yang mengganti Pod saat hilang, melakukan rollout, menjaga replica count, atau menyimpan revision history.

Cara MembuatCocok UntukTidak Cocok Untuk
Direct PodDebugging, eksperimen, static Pod, low-level testingProduction stateless service
DeploymentStateless replicated serviceStateful identity, ordered rollout
StatefulSetStateful workload dengan identity stabilStateless API sederhana
DaemonSetAgent per NodeService biasa yang perlu horizontal scaling
JobWork selesai lalu exitLong-running service
CronJobScheduled executionAlways-on API

Invariant:

Production workload should usually be managed by a controller, not by bare Pods.

Bare Pod tidak berarti salah. Tetapi bare Pod memindahkan tanggung jawab healing dan replacement ke operator manusia atau automation eksternal.


6. Pod Lifecycle

Pod memiliki phase sederhana, tetapi detail container status di dalamnya jauh lebih kaya.

Pod phase umum:

PhaseArti Operasional
PendingPod diterima API server, tetapi belum semua container berjalan. Bisa karena belum scheduled, image pulling, volume attach, init container, atau constraint.
RunningPod sudah bound ke Node dan minimal satu container utama berjalan atau sedang restart.
SucceededSemua container selesai sukses dan tidak akan restart. Umum untuk Job.
FailedSemua container selesai, minimal satu gagal, dan tidak akan restart.
UnknownControl plane tidak bisa mendapatkan status Pod, sering karena Node unreachable.

Jangan overinterpret Running. Pod Running belum tentu siap menerima traffic. Untuk traffic, lihat Ready condition dan readiness probe.


7. Container State di Dalam Pod

Container status biasanya berada di salah satu state:

StateContoh ReasonMakna
WaitingContainerCreating, ImagePullBackOff, CrashLoopBackOffContainer belum berjalan atau sedang menunggu retry.
Running-Process container sedang berjalan.
TerminatedCompleted, Error, OOMKilledProcess sudah selesai atau dibunuh.

Command diagnosis:

kubectl get pod inventory-api-abc123 -n production -o wide
kubectl describe pod inventory-api-abc123 -n production
kubectl get pod inventory-api-abc123 -n production -o yaml
kubectl logs inventory-api-abc123 -n production -c app
kubectl logs inventory-api-abc123 -n production -c app --previous

--previous penting untuk CrashLoopBackOff, karena log container saat ini mungkin kosong sementara container sebelumnya sudah crash.


8. Restart Policy: Pod-Level dan Container-Level Behavior

Field restartPolicy pada Pod menentukan kapan kubelet akan restart container. Nilai umumnya:

PolicyMaknaUmum Untuk
AlwaysRestart container jika berhentiDeployment, StatefulSet, DaemonSet
OnFailureRestart hanya jika exit non-zeroJob
NeverJangan restart containerDebugging, one-shot execution

Untuk workload long-running yang dibuat oleh Deployment, restartPolicy harus Always. Job biasanya memakai OnFailure atau Never tergantung semantik retry.

Perlu dibedakan:

kubelet restarts containers inside the same Pod.
controller replaces Pods when the Pod no longer satisfies desired state.

Dua mekanisme ini berbeda. CrashLoopBackOff adalah kubelet mencoba restart container dalam Pod yang sama dengan backoff. ReplicaSet replacement adalah controller membuat Pod baru ketika Pod lama hilang atau tidak lagi dimiliki.


9. Init Containers

Init container berjalan sebelum app container. Mereka harus selesai sukses sebelum container utama dimulai.

Kegunaan umum:

  1. Menunggu dependency internal tersedia.
  2. Menjalankan migration ringan yang aman dan idempotent.
  3. Menyiapkan file konfigurasi dari template.
  4. Mengambil metadata yang diperlukan sebelum app start.
  5. Melakukan permission setup pada mounted volume.

Contoh:

apiVersion: v1
kind: Pod
metadata:
  name: report-worker
spec:
  initContainers:
    - name: wait-for-schema
      image: registry.example.com/db-checker:1.0.0
      command: ["sh", "-c"]
      args:
        - |
          until ./check-schema --version 42; do
            echo "schema not ready"
            sleep 5
          done
  containers:
    - name: worker
      image: registry.example.com/report-worker:4.2.0

Anti-pattern:

Init container that performs non-idempotent migration across many replicas.

Jika 20 Pod start bersamaan dan semua menjalankan migration yang sama tanpa lock, kita membuat distributed race condition. Untuk migration serius, gunakan pipeline step, Job terpisah, atau mekanisme lock yang jelas.


10. Native Sidecar Containers

Sidecar adalah container pendukung yang berjalan bersama app container. Kubernetes modern mendukung sidecar sebagai restartable init container dengan restartPolicy: Always pada init container. Dengan model ini, sidecar dapat start sebelum container utama dan tetap berjalan sepanjang lifetime Pod.

Contoh use case:

SidecarFungsi
log shipperMengirim log file dari shared volume.
proxyMenangani traffic policy, mTLS, atau routing lokal.
config reloaderMemantau config dan memicu reload aman.
data syncerSinkronisasi file sebelum dan selama app berjalan.

Contoh konseptual:

apiVersion: v1
kind: Pod
metadata:
  name: catalog-api
spec:
  initContainers:
    - name: config-sidecar
      image: registry.example.com/config-syncer:2.0.0
      restartPolicy: Always
      volumeMounts:
        - name: runtime-config
          mountPath: /runtime-config
  containers:
    - name: app
      image: registry.example.com/catalog-api:3.1.0
      volumeMounts:
        - name: runtime-config
          mountPath: /app/config
  volumes:
    - name: runtime-config
      emptyDir: {}

Design rule:

Use sidecars for tightly coupled supporting behavior, not as a dumping ground for unrelated platform concerns.

Sidecar menambah resource usage, startup ordering, termination ordering, observability complexity, dan failure coupling. Jika sidecar gagal, Pod behavior dapat terpengaruh.


11. Ephemeral Containers untuk Debugging

Ephemeral container adalah container temporer yang ditambahkan ke Pod yang sudah ada untuk debugging. Ini berguna ketika image aplikasi minimal tidak memiliki shell, package manager, curl, dig, netstat, atau tool observability lain.

Contoh:

kubectl debug -it inventory-api-abc123 \
  -n production \
  --image=busybox:1.36 \
  --target=app

Gunakan ephemeral container untuk inspeksi, bukan untuk memperbaiki production state secara manual. Begitu debugging selesai, solusi harus kembali ke manifest, image, pipeline, policy, atau runtime configuration yang repeatable.

Invariant:

Manual mutation inside a running Pod is not a fix. It is an investigation step.

12. Probes: Startup, Readiness, Liveness

Probe adalah salah satu area Kubernetes yang paling sering disalahgunakan. Banyak outage terjadi bukan karena Kubernetes gagal, tetapi karena probe salah mendefinisikan kesehatan aplikasi.

Tiga tipe utama:

ProbePertanyaanEfek Jika Gagal
startupProbeApakah aplikasi sudah selesai startup?Container dibunuh dan mengikuti restart policy. Selama startup probe belum sukses, liveness/readiness normal belum mengambil alih.
readinessProbeApakah aplikasi siap menerima traffic?Pod dikeluarkan dari endpoint Service yang matching. Container tidak dibunuh.
livenessProbeApakah aplikasi deadlocked atau tidak bisa recover tanpa restart?Container dibunuh dan direstart oleh kubelet.

Decision rule:

Readiness protects users.
Liveness protects the process.
Startup protects slow initialization.

12.1 Readiness Probe

Readiness harus menjawab: “Apakah instance ini boleh menerima request baru sekarang?”

Contoh:

readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5
  timeoutSeconds: 2
  failureThreshold: 3

Readiness boleh gagal sementara. Misalnya:

  • dependency lokal belum warm.
  • cache belum loaded.
  • queue worker sedang drain.
  • app sedang overload dan ingin stop menerima traffic baru.

Tetapi hati-hati: readiness yang terlalu sensitif terhadap dependency eksternal dapat menyebabkan cascading failure. Jika semua Pod menandai diri not ready karena database lambat, Service kehilangan semua endpoint dan user melihat hard outage. Terkadang lebih baik degraded response daripada menghilang dari load balancer.

12.2 Liveness Probe

Liveness harus menjawab: “Apakah process ini sudah tidak mungkin pulih tanpa restart?”

Liveness bukan health check dependency. Jangan membuat liveness gagal hanya karena database, cache, atau downstream lambat. Jika dependency down, restart app tidak memperbaiki dependency dan malah memperparah outage.

Anti-pattern:

livenessProbe:
  httpGet:
    path: /health-that-checks-database
    port: 8080

Lebih baik:

livenessProbe:
  httpGet:
    path: /live
    port: 8080

/live sebaiknya hanya mengecek kondisi lokal fatal: event loop stuck, thread pool mati total, corrupt internal state, atau deadlock indicator.

12.3 Startup Probe

Startup probe berguna untuk aplikasi yang lambat start: JVM besar, warmup cache, schema validation, model loading, atau legacy app.

Tanpa startup probe, liveness bisa membunuh app sebelum sempat siap.

startupProbe:
  httpGet:
    path: /startup
    port: 8080
  periodSeconds: 5
  failureThreshold: 60

Contoh di atas memberi jendela startup sampai 5 menit.


13. Probe Failure Modes

GejalaKemungkinan PenyebabDampak
Pod Running tapi tidak menerima trafficReadiness gagalService endpoint tidak memasukkan Pod.
Pod restart terus setelah beberapa detikLiveness terlalu agresif atau app deadlockCrashLoopBackOff.
Slow-start app tidak pernah stabilTidak ada startup probeLiveness membunuh sebelum app siap.
Semua Pod not ready saat dependency downReadiness terlalu coupling ke dependency globalCascading outage.
Rollout stuckPod baru tidak pernah readyDeployment tidak mencapai progress.

Prinsip senior:

Probe is part of the deployment contract, not an afterthought.

Probe yang salah dapat mengubah partial degradation menjadi total outage.


14. Graceful Termination

Kubernetes tidak langsung mematikan container ketika Pod dihapus. Secara umum, kubelet mengirim signal terminasi, menjalankan lifecycle hook jika ada, menunggu terminationGracePeriodSeconds, lalu memaksa kill jika process belum keluar.

Aplikasi production harus menangani SIGTERM dengan benar:

  1. Stop menerima request baru.
  2. Selesaikan in-flight request jika aman.
  3. Flush metrics/logs/traces.
  4. Commit atau rollback work unit.
  5. Release lock/lease.
  6. Exit sebelum grace period habis.

Contoh:

spec:
  terminationGracePeriodSeconds: 45
  containers:
    - name: app
      image: registry.example.com/orders-api:2.8.0
      lifecycle:
        preStop:
          httpGet:
            path: /shutdown/drain
            port: 8080

preStop bukan pengganti SIGTERM handler. Hook dapat gagal, timeout, atau tidak cukup cepat. Aplikasi tetap harus menangani signal.


15. Pod Readiness Gates

Readiness biasanya dihitung dari readiness probe container dan kondisi internal kubelet. Untuk integrasi lebih advanced, Kubernetes mendukung readiness gates: Pod dianggap ready hanya jika condition tambahan juga true.

Use case:

  • Load balancer eksternal belum selesai register target.
  • Service mesh belum selesai inject/configure proxy.
  • Custom controller ingin menahan readiness sampai dependency platform siap.

Gunakan readiness gates dengan hati-hati. Mereka menambah dependency antara workload dan controller eksternal. Jika controller eksternal rusak, Pod bisa tidak pernah ready.


16. Resource Contract di Pod

Setiap container dapat mendefinisikan requests dan limits.

resources:
  requests:
    cpu: "250m"
    memory: "512Mi"
  limits:
    memory: "1Gi"

Kita akan bahas resource governance secara detail di Part 013. Untuk sekarang, cukup pahami bahwa Pod placement dan eviction sangat dipengaruhi oleh resource declaration.

FieldMakna
CPU requestKapasitas CPU yang digunakan scheduler untuk placement.
Memory requestKapasitas memory yang digunakan scheduler untuk placement.
CPU limitBatas throttling CPU. Tidak selalu direkomendasikan untuk semua workload latency-sensitive.
Memory limitBatas memory keras; melewati ini biasanya menyebabkan OOM kill.

Pod tanpa request membuat scheduler buta terhadap kebutuhan workload. Pod tanpa limit memory bisa membahayakan Node. Pod dengan limit terlalu kecil akan sering OOMKilled.


17. Volume dalam Pod

Volume adalah cara container dalam Pod mengakses storage selain filesystem image.

Jenis umum:

VolumeUse Case
emptyDirScratch space selama Pod hidup. Hilang saat Pod dihapus.
configMapKonfigurasi non-secret.
secretSecret material.
projectedGabungan Secret, ConfigMap, Downward API, ServiceAccount token.
persistentVolumeClaimStorage persisten melalui PV/PVC.

Contoh emptyDir:

volumes:
  - name: scratch
    emptyDir: {}

Ingat:

Pod deletion deletes ephemeral Pod-local state.

Jangan simpan state penting di filesystem container atau emptyDir kecuali data tersebut dapat hilang kapan saja.


18. Downward API

Downward API memungkinkan container membaca informasi tentang dirinya tanpa memanggil Kubernetes API server.

Contoh:

env:
  - name: POD_NAME
    valueFrom:
      fieldRef:
        fieldPath: metadata.name
  - name: POD_NAMESPACE
    valueFrom:
      fieldRef:
        fieldPath: metadata.namespace
  - name: POD_IP
    valueFrom:
      fieldRef:
        fieldPath: status.podIP

Gunakan untuk:

  • log correlation.
  • metrics labels.
  • tracing metadata.
  • runtime diagnostics.

Jangan gunakan Pod name sebagai durable identity untuk stateful logic. Untuk identity stabil, gunakan StatefulSet atau identity eksternal yang eksplisit.


19. Security Context di Level Pod dan Container

Pod dapat memiliki security context. Container juga bisa override beberapa field.

Contoh minimal:

spec:
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: registry.example.com/billing-api:1.5.0
      securityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL

Kita akan membahas hardening secara detail di Part 023. Untuk saat ini, pahami bahwa Pod adalah boundary penting untuk runtime security: service account, token mount, Linux capabilities, user, group, seccomp, AppArmor, privileged mode, host namespace, dan volume access.


20. Common Pod Failure Modes

20.1 Pending

Pod Pending berarti belum benar-benar berjalan.

Diagnosis:

kubectl describe pod <pod> -n <ns>
kubectl get events -n <ns> --sort-by=.lastTimestamp

Kemungkinan:

PenyebabIndikasi
Resource tidak cukupInsufficient cpu, Insufficient memory
Node selector/affinity tidak cocoknode(s) didn't match Pod's node affinity/selector
Taint tidak ditoleransihad untolerated taint
PVC belum boundpod has unbound immediate PersistentVolumeClaims
Image masih pullingContainerCreating, event image pull
CNI lambat/gagalsandbox/network setup error

20.2 ImagePullBackOff

Kemungkinan:

  • image tag salah.
  • registry down.
  • credential imagePullSecret salah.
  • network egress ke registry gagal.
  • rate limit registry.
  • image architecture tidak cocok.

Diagnosis:

kubectl describe pod <pod> -n <ns>
kubectl get secret -n <ns>

20.3 CrashLoopBackOff

Artinya container start, crash, lalu kubelet retry dengan backoff.

Diagnosis:

kubectl logs <pod> -n <ns> -c <container> --previous
kubectl describe pod <pod> -n <ns>

Kemungkinan:

  • config invalid.
  • secret missing.
  • command/args salah.
  • dependency required saat startup tidak tersedia.
  • liveness probe membunuh terlalu cepat.
  • permission filesystem.
  • application panic.

20.4 OOMKilled

Container melewati memory limit dan dibunuh.

Diagnosis:

kubectl get pod <pod> -n <ns> -o jsonpath='{.status.containerStatuses[*].lastState}'
kubectl describe pod <pod> -n <ns>

Kemungkinan:

  • memory limit terlalu rendah.
  • leak.
  • traffic spike.
  • JVM/container memory tidak dikonfigurasi.
  • sidecar juga memakai memory signifikan.

20.5 Evicted

Kubelet mengusir Pod karena Node pressure: memory, disk, inode, atau resource lain.

Diagnosis:

kubectl describe node <node>
kubectl describe pod <pod> -n <ns>

Evicted adalah sinyal bahwa problem bukan hanya app; bisa jadi capacity planning, QoS, request/limit, log volume, ephemeral storage, atau node health.

20.6 Stuck Terminating

Kemungkinan:

  • finalizer belum selesai.
  • volume detach lambat.
  • kubelet/node unreachable.
  • process tidak exit dalam grace period.
  • controller external tidak membersihkan resource.

Jangan langsung --force --grace-period=0 kecuali memahami konsekuensi. Force delete dapat meninggalkan process atau resource eksternal dalam state tidak konsisten.


21. Pod Design Patterns

21.1 Single Main Container

Pola default untuk microservice/API/worker.

one Pod = one primary application process

Ini paling mudah di-scale, di-rollout, di-debug, dan di-observe.

21.2 Sidecar

Gunakan ketika supporting process harus berbagi lifecycle, network, atau volume dengan app.

Contoh:

  • service mesh proxy.
  • log shipper per Pod.
  • local auth proxy.
  • config syncer.

21.3 Adapter

Adapter mengubah output app ke format standar. Misalnya mengubah metrics format legacy menjadi Prometheus-compatible.

21.4 Ambassador

Ambassador menjadi proxy lokal untuk komunikasi keluar. Pola ini berkurang relevansinya di cluster modern dengan service mesh/gateway yang matang, tetapi masih berguna untuk beberapa workload legacy.

21.5 Init-Then-App

Gunakan init container untuk setup yang harus selesai sebelum app start.

21.6 Debug Ephemeral

Gunakan ephemeral container untuk investigasi tanpa mengubah image app.


22. Pod Anti-Patterns

Anti-patternMasalah
Banyak aplikasi tidak terkait dalam satu PodScaling, rollout, failure, dan ownership bercampur.
Liveness mengecek databaseDependency outage berubah menjadi restart storm.
Tidak ada readiness probeTraffic masuk sebelum app siap.
Tidak ada startup probe untuk slow-start appApp dibunuh sebelum selesai startup.
Menyimpan state penting di filesystem containerData hilang saat Pod diganti.
Bare Pod untuk production serviceTidak ada healing/rollout controller.
Sidecar untuk semua halResource overhead dan failure coupling.
Pod tanpa resource requestScheduler tidak bisa membuat placement yang sehat.
Pod privileged tanpa alasan eksplisitRisiko node compromise.
Debugging dengan edit manual di containerTidak repeatable dan tidak auditable.

23. Deployment Implications

Controller seperti Deployment tidak mengubah container di dalam Pod yang sedang berjalan untuk mengganti image. Deployment membuat ReplicaSet baru, lalu ReplicaSet membuat Pod baru dari Pod template baru.

Implikasi:

  1. Perubahan pada Pod template adalah perubahan deployment identity.
  2. Label selector menentukan Pod mana yang dihitung oleh controller.
  3. Pod lama dan baru bisa hidup bersamaan selama rolling update.
  4. Readiness Pod baru menentukan kecepatan rollout.
  5. Liveness salah dapat membuat rollout gagal karena Pod baru restart terus.
  6. Graceful shutdown Pod lama menentukan apakah request terputus saat rollout.

24. Debugging Workflow: Dari Gejala ke Penyebab

Jangan mulai dari kubectl exec. Mulai dari object graph.

Command sequence:

# 1. Identify pods behind an app
kubectl get pods -n production -l app.kubernetes.io/name=payments-api -o wide

# 2. Inspect one failing pod
kubectl describe pod <pod> -n production

# 3. Read status in structured form
kubectl get pod <pod> -n production -o yaml

# 4. Logs
kubectl logs <pod> -n production -c app
kubectl logs <pod> -n production -c app --previous

# 5. Events
kubectl get events -n production --sort-by=.lastTimestamp

# 6. Node context
kubectl describe node <node>

Diagnosis harus menjawab:

  • Apakah Pod gagal sebelum scheduling?
  • Apakah gagal saat image pull?
  • Apakah gagal saat volume mount?
  • Apakah app start lalu crash?
  • Apakah probe membunuh container?
  • Apakah Pod tidak ready karena dependency?
  • Apakah Node mengalami pressure?
  • Apakah controller mengganti Pod terus-menerus?

25. Production Checklist untuk Pod Template

Gunakan checklist ini sebelum Pod template dipromosikan ke production.

Identity and Ownership

  • Pod dibuat oleh controller, bukan bare Pod.
  • Labels mengikuti schema organisasi.
  • OwnerReferences dihasilkan controller dengan benar.
  • Service selector cocok dengan label Pod yang dimaksud.

Runtime

  • Image immutable atau digest-based untuk environment kritikal.
  • Command/args jelas dan tidak bergantung pada shell magic yang rapuh.
  • Environment variable dan mounted config terdokumentasi.
  • Secret tidak diprint di log.

Probes

  • Readiness probe ada untuk service yang menerima traffic.
  • Liveness probe hanya mengecek fatal local unrecoverable state.
  • Startup probe ada untuk aplikasi slow-start.
  • Timeout dan threshold realistis.

Shutdown

  • App menangani SIGTERM.
  • terminationGracePeriodSeconds sesuai durasi in-flight work.
  • Worker melakukan drain/ack/nack dengan benar.
  • Tidak ada lock yang tertinggal saat Pod mati.

Resources

  • CPU/memory requests ditentukan.
  • Memory limit realistis.
  • Ephemeral storage dipertimbangkan jika app menulis file/log besar.
  • Sidecar overhead dihitung.

Security

  • runAsNonRoot jika memungkinkan.
  • allowPrivilegeEscalation: false.
  • Linux capabilities tidak perlu di-drop semua jika app butuh capability tertentu, tetapi default harus minimal.
  • ServiceAccount spesifik, bukan default account dengan privilege luas.

Observability

  • Logs ke stdout/stderr atau dikirim dengan pola yang jelas.
  • Metrics endpoint tersedia jika diperlukan.
  • Pod metadata masuk ke log/trace/metrics.
  • Container name konsisten.

26. Deliberate Practice

Latihan berikut dirancang agar kita bisa mengoreksi diri.

Exercise 1 — Diagnose Pending Pod

Buat Pod dengan request CPU terlalu besar sehingga tidak bisa dijadwalkan. Lalu jawab:

  • Event apa yang muncul?
  • Apakah Pod punya Node?
  • Apakah container pernah dibuat?
  • Apa perbedaan kubectl get pod dan kubectl describe pod?

Exercise 2 — Break Readiness

Buat Deployment dengan readiness endpoint salah. Lalu jawab:

  • Apakah Pod Running?
  • Apakah Pod Ready?
  • Apakah Service punya endpoint?
  • Apakah rollout selesai?

Exercise 3 — Liveness Restart Storm

Buat liveness probe terlalu agresif. Lalu jawab:

  • Apa restart count-nya?
  • Apa isi --previous logs?
  • Apa event yang dicatat kubelet?
  • Bagaimana memperbaiki tanpa menghapus liveness sepenuhnya?

Exercise 4 — Graceful Shutdown

Deploy service yang sleep 20 detik sebelum exit saat SIGTERM. Atur grace period 5 detik lalu 30 detik. Amati:

  • Apakah request terputus?
  • Apakah app exit sendiri atau di-kill?
  • Bagaimana event dan log berubah?

27. Summary

Kubernetes Pod adalah fondasi runtime, tetapi bukan abstraksi deployment paling tinggi. Pod adalah cell eksekusi ephemeral yang dibuat, diamati, dan diganti oleh controller.

Hal yang harus melekat:

  1. Pod adalah scheduling atom, bukan durable server.
  2. Container dalam Pod berbagi network identity dan placement.
  3. spec adalah desired state; status adalah observed state.
  4. Running tidak sama dengan Ready.
  5. Probe adalah bagian dari deployment safety contract.
  6. Init container menyelesaikan precondition; sidecar mendampingi lifecycle app; ephemeral container membantu debugging.
  7. Graceful termination harus didesain di aplikasi, bukan diasumsikan otomatis.
  8. Bare Pod jarang cocok untuk production service.
  9. Debugging Pod harus membaca object graph, events, status, logs, dan node context.

Di part berikutnya, kita akan membahas label, selector, ownership, dan garbage collection. Ini adalah mekanisme yang menentukan bagaimana controller menemukan Pod, bagaimana Service memilih endpoint, bagaimana object saling memiliki, dan bagaimana Kubernetes membersihkan dependensi.


References

Lesson Recap

You just completed lesson 05 in start here. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.