Sau bài này bạn làm được: deploy app lên cluster với zero-downtime rolling update; rollback phiên bản lỗi trong 10 giây; hiểu relationship Deployment → ReplicaSet → Pod.
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 (bạn tạo)
└── ReplicaSet v2 (Deployment tạo) ← current
│ ├── Pod 1
│ ├── Pod 2
│ └── Pod 3
└── ReplicaSet v1 (giữ lại để rollback, replicas=0)
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 |
|---|---|---|
maxUnavailable | 1 hoặc 25% | Tối đa bao nhiêu pod dưới replicas mong muốn trong quá trình update |
maxSurge | 1 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êu | maxUnavailable | maxSurge |
|---|---|---|
| Zero-downtime (an toàn nhất) | 0 | 1 hoặc 25% |
| Nhanh nhất | 25% | 25% |
| Tiết kiệm resource | 1 | 0 |
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
| Layer | Trách nhiệm |
|---|---|
| Deployment | Quả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) |
| Pod | Chạ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 undorollback ngay.revisionHistoryLimitgiới hạn số revision giữ lại.minReadySeconds+progressDeadlineSecondslà 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ì.