Tại sao không tạo Pod trực tiếp

Pod chết = pod mất. Không ai tạo lại. Bạn cần:

  • ReplicaSet: đảm bảo luôn có N pod chạy.
  • Deployment: quản lý ReplicaSet + rollout/rollback.
Deployment (do bạn tạo)
│
▼
ReplicaSet v2 (current)

Deployment (do bạn tạo)
│
▼
ReplicaSet v1 (replicas=0, giữ lại để rollback)

ReplicaSet v2 (current)
│
▼
Pod 1

ReplicaSet v2 (current)
│
▼
Pod 2

ReplicaSet v2 (current)
│
▼
Pod 3

Deployment spec

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-api
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1 # Tối đa 1 pod không sẵn sàng
      maxSurge: 1 # Tối đa 1 pod thêm (tổng có thể 4)
  template:
    metadata:
      labels:
        app: my-api
    spec:
      containers:
        - name: app
          image: my-api:1.2.0
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              memory: "256Mi"
          readinessProbe: # Quan trọng cho rolling update
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10

Rolling update, cơ chế

Khi bạn đổi image (hoặc bất kỳ field nào trong .spec.template):

1. Deployment controller tạo ReplicaSet mới (v2)
2. Scale up v2 theo maxSurge (thêm 1 pod)
3. Chờ pod v2 Ready (readiness probe pass)
4. Scale down v1 theo maxUnavailable (giảm 1 pod)
5. Lặp lại cho đến khi v2 = 3 pods, v1 = 0 pods
# Trigger update
kubectl set image deploy/my-api app=my-api:1.3.0

# Hoặc edit trực tiếp
kubectl edit deploy my-api

# Hoặc apply file YAML đã sửa
kubectl apply -f deploy.yaml

maxUnavailable và maxSurge

Tham sốGiá trịÝ nghĩa
maxUnavailable1 hoặc 25%Tối đa bao nhiêu pod dưới replicas mong muốn trong quá trình update
maxSurge1 hoặc 25%Tối đa bao nhiêu pod trên replicas mong muốn

Ví dụ: replicas=4, maxUnavailable=1, maxSurge=1:

  • Tại bất kỳ thời điểm: tối thiểu 3 pod ready, tối đa 5 pod tồn tại.

Chiến lược phổ biến:

Mục tiêumaxUnavailablemaxSurge
Zero-downtime (an toàn nhất)01 hoặc 25%
Nhanh nhất25%25%
Tiết kiệm resource10

Rollout commands

# Xem trạng thái rollout
kubectl rollout status deploy/my-api

# Lịch sử revision
kubectl rollout history deploy/my-api
kubectl rollout history deploy/my-api --revision=2   # Chi tiết revision

# Rollback về revision trước
kubectl rollout undo deploy/my-api

# Rollback về revision cụ thể
kubectl rollout undo deploy/my-api --to-revision=3

# Pause rollout (canary thủ công)
kubectl rollout pause deploy/my-api
# ... quan sát pod mới ...
kubectl rollout resume deploy/my-api

# Restart (trigger update mà không đổi image)
kubectl rollout restart deploy/my-api

Revision history

Deployment giữ lại ReplicaSet cũ (replicas=0) để rollback. Giới hạn bằng:

spec:
  revisionHistoryLimit: 10 # Mặc định 10, giữ 10 ReplicaSet cũ

Recreate strategy

Thay vì rolling, dùng Recreate khi app không chạy được 2 version cùng lúc (ví dụ: DB migration incompatible, singleton):

spec:
  strategy:
    type: Recreate # Kill tất cả v1, rồi tạo v2 → có downtime

Deployment vs ReplicaSet, ai quản lý ai

LayerTrách nhiệm
DeploymentQuản lý ReplicaSet, rolling update, rollback, revision history
ReplicaSetĐảm bảo đúng N pod chạy (tạo mới nếu thiếu, xoá nếu thừa)
PodChạy container thực tế

Không nên tạo ReplicaSet trực tiếp, luôn dùng Deployment. Ngoại lệ duy nhất: khi bạn cần controller đặc biệt (StatefulSet, DaemonSet, bài 06).


Readiness probe và rolling update

Rolling update phụ thuộc vào readiness probe. Nếu không có readiness probe:

  • Pod mới start xong là coi như Ready → traffic tới ngay.
  • Nếu app cần warm-up (load cache, connect pool) → user gặp lỗi.
readinessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 5 # Chờ 5s trước probe đầu tiên
  periodSeconds: 10 # Probe mỗi 10s
  failureThreshold: 3 # 3 lần fail → không Ready

Chi tiết probe → Bài 05.


minReadySeconds

Pod Ready chưa chắc đã “ổn”. minReadySeconds bắt Deployment chờ thêm sau khi pod Ready trước khi tiếp tục update:

spec:
  minReadySeconds: 30 # Chờ 30s sau khi Ready, nếu không crash → tiếp

Giúp phát hiện lỗi sớm: nếu pod crash trong 30s đầu, rollout dừng lại.


progressDeadlineSeconds

Nếu rollout không tiến triển trong khoảng thời gian này, Deployment báo ProgressDeadlineExceeded:

spec:
  progressDeadlineSeconds: 600 # Mặc định 600s (10 phút)
kubectl rollout status deploy/my-api
# error: deployment "my-api" exceeded its progress deadline

Nguyên nhân thường gặp: image không tồn tại, readiness probe luôn fail, resource không đủ.


Lab: rolling update trên kind

# Tạo deployment
kubectl create deployment web --image=nginx:1.25 --replicas=3

# Xem pod
kubectl get pods -l app=web -w

# Update image (terminal khác watch)
kubectl set image deploy/web nginx=nginx:1.26

# Xem rollout
kubectl rollout status deploy/web

# Xem ReplicaSet
kubectl get rs -l app=web

# Rollback
kubectl rollout undo deploy/web

# Xem history
kubectl rollout history deploy/web

Tóm tắt

  • Deployment → ReplicaSet → Pod. Luôn dùng Deployment, không tạo RS/Pod trực tiếp.
  • RollingUpdate thay pod cũ bằng pod mới dần dần. maxUnavailable + maxSurge điều khiển tốc độ.
  • Readiness probe là bắt buộc cho rolling update an toàn, không có = traffic tới pod chưa sẵn sàng.
  • rollout undo rollback ngay. revisionHistoryLimit giới hạn số revision giữ lại.
  • minReadySeconds + progressDeadlineSeconds là safety net cho deploy automation.

Câu hỏi hay gặp

Đổi label selector của Deployment có được không?

Trả lời: Không (từ K8s 1.x). .spec.selector là immutable sau khi tạo. Đổi label pattern → tạo Deployment mới, chuyển traffic dần, xoá cũ.

Rollback có phải “deploy lại image cũ” không?

Trả lời: Về cơ bản có, rollout undo scale lên ReplicaSet cũ (đã giữ sẵn, replicas=0). Nhanh hơn rebuild image vì ReplicaSet spec còn đó. Tuy nhiên image vẫn phải còn trên registry.

Deployment update mỗi khi kubectl apply dù không đổi gì?

Trả lời: Nếu .spec.template không đổi, apply chỉ update metadata (annotation kubectl.kubernetes.io/last-applied-configuration), không trigger rollout. Rollout chỉ xảy ra khi template thay đổi.


Bài tiếp theo (Giai đoạn II): Probe health: liveness, readiness, startup, cấu hình đúng, sai cấu hình thì hậu quả gì.