PodDisruptionBudget bảo Kubernetes: đừng đuổi quá nhiều bản cùng lúc. Bài này đo nó bằng cách rút node ra bảo trì ba lần với ba cấu hình.
Cùng một lệnh, ba kết quả
Deployment 4 bản, rút một node ra bảo trì:
kubectl drain |
|
|---|---|
| không có PDB | 2,1 giây |
PDB minAvailable: 4 |
không bao giờ xong |
PDB minAvailable: 3 |
6,6 giây |
Với minAvailable: 4 trên 4 bản:
cho-phep-duoi = 0
error when evicting pods/"pdb-...-m8bw4" -n "default": global timeout reached: 45s
error when evicting pods/"pdb-...-sns95" -n "default": global timeout reached: 45s
Một con số sai và node không bao giờ rút ra được.
Kubernetes không báo lỗi cấu hình — PDB đó hoàn toàn hợp lệ. Nó chỉ nghĩa là "không được đuổi bản nào", và drain tôn trọng điều đó mãi mãi.
Cột cho-phep-duoi là thứ nói thật
minAvailable=4 trên 4 bản -> cho-phep-duoi = 0 KẸT
minAvailable=3 trên 4 bản -> cho-phep-duoi = 1 chạy được
maxUnavailable=1 trên 4 bản -> cho-phep-duoi = 1 chạy được
kubectl get pdb
Cột ALLOWED DISRUPTIONS bằng 0 nghĩa là mọi việc bảo trì liên quan tới pod đó sẽ treo. Đây là một con số nên có trên bảng theo dõi, vì nó là dạng cấu hình sai không gây triệu chứng gì cho tới ngày bạn cần nâng cấp cụm.
maxUnavailable an toàn hơn minAvailable
minAvailable: 3 -> cố định
maxUnavailable: 1 -> luôn cho phép một, bất kể số bản
Với ứng dụng có HPA (phần 66), minAvailable là quả bom hẹn giờ:
- Giờ cao điểm: 10 bản,
minAvailable: 3→ cho phép đuổi 7. Rộng rãi. - Đêm tải thấp: HPA thu gọn về 3 bản → cho phép đuổi 0. Kẹt.
Và nó chỉ nổ vào đêm tải thấp — đúng lúc bạn muốn bảo trì.
maxUnavailable: 1 không có vấn đề đó: dù 3 bản hay 10 bản, luôn cho phép đuổi một.
Dùng tỉ lệ phần trăm cũng được nhưng cần cẩn thận: maxUnavailable: 25% trên 3 bản cho phép đuổi floor(0,75) = 0 — lại kẹt.
PDB chỉ áp cho việc đuổi tự nguyện
Đây là giới hạn quan trọng nhất và hay bị hiểu sai.
PDB chặn được:
kubectl drain(bảo trì node)- Cluster Autoscaler thu gọn (phần 68)
- VPA giết pod để đổi
requests(phần 67) - Bất cứ thứ gì dùng API
eviction
PDB không chặn được:
- Node chết đột ngột (phần 42)
OOMKilled(phần 54)kubeletđuổi pod vì node hết RAM (phần 53)kubectl delete podtrực tiếp- Vết
NoExecute(phần 69 — đuổi trong 1,3 giây, không hỏi PDB)
Nghĩa là PDB không phải cơ chế bảo đảm tính sẵn sàng. Nó chỉ ngăn các công cụ tự động làm hỏng dịch vụ khi chúng đang làm việc theo kế hoạch.
Muốn sống sót qua sự cố thật thì cần đủ bản và rải chúng ra (phần 69), không phải PDB.
PDB cho StatefulSet là bắt buộc
Với Deployment không trạng thái, mất một bản trong lúc bảo trì thường chấp nhận được.
Với StatefulSet chạy hệ thống đồng thuận — etcd, ZooKeeper, cơ sở dữ liệu có bầu chọn — mất hai bản cùng lúc là mất quorum, và cụm ngừng hoạt động.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata: {name: db}
spec:
maxUnavailable: 1
selector: {matchLabels: {app: db}}
maxUnavailable: 1 là con số đúng cho gần như mọi hệ thống ba bản: chịu được bảo trì tuần tự, không bao giờ mất quorum.
PDB không có selector khớp thì vô dụng
kubectl get pdb <ten> -o jsonpath='{.status.currentHealthy}'
Bằng 0 với deployment đang chạy nghĩa là selector không khớp pod nào — thường vì nhãn gõ sai.
PDB đó tồn tại, trông có vẻ đang bảo vệ, và không bảo vệ gì cả. Không có cảnh báo nào cho trường hợp này.
Ba con số nên kiểm định kỳ
kubectl get pdb -A -o custom-columns=\
NS:.metadata.namespace,TEN:.metadata.name,\
MIN:.spec.minAvailable,MAX:.spec.maxUnavailable,\
KHOE:.status.currentHealthy,\
CHO_PHEP:.status.disruptionsAllowed
KHOEbằng 0 → selector sai, PDB vô dụng.CHO_PHEPbằng 0 → mọi bảo trì sẽ treo.MINcó giá trị và ứng dụng có HPA → sẽ kẹt vào giờ tải thấp.
Ba dòng lệnh này đáng chạy trước mỗi lần nâng cấp cụm — chúng biến một sự cố bảo trì lúc nửa đêm thành một sửa đổi cấu hình lúc chiều.
Thử ba mươi giây
Thử xem cụm của bạn có rút node ra được không, mà không thật sự rút:
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data --dry-run=server
--dry-run=server cho Kubernetes tính toán đầy đủ mà không đuổi ai. Nếu nó báo pod nào không đuổi được, đó chính xác là thứ sẽ chặn bạn vào lần bảo trì thật.
Phần sau đo RBAC: ai được làm gì, và cách tìm ra quyền thừa.