Kodeloka
  1. Kodeloka
  2. Kelas Kubernetes
  3. Materi

1 · Fondasi · Modul 2 dari 14

Pod, Deployment & ReplicaSet

Hubungan antara tiga objek yang paling sering Anda sentuh, dan kenapa Anda hampir tidak pernah membuat Pod secara langsung.

Rantai Kepemilikan

Deployment  ──membuat──>  ReplicaSet  ──membuat──>  Pod
(kelola rilis)            (jaga jumlah)           (jalankan kontainer)

Anda membuat Deployment. Deployment membuat ReplicaSet. ReplicaSet membuat Pod. Saat Anda memperbarui image, Deployment membuat ReplicaSet baru dan mengecilkan yang lama secara bertahap — itulah cara rolling update bekerja.

Deployment yang Layak Produksi

apiVersion: apps/v1
kind: Deployment
metadata:
  name: layanan-pesanan
  labels:
    app: layanan-pesanan
spec:
  replicas: 3
  revisionHistoryLimit: 5
  selector:
    matchLabels:
      app: layanan-pesanan        # HARUS cocok dengan label template
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0           # kapasitas tidak pernah turun
  template:
    metadata:
      labels:
        app: layanan-pesanan
    spec:
      containers:
        - name: api
          image: registry.contoh.com/pesanan:2.4.0
          ports:
            - name: http
              containerPort: 8080
          env:
            - name: LINGKUNGAN
              value: produksi
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              memory: 512Mi
          livenessProbe:
            httpGet: { path: /healthz, port: http }
            periodSeconds: 10
            failureThreshold: 3
          readinessProbe:
            httpGet: { path: /readyz, port: http }
            periodSeconds: 5
          lifecycle:
            preStop:
              exec: { command: ["sleep", "5"] }
      terminationGracePeriodSeconds: 45
⚠️ selector bersifat permanen

Field spec.selector tidak bisa diubah setelah Deployment dibuat. Bila Anda perlu mengubahnya, Deployment harus dihapus dan dibuat ulang. Karena itu pilih label selector yang stabil sejak awal — jangan memasukkan nomor versi ke dalamnya.

Label dan Selector

Kubernetes tidak menghubungkan objek lewat referensi langsung, melainkan lewat label. Service menemukan Pod dengan mencocokkan label. ReplicaSet mengklaim Pod dengan mencocokkan label. Ini fleksibel, tetapi juga sumber kebingungan.

# Label yang dianjurkan (konvensi resmi)
metadata:
  labels:
    app.kubernetes.io/name: pesanan
    app.kubernetes.io/instance: pesanan-produksi
    app.kubernetes.io/version: "2.4.0"
    app.kubernetes.io/component: api
    app.kubernetes.io/part-of: platform-toko
# Menyaring dengan selector
kubectl get pods -l app=layanan-pesanan
kubectl get pods -l 'lingkungan in (produksi,staging)'
kubectl get pods -l 'app=pesanan,versi!=2.3.0'
kubectl get pods --show-labels
🚫 Label yang bertabrakan itu berbahaya

Bila dua Deployment berbeda memakai label yang sama, Service akan mengirim trafik ke keduanya, dan ReplicaSet bisa saling "mencuri" pod. Gejalanya sangat membingungkan: sebagian permintaan mendapat respons dari aplikasi yang salah. Selalu sertakan nama aplikasi dan instansi di dalam label.

Mengendalikan Rilis

kubectl set image deploy/layanan-pesanan api=registry.contoh.com/pesanan:2.5.0
kubectl rollout status deploy/layanan-pesanan --timeout=180s
kubectl rollout history deploy/layanan-pesanan
kubectl rollout undo deploy/layanan-pesanan
kubectl rollout undo deploy/layanan-pesanan --to-revision=3

# Menghentikan rilis di tengah jalan
kubectl rollout pause deploy/layanan-pesanan
kubectl rollout resume deploy/layanan-pesanan

# Memaksa pembuatan ulang seluruh pod (misal untuk memuat Secret baru)
kubectl rollout restart deploy/layanan-pesanan
📌 maxUnavailable: 0 vs maxSurge

Dengan maxUnavailable: 0 dan maxSurge: 1, Kubernetes selalu menyalakan pod baru dulu dan menunggunya siap sebelum mematikan yang lama. Kapasitas layanan tidak pernah berkurang selama rilis. Harganya: sementara waktu Anda memakai sumber daya satu pod lebih banyak. Untuk layanan yang menghadap pengguna, ini hampir selalu pertukaran yang tepat.

Jangan Pernah Memakai Tag :latest

🚫 Kenapa :latest merusak segalanya

Kubernetes memutuskan perlu-tidaknya rilis baru dengan membandingkan spesifikasi pod. Bila spesifikasinya tetap app:latest, tidak ada yang berubah — sehingga kubectl apply tidak melakukan apa pun meski image di registry sudah diperbarui. Lebih buruk lagi, pod yang di-restart di waktu berbeda bisa menarik image yang berbeda, sehingga replika Anda tidak lagi menjalankan kode yang sama. Selalu pakai tag versi atau digest.