Series MapLesson 09 / 35
Build CoreOrdered learning track

Learn Kubernetes Deployment Model Part 009 Deployment Controller Deep Dive

19 min read3728 words
PrevNext
Lesson 0935 lesson track0719 Build Core

title: Learn Kubernetes, Deployment Model, and Cloud Native Platform Engineering - Part 009 description: Deep dive Deployment controller, ReplicaSet relationship, rollout lifecycle, rolling update math, status conditions, rollback, pause/resume, production failure modes, dan debugging. series: learn-kubernetes-deployment-model seriesTitle: Learn Kubernetes, Deployment Model, and Cloud Native Platform Engineering order: 9 partTitle: Deployment Controller Deep Dive tags:

  • kubernetes
  • deployment
  • replicaset
  • rollout
  • rollback
  • reliability
  • sre
  • platform-engineering
  • series date: 2026-07-01

Part 009 — Deployment Controller Deep Dive

Tujuan part ini adalah membuat kita memahami Deployment bukan sebagai “YAML untuk menjalankan app”, tetapi sebagai controller-driven release mechanism: ia menciptakan ReplicaSet, mengelola transisi versi Pod, menjaga availability constraint, mencatat revision, dan memberi kita primitive untuk rollout, pause, resume, serta rollback.

Di Kubernetes, Deployment adalah resource tingkat tinggi untuk mengelola aplikasi stateless yang direpresentasikan sebagai sekumpulan Pod identik. Deployment tidak langsung “menjalankan container”. Deployment menyatakan desired state. Deployment controller lalu membuat dan mengelola ReplicaSet. ReplicaSet membuat dan menjaga Pod. Kubelet menjalankan Pod di Node.

Mental model paling penting:

Deployment is a versioned desired-state transition controller.
ReplicaSet is the replica-count enforcer for one Pod template revision.
Pod is the runtime execution cell.

Kalau kita salah memahami relasi ini, kita akan salah saat debugging rollout, salah membaca status, salah membuat rollback plan, dan salah mendesain release safety.


1. Kaufman Deconstruction: Skill yang Harus Dikuasai

Deployment tampak sederhana, tetapi skill produksinya terdiri dari beberapa sub-skill kecil:

Sub-skillPertanyaan yang Harus Bisa Dijawab
Controller relationshipDeployment membuat apa? ReplicaSet membuat apa? Pod dimiliki siapa?
Pod template revisionPerubahan apa yang menghasilkan revision baru? Perubahan apa yang tidak?
Selector safetyKenapa selector Deployment berbahaya jika salah?
Rolling update mathBagaimana maxSurge dan maxUnavailable membatasi transisi?
Availability semanticsApa beda desired replicas, updated replicas, ready replicas, dan available replicas?
Rollout monitoringBagaimana tahu rollout sedang sehat, lambat, stuck, atau gagal?
Rollback semanticsApa yang benar-benar terjadi saat rollback?
Pause/resumeKapan rollout perlu dipause dan apa konsekuensinya?
Production failure modesBagaimana mendeteksi bad image, failing readiness, quota issue, slow start, PDB conflict, node pressure, dan selector collision?
Operational contractField apa yang wajib distandarkan oleh platform team?

Target akhirnya bukan “bisa membuat Deployment”. Targetnya adalah bisa menjawab:

Apakah release ini aman, observable, reversible, dan bounded blast radius-nya?

2. Deployment Object Graph

Deployment adalah root controller untuk pola stateless replicated application.

Object graph ini menghasilkan beberapa konsekuensi:

  1. Deployment mengelola ReplicaSet, bukan Pod secara langsung.
  2. ReplicaSet mengelola Pod yang cocok dengan selector dan template revision-nya.
  3. Service biasanya memilih Pod lewat label, bukan memilih Deployment.
  4. Saat rollout, Service bisa mengirim traffic ke Pod lama dan baru secara bersamaan jika label selector-nya cocok.
  5. Rollback bukan “menghidupkan container lama”; rollback membuat Deployment kembali menggunakan Pod template revision sebelumnya.

Ketika production incident terjadi, jangan mulai dari YAML saja. Mulai dari graph:

Deployment -> ReplicaSet -> Pod -> Container -> Node -> Event -> Log -> Metric

3. Kenapa Jangan Mengelola ReplicaSet Langsung?

ReplicaSet memastikan jumlah Pod yang cocok dengan selector tersedia. Secara teknis kita bisa membuat ReplicaSet manual. Namun untuk aplikasi umum, Deployment lebih tepat karena memberikan layer rollout.

KemampuanReplicaSetDeployment
Menjaga jumlah PodYaYa, via ReplicaSet
Pod templateYaYa
Rolling updateTidak sebagai primitive utamaYa
Revision historyTidak sebagai interface release utamaYa
RollbackManualNative via rollout history
Pause/resume rolloutTidakYa
Declarative update strategyTerbatasYa
Status rolloutTerbatasYa

Rule of thumb:

Gunakan Deployment untuk aplikasi stateless long-running.
Biarkan Deployment mengelola ReplicaSet.
Jangan patch ReplicaSet manual kecuali untuk debugging terbatas dan sadar konsekuensi.

Patch manual pada ReplicaSet yang dimiliki Deployment mudah dioverwrite oleh controller. Dalam sistem reconciliation, perubahan manual pada child object sering bukan sumber kebenaran.


4. Anatomy of a Production Deployment

Contoh manifest minimal yang lebih dekat ke production baseline:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: payments-api
  namespace: payments
  labels:
    app.kubernetes.io/name: payments-api
    app.kubernetes.io/part-of: payment-platform
    app.kubernetes.io/component: api
    app.kubernetes.io/managed-by: gitops
spec:
  replicas: 6
  revisionHistoryLimit: 5
  progressDeadlineSeconds: 600
  minReadySeconds: 20
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 0
  selector:
    matchLabels:
      app.kubernetes.io/name: payments-api
      app.kubernetes.io/component: api
  template:
    metadata:
      labels:
        app.kubernetes.io/name: payments-api
        app.kubernetes.io/part-of: payment-platform
        app.kubernetes.io/component: api
        app.kubernetes.io/version: "2026.07.01-1"
    spec:
      serviceAccountName: payments-api
      terminationGracePeriodSeconds: 45
      containers:
      - name: app
        image: registry.example.com/payments-api:2026.07.01-1
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 8080
        resources:
          requests:
            cpu: "500m"
            memory: "512Mi"
          limits:
            memory: "1Gi"
        startupProbe:
          httpGet:
            path: /health/startup
            port: http
          failureThreshold: 30
          periodSeconds: 2
        readinessProbe:
          httpGet:
            path: /health/ready
            port: http
          periodSeconds: 5
          timeoutSeconds: 1
          failureThreshold: 2
        livenessProbe:
          httpGet:
            path: /health/live
            port: http
          periodSeconds: 10
          timeoutSeconds: 1
          failureThreshold: 3
        lifecycle:
          preStop:
            httpGet:
              path: /shutdown/drain
              port: http

Beberapa hal yang sengaja ada:

FieldFungsi Production
replicasDesired replica count untuk steady state.
revisionHistoryLimitMembatasi jumlah ReplicaSet lama yang disimpan untuk rollback.
progressDeadlineSecondsBatas waktu Deployment dianggap gagal progress.
minReadySecondsPod harus ready selama durasi tertentu sebelum dianggap available.
strategy.rollingUpdate.maxSurgeKapasitas ekstra selama rollout.
strategy.rollingUpdate.maxUnavailableBerapa banyak replica boleh unavailable selama rollout.
selectorBinding permanen Deployment ke Pod set.
template.metadata.labelsLabel Pod yang harus match selector dan Service.
startupProbeMelindungi aplikasi slow-start dari liveness kill terlalu cepat.
readinessProbeMengontrol apakah Pod boleh menerima traffic.
livenessProbeMengontrol restart saat proses benar-benar stuck.
preStop + graceful shutdownMengurangi dropped requests saat Pod dihapus.

Deployment yang aman bukan hanya memiliki image dan replica. Deployment yang aman punya traffic readiness, bounded rollout, rollback history, dan shutdown semantics.


5. Field yang Tidak Boleh Diremehkan

5.1 selector

Selector menentukan Pod mana yang dikelola Deployment. Pada apps/v1, selector wajib dan harus match label template.

spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: payments-api
  template:
    metadata:
      labels:
        app.kubernetes.io/name: payments-api

Selector adalah kontrak berbahaya karena:

  1. Selector yang terlalu luas dapat “mengadopsi” Pod yang tidak seharusnya.
  2. Selector yang tidak match template membuat Deployment tidak bisa mengelola Pod yang dibuatnya.
  3. Selector Deployment tidak boleh diperlakukan seperti label biasa yang bebas berubah.

Anti-pattern:

selector:
  matchLabels:
    app: api

Label terlalu generik. Dalam namespace besar, app: api mudah bertabrakan.

Lebih aman:

selector:
  matchLabels:
    app.kubernetes.io/name: payments-api
    app.kubernetes.io/component: api

Jangan masukkan label yang berubah per version ke selector, misalnya:

# Buruk untuk selector Deployment
app.kubernetes.io/version: "v2"

Kalau version masuk selector, rollout akan berubah menjadi relasi ownership yang rapuh.


5.2 template

spec.template adalah Pod template. Perubahan pada Pod template menghasilkan revision baru dan biasanya memicu rollout.

Contoh perubahan yang memicu rollout:

  • image tag/digest berubah
  • env var berubah
  • ConfigMap/Secret name berubah
  • resource request/limit berubah
  • probe berubah
  • label/annotation pada Pod template berubah
  • command/args berubah
  • volume mount berubah

Contoh perubahan yang tidak menghasilkan Pod revision baru:

  • perubahan spec.replicas
  • perubahan field metadata Deployment di luar Pod template
  • perubahan beberapa field strategy tanpa mengubah template

Inilah alasan annotation seperti ini sering dipakai untuk memaksa rollout saat ConfigMap berubah:

spec:
  template:
    metadata:
      annotations:
        checksum/config: "sha256:abc123..."

Jika ConfigMap dipasang sebagai volume, kubelet dapat memperbarui file eventually. Tetapi banyak aplikasi tidak reload otomatis. Dengan checksum annotation di Pod template, perubahan konfigurasi menghasilkan Pod baru secara eksplisit.


5.3 replicas

replicas adalah desired count. Namun jumlah aktual selama rollout bisa melebihi replicas karena maxSurge, atau kurang dari replicas karena maxUnavailable.

replicas = steady-state target
current pods during rollout = replicas +/- strategy allowance

Jangan membaca “ada lebih banyak Pod dari replicas” sebagai bug sebelum mengecek rollout strategy.


5.4 minReadySeconds

minReadySeconds menyatakan durasi minimal Pod harus Ready tanpa crash sebelum dianggap Available.

Tanpa minReadySeconds, Pod yang sebentar Ready lalu crash bisa membuat rollout tampak terlalu optimistis.

Gunakan ini saat:

  • aplikasi butuh warm-up cache
  • readiness cepat hijau tetapi error rate baru tampak setelah traffic masuk
  • dependency connection pool butuh stabil
  • startup selesai tetapi runtime belum benar-benar steady

Namun jangan terlalu besar tanpa alasan. Nilai terlalu besar memperlambat rollout dan bisa memicu progress deadline.


5.5 progressDeadlineSeconds

progressDeadlineSeconds adalah batas waktu Deployment dianggap tidak membuat progress. Jika rollout tidak bergerak dalam batas ini, Deployment dapat menandai kondisi Progressing=False dengan reason seperti ProgressDeadlineExceeded.

Ini bukan rollback otomatis. Ini sinyal bahwa automation atau operator harus bereaksi.

Progress deadline is a failure detector, not a magic recovery system.

Nilainya harus disesuaikan dengan:

  • waktu image pull
  • waktu scheduling
  • startup time
  • readiness stabilization
  • minReadySeconds
  • dependency warm-up
  • cluster capacity

5.6 revisionHistoryLimit

revisionHistoryLimit menentukan berapa banyak ReplicaSet lama yang disimpan untuk rollback.

Terlalu kecil:

  • rollback ke versi lebih lama tidak tersedia
  • forensic comparison lebih sulit

Terlalu besar:

  • object lama menumpuk
  • kebisingan saat debugging

Baseline umum: 3–10, bergantung frekuensi deploy dan compliance/audit model. Untuk sistem regulated, revision history di Kubernetes tidak boleh menjadi satu-satunya audit trail. Tetap butuh Git commit, artifact digest, deployment event, approval, dan change record.


6. Rolling Update Math

Deployment mendukung strategi RollingUpdate dan Recreate. Untuk RollingUpdate, dua field utama adalah:

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 25%
    maxUnavailable: 25%

6.1 maxSurge

maxSurge adalah jumlah Pod tambahan di atas desired replicas yang boleh dibuat selama rollout.

Jika:

replicas = 10
maxSurge = 30%

Maka new ReplicaSet dapat naik sehingga total Pod tidak melebihi:

10 + ceil(30% of 10) = 13

maxSurge membantu menjaga availability karena Pod baru dibuat sebelum Pod lama dikurangi.


6.2 maxUnavailable

maxUnavailable adalah jumlah Pod desired yang boleh unavailable selama rollout.

Jika:

replicas = 10
maxUnavailable = 20%

Maka minimal available selama rollout adalah:

10 - floor(20% of 10) = 8

Untuk workload critical, sering dipakai:

maxSurge: 25%
maxUnavailable: 0

Konsekuensinya: rollout butuh kapasitas ekstra. Jika cluster tidak punya kapasitas, rollout bisa stuck karena tidak bisa membuat Pod baru.


6.3 Availability vs Capacity Trade-off

StrategyAvailabilityCapacity NeedRollout SpeedRisiko
maxSurge: 0, maxUnavailable: 25%Lebih rendahTidak perlu ekstra besarSedangAda penurunan kapasitas serving
maxSurge: 25%, maxUnavailable: 25%SedangButuh ekstraCepatCampuran availability/capacity
maxSurge: 25%, maxUnavailable: 0TinggiButuh ekstraSedangStuck jika cluster penuh
maxSurge: 100%, maxUnavailable: 0Sangat tinggiButuh kapasitas 2xCepatMahal, bisa overload dependency

Deployment strategy bukan keputusan Kubernetes saja. Ini keputusan reliability dan capacity planning.


7. Rollout Lifecycle

Saat Pod template berubah, Deployment melakukan transisi dari ReplicaSet lama ke ReplicaSet baru.

Rollout selesai ketika:

  1. updated replicas mencapai desired replicas
  2. old replicas turun ke 0
  3. available replicas memenuhi expectation
  4. Deployment observed generation sudah menyusul generation terbaru

Operationally:

kubectl rollout status deployment/payments-api -n payments --timeout=10m
kubectl get deployment payments-api -n payments
kubectl describe deployment payments-api -n payments
kubectl get rs -n payments -l app.kubernetes.io/name=payments-api
kubectl get pods -n payments -l app.kubernetes.io/name=payments-api -o wide

8. Status Fields yang Harus Bisa Dibaca

kubectl get deployment sering menampilkan kolom seperti:

NAME           READY   UP-TO-DATE   AVAILABLE   AGE
payments-api   5/6     6            5           3d

Maknanya:

FieldMakna
READYPod yang Ready dibanding desired replicas.
UP-TO-DATEPod yang dibuat dari template terbaru.
AVAILABLEPod yang available, memperhitungkan readiness dan minReadySeconds.
AGEUmur Deployment object.

Di status object:

FieldMakna
observedGenerationGeneration terakhir yang sudah diproses controller.
replicasTotal replicas yang dikelola.
updatedReplicasReplicas dari template terbaru.
readyReplicasReplicas yang Ready.
availableReplicasReplicas yang Available.
unavailableReplicasReplicas yang belum available.
conditionsSinyal tingkat tinggi: progressing, available, replica failure.

Jika metadata.generation lebih besar dari status.observedGeneration, controller belum memproses perubahan terbaru. Jangan langsung menyimpulkan rollout gagal.


9. Deployment Conditions

Deployment conditions adalah ringkasan controller terhadap state.

Contoh:

kubectl describe deployment payments-api -n payments

Output dapat mencakup:

Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable

Tiga condition penting:

ConditionArti
ProgressingDeployment sedang atau sudah membuat progress terhadap revision baru.
AvailableDeployment memenuhi minimum availability.
ReplicaFailureAda kegagalan membuat atau menghapus Pod.

Reason yang sering muncul:

ReasonInterpretasi
NewReplicaSetCreatedReplicaSet baru dibuat.
ReplicaSetUpdatedReplicaSet diskalakan.
NewReplicaSetAvailableReplicaSet baru tersedia.
ProgressDeadlineExceededRollout tidak progress dalam deadline.
MinimumReplicasAvailableMinimum availability terpenuhi.
FailedCreateReplicaSet gagal membuat Pod.

Condition bukan pengganti investigasi. Condition memberi entry point.


10. Revision Semantics

Deployment mencatat revision melalui annotation pada ReplicaSet, misalnya:

deployment.kubernetes.io/revision: "7"

Melihat history:

kubectl rollout history deployment/payments-api -n payments

Melihat detail revision:

kubectl rollout history deployment/payments-api -n payments --revision=7

Rollback ke revision sebelumnya:

kubectl rollout undo deployment/payments-api -n payments

Rollback ke revision tertentu:

kubectl rollout undo deployment/payments-api -n payments --to-revision=6

Yang perlu dipahami:

  1. Revision terkait Pod template.
  2. Rollback membuat template Deployment kembali ke revision sebelumnya.
  3. Rollback juga merupakan rollout baru secara operasional.
  4. Rollback tidak otomatis mengembalikan state eksternal seperti database schema, Kafka message format, cache content, atau third-party dependency behavior.

Karena itu, rollback aplikasi harus dibedakan dari rollback sistem secara keseluruhan.


11. Pause dan Resume

Deployment bisa dipause:

kubectl rollout pause deployment/payments-api -n payments

Saat paused, perubahan pada Deployment dapat dikumpulkan tanpa langsung memicu rollout. Setelah siap:

kubectl rollout resume deployment/payments-api -n payments

Use case:

  • menggabungkan beberapa perubahan template menjadi satu rollout
  • investigasi saat rollout menunjukkan sinyal buruk
  • manual gate sebelum exposure lebih lanjut

Anti-pattern:

Membiarkan Deployment paused tanpa alert atau ownership jelas.

Deployment paused terlalu lama menciptakan state ambigu: desired YAML bisa sudah berubah, tetapi runtime belum bergerak.

Governance yang sehat:

  • semua paused Deployment harus punya owner
  • harus ada annotation alasan pause
  • harus ada alert untuk pause terlalu lama
  • GitOps controller harus sadar atau dikonfigurasi agar tidak melawan manual pause

12. Scaling During Rollout

Jika Deployment diskalakan saat rollout berlangsung, controller akan menyesuaikan ReplicaSet lama dan baru agar proporsi rollout tetap masuk akal.

Contoh:

kubectl scale deployment/payments-api -n payments --replicas=12

Hal yang harus diperhatikan:

  1. HPA dapat mengubah replicas saat rollout.
  2. Autoscaling saat rollout dapat memperbesar blast radius jika versi baru bermasalah.
  3. Metric HPA yang memburuk karena versi baru dapat menyebabkan scale-up versi baru juga.
  4. Capacity planning harus memperhitungkan replicas + maxSurge + HPA maxReplicas.

Rule of thumb:

Untuk workload critical, uji interaksi rollout strategy, HPA, PDB, dan cluster autoscaler secara eksplisit.

13. Deployment vs Service: Jangan Campur Release dan Routing

Deployment mengelola Pod. Service mengarahkan traffic ke Pod yang match selector.

Rolling update dengan satu Deployment biasanya membuat Service melihat Pod lama dan baru secara bersamaan. Traffic split-nya tidak selalu presisi 50/50 atau berdasarkan version; traffic diarahkan ke endpoint yang ready.

Jika butuh kontrol traffic versi secara presisi, Deployment saja tidak cukup. Kita butuh layer routing tambahan seperti:

  • Service selector switch
  • Ingress/Gateway routing
  • service mesh
  • progressive delivery controller
  • feature flag
  • external load balancer

Ini akan dibahas lebih jauh di Part 010 dan Part 011.


14. Failure Mode: Bad Image

Gejala:

ImagePullBackOff
ErrImagePull

Diagnosis:

kubectl get pods -n payments -l app.kubernetes.io/name=payments-api
kubectl describe pod <pod> -n payments
kubectl get events -n payments --sort-by=.lastTimestamp

Penyebab umum:

  • image tag salah
  • image belum dipush
  • registry credential salah
  • imagePullSecret tidak tersedia
  • registry rate limit
  • node tidak bisa reach registry
  • policy admission menolak image

Mitigasi desain:

  • deploy by digest untuk immutability
  • validasi image exists sebelum apply
  • admission policy untuk registry allowlist
  • image signing/provenance di supply chain
  • canary kecil sebelum rollout luas

15. Failure Mode: Failing Readiness

Gejala:

READY 0/1
Deployment updatedReplicas naik tetapi availableReplicas tidak naik

Diagnosis:

kubectl describe pod <pod> -n payments
kubectl logs <pod> -n payments -c app
kubectl exec -n payments <pod> -- curl -s localhost:8080/health/ready

Penyebab umum:

  • dependency database tidak reachable
  • migration belum kompatibel
  • config salah
  • secret missing
  • app binding ke port yang salah
  • readiness endpoint terlalu strict
  • NetworkPolicy memblokir dependency
  • DNS issue

Prinsip:

Readiness should answer: can this Pod receive real traffic now?

Readiness tidak boleh hanya process is alive. Itu tugas liveness.


16. Failure Mode: Liveness Membunuh Pod yang Sebenarnya Sedang Start

Gejala:

CrashLoopBackOff
Last State: Terminated
Reason: Error
Events: Liveness probe failed

Penyebab:

  • startup lambat
  • liveness probe terlalu cepat aktif
  • threshold terlalu agresif
  • endpoint health bergantung dependency eksternal

Mitigasi:

  • gunakan startupProbe
  • jangan membuat liveness bergantung pada dependency eksternal yang flappy
  • gunakan readiness untuk traffic gating
  • gunakan liveness hanya untuk deadlock/hang yang tidak recoverable

Model sehat:

startupProbe: apakah app sudah selesai bootstrap?
readinessProbe: apakah app boleh menerima traffic?
livenessProbe: apakah process perlu direstart karena stuck?

17. Failure Mode: Stuck Karena Tidak Ada Capacity

Gejala:

Pod Pending
0/10 nodes are available: insufficient cpu, insufficient memory

Khususnya sering terjadi dengan:

maxUnavailable: 0
maxSurge: 25%

Strategi ini butuh kapasitas ekstra. Jika cluster penuh, Pod baru tidak bisa dijadwalkan, Pod lama tidak boleh diturunkan karena maxUnavailable: 0, maka rollout stuck.

Pilihan mitigasi:

  1. Sediakan headroom cluster.
  2. Aktifkan cluster autoscaler dengan limit yang cukup.
  3. Turunkan request jika memang overestimated.
  4. Pakai maxUnavailable kecil jika availability masih bisa diterima.
  5. Gunakan maintenance window untuk workload besar.
  6. Pakai rollout batch lebih kecil.

Trade-off:

Availability tinggi sering dibayar dengan capacity headroom.

18. Failure Mode: Quota dan LimitRange

Gejala:

Error creating: pods "..." is forbidden: exceeded quota

Penyebab:

  • namespace ResourceQuota sudah penuh
  • request/limit tidak memenuhi LimitRange
  • jumlah object melebihi quota
  • ephemeral storage request/limit tidak sesuai

Diagnosis:

kubectl describe quota -n payments
kubectl describe limitrange -n payments
kubectl describe rs <new-rs> -n payments

Design implication:

  • quota harus memperhitungkan surge rollout
  • environment production butuh quota headroom
  • platform harus menguji deployment under quota, bukan hanya steady state

Jika replicas = 20 dan maxSurge = 25%, quota harus mampu menampung 25 Pod, bukan hanya 20.


19. Failure Mode: Selector Collision

Gejala:

  • Deployment mengelola Pod yang tidak seharusnya
  • ReplicaSet count aneh
  • Service mengirim traffic ke Pod dari aplikasi lain
  • rollout tampak berhasil tetapi traffic error campur

Diagnosis:

kubectl get pods -n payments --show-labels
kubectl get rs -n payments --show-labels
kubectl describe deployment payments-api -n payments
kubectl get endpointslice -n payments -l kubernetes.io/service-name=payments-api

Penyebab:

  • label terlalu generik
  • selector Service terlalu luas
  • copy-paste manifest
  • environment label masuk selector secara tidak konsisten

Mitigasi:

  • gunakan label taxonomy standar
  • selector hanya memakai identity stabil
  • validasi dengan admission policy
  • review object graph pada CI

20. Failure Mode: Slow Termination dan Dropped Requests

Saat rollout menurunkan Pod lama, Pod menerima termination signal. Jika app tidak drain dengan benar, request bisa terputus.

Urutan ideal:

Mitigasi:

  • app handle SIGTERM
  • readiness menjadi false saat draining
  • terminationGracePeriodSeconds cukup
  • preStop hanya membantu, bukan pengganti graceful shutdown app
  • load balancer drain delay dipahami
  • long-running request punya timeout dan idempotency

Anti-pattern:

kill -9 mindset in distributed traffic systems.

21. Rollout Debugging Workflow

Gunakan workflow tetap agar tidak lompat-lompat.

Step 1 — Lihat status Deployment

kubectl get deployment payments-api -n payments
kubectl describe deployment payments-api -n payments

Cari:

  • desired vs ready
  • updated vs available
  • conditions
  • events
  • old/new ReplicaSet

Step 2 — Lihat ReplicaSet

kubectl get rs -n payments -l app.kubernetes.io/name=payments-api
kubectl describe rs <new-rs> -n payments

Cari:

  • ReplicaSet mana revision terbaru
  • apakah Pod dibuat
  • apakah ada FailedCreate
  • apakah selector match

Step 3 — Lihat Pod

kubectl get pods -n payments -l app.kubernetes.io/name=payments-api -o wide
kubectl describe pod <pod> -n payments

Cari:

  • Pending
  • ImagePullBackOff
  • CrashLoopBackOff
  • readiness failure
  • OOMKilled
  • node placement
  • events

Step 4 — Lihat log dan previous log

kubectl logs <pod> -n payments -c app
kubectl logs <pod> -n payments -c app --previous

--previous penting untuk container yang restart.

Step 5 — Lihat dependency dan traffic

kubectl get svc,endpointslice -n payments
kubectl get networkpolicy -n payments
kubectl top pod -n payments
kubectl top node

Masalah rollout sering bukan Deployment object, tetapi dependency, network, resource, atau policy.


22. Production Rollout Guardrails

Deployment raw memberi primitive. Production safety butuh guardrail tambahan.

GuardrailTujuan
readinessProbe wajibMencegah Pod menerima traffic sebelum siap.
startupProbe untuk slow-startMencegah liveness kill saat bootstrap.
resource requests wajibMembantu scheduler dan capacity planning.
PDB untuk critical workloadMengontrol voluntary disruption.
maxUnavailable sesuai SLOMenjaga minimum capacity.
progressDeadlineSecondsMendeteksi rollout stuck.
immutable image digestMenghindari tag drift.
audit deployment eventTraceability.
alert pada rollout stuckMengurangi MTTR.
rollback runbookRecovery cepat.

Deployment tanpa guardrail akan tampak bekerja di dev, tetapi rapuh di production.


23. Deployment dan PodDisruptionBudget

PodDisruptionBudget atau PDB membatasi voluntary disruption. Ia tidak secara langsung mengatur Deployment rolling update dengan cara yang sama seperti drain node, tetapi dalam praktik, PDB, rollout strategy, dan availability target harus konsisten.

Contoh konflik desain:

replicas = 3
maxUnavailable = 1
PDB minAvailable = 3

PDB meminta semua 3 tersedia untuk voluntary disruption. Rollout strategy mengizinkan 1 unavailable. Keduanya dapat menciptakan ekspektasi operasional yang membingungkan dalam maintenance/drain scenario.

Desain yang lebih jelas:

replicas = 6
Deployment maxUnavailable = 0 or 1
PDB minAvailable = 5

Prinsip:

Deployment strategy, PDB, HPA, and cluster capacity must be designed together.

24. Deployment dengan HPA

Jika HPA mengelola Deployment, jangan terus-menerus mengubah spec.replicas via GitOps tanpa policy jelas. HPA akan update replicas, GitOps bisa mengembalikan, lalu terjadi control loop conflict.

Anti-pattern:

GitOps continuously enforces replicas=3 while HPA tries to scale to 10.

Pilihan desain:

  1. Hilangkan replicas dari manifest untuk workload yang dikelola HPA jika tooling mendukung.
  2. Abaikan diff spec.replicas pada GitOps controller.
  3. Tetapkan min/max di HPA sebagai source of truth scaling.
  4. Dokumentasikan ownership field.

Field ownership adalah konsep penting dalam Kubernetes production:

Not every field should be owned by Git.
Some fields are owned by controllers.
Some fields are observed-only status.

25. Deployment Anti-Patterns

Anti-patternKenapa BerbahayaAlternatif
latest tagTidak immutable, rollback ambigudigest atau version tag immutable
Tidak ada readinessProbeTraffic masuk ke Pod belum siapreadiness endpoint nyata
Liveness terlalu agresifRestart stormstartupProbe + liveness konservatif
Selector generikCollision/adoption risklabel taxonomy stabil
maxUnavailable tinggi untuk workload criticalCapacity serving turungunakan maxUnavailable kecil/0
Tidak ada resource requestsScheduling tidak akuratrequest berbasis profiling
Manual edit child ReplicaSetController overwriteubah Deployment source
Rollback tanpa cek schema compatibilityData corruption / runtime mismatchbackward-compatible migration
ConfigMap berubah tanpa rollout/reloadPod masih pakai config lamachecksum annotation atau reload mechanism
Menganggap rollout sukses = release suksesError bisnis bisa muncul setelah readymetric gate, SLO, canary

26. Deployment Review Checklist

Sebelum approve Deployment production, jawab:

Identity dan Ownership

  • Apakah name dan namespace benar?
  • Apakah label taxonomy konsisten?
  • Apakah selector stabil dan tidak terlalu luas?
  • Apakah Service selector match Pod label yang benar?

Runtime Safety

  • Apakah readinessProbe valid?
  • Apakah startupProbe diperlukan?
  • Apakah livenessProbe tidak terlalu agresif?
  • Apakah termination graceful?
  • Apakah resource requests realistis?

Rollout Safety

  • Apakah maxSurge dan maxUnavailable sesuai SLO?
  • Apakah cluster punya headroom untuk surge?
  • Apakah progressDeadlineSeconds realistis?
  • Apakah minReadySeconds diperlukan?
  • Apakah rollback bisa dilakukan?

Dependency Safety

  • Apakah perubahan kompatibel dengan DB schema?
  • Apakah event/message contract backward-compatible?
  • Apakah cache dan dependency eksternal siap?
  • Apakah NetworkPolicy mengizinkan dependency baru?

Observability

  • Apakah metrics per version tersedia?
  • Apakah logs punya release/build metadata?
  • Apakah alert rollout stuck ada?
  • Apakah dashboard membedakan old/new revision?

27. Lab: Membaca Rollout Seperti Engineer Production

Buat Deployment kecil:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rollout-demo
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: rollout-demo
  template:
    metadata:
      labels:
        app: rollout-demo
    spec:
      containers:
      - name: nginx
        image: nginx:1.27
        ports:
        - containerPort: 80
        readinessProbe:
          httpGet:
            path: /
            port: 80
          periodSeconds: 5

Apply:

kubectl apply -f rollout-demo.yaml
kubectl rollout status deployment/rollout-demo

Update image:

kubectl set image deployment/rollout-demo nginx=nginx:1.28
kubectl get deploy,rs,pod -l app=rollout-demo -w

Simulasikan bad image:

kubectl set image deployment/rollout-demo nginx=nginx:does-not-exist
kubectl rollout status deployment/rollout-demo --timeout=90s
kubectl describe deployment rollout-demo
kubectl get pods -l app=rollout-demo

Rollback:

kubectl rollout undo deployment/rollout-demo
kubectl rollout status deployment/rollout-demo

Yang harus diamati:

  • ReplicaSet lama tidak langsung hilang.
  • New ReplicaSet dibuat saat template berubah.
  • Bad image membuat Pod gagal, bukan Deployment object hilang.
  • Rollback mengubah template kembali.
  • Service tetap bisa mengarah ke Pod lama jika availability masih dijaga.

28. Mental Model Final

Deployment adalah salah satu resource paling sering dipakai di Kubernetes, tetapi juga salah satu yang paling sering diremehkan.

Jangan pikirkan Deployment sebagai:

run this container

Pikirkan sebagai:

maintain N available replicas of this Pod template, transition safely between revisions, and expose enough status for operators to know whether the transition is progressing.

Invariants yang harus selalu diingat:

  1. Deployment mengelola ReplicaSet.
  2. ReplicaSet mengelola Pod.
  3. Pod template change menghasilkan revision baru.
  4. Rollout safety ditentukan oleh readiness, strategy, capacity, dan dependency compatibility.
  5. Rollback Kubernetes tidak sama dengan rollback data atau contract eksternal.
  6. Service traffic mengikuti selector dan endpoint readiness, bukan Deployment revision secara eksplisit.
  7. Deployment controller melakukan reconciliation, bukan menjalankan imperative script.

Jika kita memahami ini, debugging production Deployment menjadi lebih struktural: kita membaca object graph, status, events, dan invariants; bukan sekadar mencoba command acak.


29. Referensi Resmi

  • Kubernetes Documentation — Deployments: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
  • Kubernetes Documentation — ReplicaSet: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
  • Kubernetes Documentation — Managing Workloads / Rollouts: https://kubernetes.io/docs/concepts/workloads/management/
  • Kubernetes Task — Update a Deployment Without Downtime: https://kubernetes.io/docs/tasks/run-application/update-deployment-rolling/
  • Kubernetes API Reference — Deployment v1: https://kubernetes.io/docs/reference/kubernetes-api/apps/deployment-v1/
  • kubectl Reference — rollout: https://kubernetes.io/docs/reference/kubectl/generated/kubectl_rollout/

30. Ringkasan Part 009

Di part ini kita membangun pemahaman bahwa Deployment adalah release controller untuk aplikasi replicated stateless. Fokusnya bukan YAML, tetapi relasi Deployment → ReplicaSet → Pod, revision semantics, rolling update math, status conditions, rollback, pause/resume, dan failure modelling.

Setelah part ini, kita harus bisa:

  • membaca object graph Deployment secara benar
  • menjelaskan kapan revision baru dibuat
  • menghitung efek maxSurge dan maxUnavailable
  • membedakan ready, available, updated, dan desired replicas
  • mendiagnosis rollout stuck secara sistematis
  • mendesain Deployment baseline yang lebih aman untuk production
  • memahami batas rollback Kubernetes terhadap dependency eksternal

Part berikutnya akan membahas release deployment models: rolling, recreate, blue-green, canary, shadow, dan A/B testing. Deployment controller adalah primitive. Release model adalah strategi exposure dan risk management di atas primitive tersebut.

Lesson Recap

You just completed lesson 09 in build core. 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.