Phần 41 đo được một lần đổi ảnh với 200 yêu cầu và 0 lỗi. Bài này đo kỹ hơn: thay đổi từng tham số một để tìm ra thứ nào thật sự tạo ra "không gián đoạn".
Có readinessProbe: ba cấu hình, không mất yêu cầu nào
6 bản, đổi ảnh, gọi HTTP liên tục trong suốt quá trình:
| Cấu hình | Thời gian | Kết quả |
|---|---|---|
maxUnavailable=1, maxSurge=1 |
11,6 giây | 400 OK / 0 lỗi |
maxUnavailable=0, maxSurge=1 |
24,0 giây | 400 OK / 0 lỗi |
maxUnavailable=3, maxSurge=3 |
4,0 giây | 400 OK / 0 lỗi |
Nhanh gấp sáu lần vẫn không mất yêu cầu nào.
Đây là kết quả tôi không chờ đợi. Trực giác nói maxUnavailable=3 — cho phép một nửa số bản biến mất cùng lúc — phải nguy hiểm hơn maxUnavailable=0. Nó không, vì ba bản còn lại vẫn phục vụ đủ.
Cấu hình quyết định tốc độ, không quyết định độ an toàn. Nó chỉ trở thành vấn đề an toàn khi số bản còn lại không gánh nổi tải — và đó là bài toán về năng lực, không phải về Kubernetes.
Bỏ readinessProbe: 8% yêu cầu chết
Cùng cụm, cùng lệnh, nhưng container mất 8 giây mới nghe cổng 80, và không khai readinessProbe:
| Kết quả | ||
|---|---|---|
RollingUpdate 1/1 |
876 OK / 77 lỗi | 8% thất bại |
Recreate |
604 OK / 129 lỗi | 18% thất bại |
Và chi tiết đáng nhớ hơn cả con số: kubectl rollout status báo hoàn tất sau 2,6 giây — trong khi container còn tám giây nữa mới phục vụ được.
Không có readinessProbe, Kubernetes coi pod sẵn sàng ngay khi tiến trình khởi động. Nó đưa pod vào Endpoints, kube-proxy bắt đầu chuyển lưu lượng tới, và không ai nghe ở đầu kia.
Thứ tạo ra "không gián đoạn" là
readinessProbe, không phảiRollingUpdate.
readinessProbe:
httpGet: {path: /, port: 80}
initialDelaySeconds: 3
periodSeconds: 1
Pod chỉ vào Endpoints khi probe qua. Trước đó nó tồn tại, chạy, và không nhận lưu lượng. Đó là toàn bộ cơ chế.
Recreate tệ hơn gấp đôi
18% so với 8%. Recreate xoá hết pod cũ rồi mới tạo pod mới — có một khoảng thời gian thật sự không còn bản nào.
Nó chỉ đúng khi ứng dụng không chạy hai phiên bản cùng lúc được: dùng chung một volume ReadWriteOnce, hoặc chạy migration cơ sở dữ liệu không tương thích ngược.
Với những trường hợp đó, gián đoạn là điều bắt buộc — và bạn nên lên lịch nó thay vì bị bất ngờ.
Ba tham số điều khiển tốc độ
maxUnavailable — bao nhiêu bản được phép thiếu. Mặc định 25%.
maxSurge — bao nhiêu bản thừa được phép tạo tạm. Mặc định 25%.
Hai cái này không được cùng bằng 0 — Kubernetes từ chối, vì khi ấy không có cách nào tiến lên.
minReadySeconds — pod phải Ready liên tục bao lâu mới được tính. Mặc định 0. Đặt 10–30 giây là cách rẻ nhất để chặn một bản hỏng nhanh lan ra toàn bộ: pod khởi động rồi sập sau 5 giây sẽ không bao giờ được tính, và việc triển khai dừng lại.
Khi triển khai bị kẹt
kubectl rollout status deployment/app --timeout=180s
Hết giờ mà chưa xong thường có ba nguyên nhân, và cả ba đều nằm trong describe:
Ảnh không kéo được — ErrImagePull hoặc ImagePullBackOff. Sai tên, sai tag, hoặc thiếu imagePullSecrets.
Probe không bao giờ qua — pod Running nhưng 0/1 READY mãi. Đường dẫn probe sai, cổng sai, hoặc ứng dụng khởi động lâu hơn initialDelaySeconds cho phép.
Không đủ tài nguyên để tạo bản mới — maxSurge cần chỗ trống, và phần 47 đo được bộ lập lịch cộng requests chứ không nhìn mức dùng thật.
kubectl rollout undo deployment/app # lùi lại, 2,3 giây (phần 49)
progressDeadlineSeconds
Mặc định 600 giây. Nếu việc triển khai không tiến triển trong mười phút, Deployment được đánh dấu Progressing=False với lý do ProgressDeadlineExceeded.
Quan trọng: nó không tự quay lui. Nó chỉ đánh dấu. Việc quay lui vẫn là của bạn hoặc của quy trình CI/CD.
Đó là chỗ đáng cắm cảnh báo — một Deployment kẹt mười phút mà không ai biết là một bản triển khai nửa vời đang chạy trên môi trường thật.
Thử ba mươi giây
Kiểm xem deployment của bạn có thật sự không gián đoạn không:
kubectl get deployment <ten> -o jsonpath='{.spec.template.spec.containers[*].readinessProbe}'
Rỗng nghĩa là mọi lần triển khai đều có một cửa sổ mà lưu lượng đi vào pod chưa sẵn sàng. Với ứng dụng khởi động trong nửa giây thì cửa sổ đó nhỏ; với ứng dụng Java khởi động ba mươi giây thì nó là ba mươi giây lỗi ở mỗi bản.
Phần sau đo Service: cách một cái tên DNS biến thành lưu lượng tới đúng pod.