Cách khắc phục nhanh
Nếu các Pod của bạn bị kẹt ở trạng thái Pending do các ràng buộc về topology, bạn thường có hai cách để chúng hoạt động ngay lập tức:
- Chuyển sang ràng buộc mềm (soft constraints): Thay đổi
whenUnsatisfiable: DoNotSchedulethànhwhenUnsatisfiable: ScheduleAnyway. Điều này yêu cầu bộ lập lịch (scheduler) cố gắng hết sức nhưng ưu tiên việc đưa pod vào hoạt động. - Nới lỏng tính toán: Tăng giá trị
maxSkewcủa bạn. Nếu hiện tại là1, hãy thử2. Điều này cho phép phân bổ không đồng đều hơn giữa các node hoặc zone.
# Cập nhật file YAML của deployment:
whenUnsatisfiable: ScheduleAnyway # Thay đổi từ DoNotSchedule
Tại sao lỗi này xảy ra
Kubernetes không thể lập lịch cho pod của bạn vì các quy tắc bạn thiết lập cho tính sẵn sàng cao (high availability) quá khắt khe so với trạng thái cụm hiện tại. Hãy coi đó như một bài toán toán học mà bộ lập lịch không thể giải được. Các nguyên nhân phổ biến bao gồm:
- Bẫy "Cân bằng hoàn hảo": Bạn đặt
maxSkew: 1, nhưng số lượng node của bạn không đồng đều. Ví dụ, việc cố gắng phân bổ 5 pod trên 2 node với skew là 1 là điều không thể về mặt toán học. - Thiếu Label:
topologyKeycủa bạn (nhưtopology.kubernetes.io/zone) không tồn tại trên các node. Nếu bộ lập lịch không tìm thấy label, nó sẽ coi node đó không đủ điều kiện. - Phân mảnh tài nguyên: Bạn có thể có đủ node, nhưng node cụ thể đáng lẽ phải nhận pod để thỏa mãn điều kiện phân bổ lại bị đầy hoặc có taint.
- Chồng lấn Label:
labelSelectorcủa bạn quá rộng. Nếu hai deployment khác nhau dùng chung labelapp: web, Kubernetes sẽ tính tổng tất cả các pod đó khi tính toán phân bổ.
Giải pháp từng bước
1. Kiểm tra các Label của Node
Bộ lập lịch sẽ bị "mù" nếu không có các label phù hợp. Nếu bạn đang phân bổ pod giữa các zone, hãy xác nhận rằng các node của bạn thực sự khai báo chúng nằm ở zone nào.
kubectl get nodes --show-labels
Kiểm tra key được định nghĩa trong file YAML của bạn. Nếu bạn sử dụng topology.kubernetes.io/zone nhưng các node chỉ có kubernetes.io/hostname, ràng buộc sẽ luôn thất bại. Hãy khớp file YAML với các label thực tế trên node.
2. Chuyển sang các ràng buộc mềm
DoNotSchedule là một yêu cầu cứng. Nó rất tốt cho môi trường production quy mô lớn, nhưng có thể làm gián đoạn các cụm nhỏ hơn trong quá trình bảo trì hoặc mở rộng. Thay đổi giá trị này thành ScheduleAnyway cho phép pod được triển khai trên một node ngay cả khi nó vi phạm mức phân bổ lý tưởng.
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app: my-app
3. Tính toán lại maxSkew
Giá trị maxSkew định nghĩa sự chênh lệch tối đa cho phép về số lượng pod giữa hai domain topology bất kỳ. Trong một cụm 3 node, maxSkew: 1 hoạt động hoàn hảo cho 3, 4 hoặc 5 pod. Tuy nhiên, nếu một node bị sập, chính maxSkew: 1 đó có thể ngăn pod thứ 4 được lập lịch trên hai node còn lại. Việc tăng giá trị lên 2 sẽ tạo ra nhiều "không gian thở" hơn khi có sự cố.
4. Cô lập Label Selector
Đảm bảo labelSelector trong ràng buộc của bạn được chỉ định chính xác. Nếu nó quá chung chung, bộ lập lịch sẽ bao gồm cả các pod không liên quan vào tính toán. Sử dụng một label phiên bản hoặc thành phần cụ thể để đảm bảo việc tính toán chỉ áp dụng cho các pod trong deployment cụ thể của bạn.
# Sử dụng label duy nhất để tránh tính toán nhầm các ứng dụng khác
labelSelector:
matchLabels:
app: billing-api
tier: backend
Cách xác minh bản sửa lỗi
Sau khi áp dụng các thay đổi, bạn cần xác nhận rằng các pod đang di chuyển và phân bổ chính xác.
Theo dõi trạng thái Pod
kubectl get pods -w
Các pod của bạn sẽ chuyển từ trạng thái Pending sang Running. Nếu chúng vẫn ở trạng thái Pending, hãy chạy lệnh kubectl describe pod <pod-name> để xem có lỗi mới nào xuất hiện không, ví dụ như Insufficient CPU.
Phân tích sự phân bổ
Chạy lệnh này để xem chính xác có bao nhiêu pod đã được triển khai trên mỗi node:
kubectl get pods -l app=my-app -o custom-columns=NODE:.spec.nodeName | sort | uniq -c
Nếu bạn thấy kết quả như 3 node-a và 2 node-b, skew của bạn là 1. Điều này xác nhận bộ lập lịch đang hoạt động trong phạm vi các tham số mới của bạn.

