Sự cố triển khai lúc 2 giờ sáng
Bạn vừa đẩy một bản cập nhật quan trọng lên cluster AWS EKS của mình. Pipeline CI/CD hiển thị dấu tích xanh, nhưng năm phút sau, ứng dụng của bạn ngoại tuyến. Bạn chạy lệnh kubectl get pods và thấy một loạt trạng thái Pending. Thời gian trôi qua, nhưng các container vẫn không khởi động.
Khi bạn kiểm tra các sự kiện của pod, bạn thấy điểm nghẽn cụ thể này:
0/3 nodes are available: 3 Insufficient cpu. preemption: 0/3 nodes are available: 3 No preemption victims found for incoming pod.
Lỗi này cho biết bộ lập lịch (scheduler) của Kubernetes đã kiểm tra mọi node và thấy không còn dung lượng CPU trống. Tệ hơn nữa, nó không thể tìm thấy bất kỳ pod ưu tiên thấp nào để chấm dứt (preempt) nhằm nhường chỗ cho bản triển khai mới của bạn. Cluster của bạn thực tế đã đầy.
Bước 1: Gỡ lỗi việc sử dụng tài nguyên "ma"
Một điểm gây nhầm lẫn phổ biến là thấy một node có mức sử dụng CPU thực tế thấp nhưng vẫn từ chối các pod mới. Kubernetes lập lịch dựa trên Requests, không phải mức tiêu thụ thời gian thực. Nếu một node có 2 vCPUs và bạn có bốn pod, mỗi pod yêu cầu 450m CPU, thì node đó đã đầy 90% trong mắt bộ lập lịch—ngay cả khi các pod đó hiện đang ở trạng thái nhàn rỗi với mức sử dụng 1%.
Phân tích Pod Resource Requests
Kiểm tra chính xác lượng CPU mà pod đang chờ xử lý của bạn yêu cầu. Tìm phần Requests trong kết quả đầu ra:
kubectl describe pod <pod-name> | grep -A 5 "Requests:"
Kiểm tra dung lượng Node
Tiếp theo, hãy xem bao nhiêu CPU đã được "đặt trước" trên các node của bạn. Lệnh này xác định khoảng cách giữa những gì thực tế hiện có và những gì được phân bổ về mặt logic:
kubectl describe nodes | grep -A 10 "Allocated resources:"
Nếu cột "CPU Requests" hiển thị 90% hoặc cao hơn, bộ lập lịch sẽ từ chối bất kỳ pod nào không vừa với phần dung lượng ít ỏi còn lại.
Bước 2: Các biện pháp khắc phục ngay lập tức
Tùy chọn A: Điều chỉnh kích thước Pod Request phù hợp
Các nhà phát triển thường thiết lập CPU requests dựa trên phán đoán cảm tính. Nếu microservice của bạn thực tế chỉ sử dụng 50m (0.05 cores) nhưng manifest của bạn lại yêu cầu 1000m (1 core đầy đủ), bạn đang lãng phí 95% tài nguyên đã trả phí. Hãy điều chỉnh tệp deployment.yaml của bạn để phản ánh thực tế:
spec:
containers:
- name: api-server
resources:
requests:
cpu: "250m" # Giảm từ 1000m
memory: "512Mi"
limits:
cpu: "1000m"
memory: "1Gi"
Áp dụng bản cập nhật: kubectl apply -f deployment.yaml. Nếu yêu cầu mới phù hợp với phần tài nguyên dư thừa hiện có, Kubernetes sẽ lập lịch cho pod ngay lập tức.
Tùy chọn B: Mở rộng thủ công
Nếu các yêu cầu tài nguyên của bạn đã chính xác, bạn chỉ cần thêm phần cứng. Bạn có thể tăng kích thước của Node Group theo cách thủ công thông qua AWS CLI. Ví dụ: để tăng một cluster từ 3 node lên 5 node:
aws autoscaling update-auto-scaling-group \
--auto-scaling-group-name <your-eks-asg-name> \
--desired-capacity 5
Các thực thể EC2 mới thường mất từ 2 đến 3 phút để gia nhập cluster. Khi chúng hiển thị trạng thái Ready, bộ lập lịch sẽ tự động chuyển các pod của bạn từ Pending sang Running.
Bước 3: Ngăn ngừa dài hạn
Triển khai Karpenter để mở rộng tức thì
Mở rộng thủ công là nguyên nhân dẫn đến thời gian ngừng hoạt động. Các thiết lập EKS hiện đại sử dụng Karpenter. Không giống như Cluster Autoscaler cũ, Karpenter không chỉ thêm các node vào một nhóm. Nó xem xét các pod đang chờ xử lý và cung cấp chính xác loại thực thể EC2 cần thiết—như c5.large cho các tác vụ nặng về tính toán hoặc r5.large cho các tác vụ tiêu tốn nhiều bộ nhớ—và có thể khởi chạy chúng trong vòng chưa đầy một phút.
Sử dụng Vertical Pod Autoscaler (VPA)
Nếu bạn không chắc chắn CPU requests nên là bao nhiêu, hãy chạy VPA ở chế độ Recommendation. Nó theo dõi dữ liệu sử dụng trong lịch sử và cung cấp một giá trị gợi ý. Điều này ngăn chặn lỗi "Insufficient CPU" gây ra bởi việc cấp phát dư thừa "cho chắc chắn".
Xác minh
Xác nhận việc khắc phục bằng cách theo dõi vòng đời của pod:
kubectl get pods -w
Trạng thái sẽ chuyển từ Pending sang ContainerCreating và cuối cùng là Running. Để xem chính xác pod được đặt ở đâu, hãy sử dụng cờ -o wide:
kubectl get pod <pod-name> -o wide
Những điểm chính cần lưu ý
- Bộ lập lịch là một công cụ tính toán: Nó chỉ quan tâm đến
requests. Nó không xem xét lượng CPU mà ứng dụng của bạn thực tế đang sử dụng tại thời điểm đó. - Tính toán đến tài nguyên dự phòng của EKS: Một thực thể
t3.mediumcó 2 vCPUs, nhưng EKS dự phòng khoảng 190m CPU cho hệ thống. Bạn chỉ có khoảng 1.81 vCPUs khả dụng cho các pod của mình. - Tự động hóa hoặc thất bại: Chạy các khối lượng công việc production mà không có Karpenter hoặc Cluster Autoscaler sẽ dẫn đến việc phải can thiệp thủ công và gây ra sự cố ngừng hoạt động.
- Cảnh báo: Thiết lập cảnh báo Prometheus cho
kube_pod_status_phase{phase="Pending"}. Điều này giúp phát hiện các vấn đề về dung lượng trước khi người dùng của bạn nhận ra.

