Lỗi
Error from server (Forbidden): pods "my-pod" is forbidden: exceeded quota: my-quota, requested: cpu=500m, used: cpu=900m, limited: cpu=1
Namespace của bạn có giới hạn ResourceQuota, và pod này đã vượt quá mức đó. Thông báo lỗi nói rõ: giới hạn quota là 1000m CPU, đã dùng 900m, và bạn đang yêu cầu thêm 500m — tổng cộng là 1400m. Kubernetes từ chối ngay lập tức.
Pod không bao giờ vào trạng thái Pending. Nó bị chặn ngay tại API server trước khi scheduler kịp xử lý.
Bước 1: Kiểm tra mức sử dụng Quota hiện tại
Bắt đầu bằng cách xem chính xác lượng đã dùng so với giới hạn cho phép:
# Thay 'my-namespace' bằng namespace thực tế của bạn
kubectl describe resourcequota -n my-namespace
Kết quả trả về có dạng:
Name: my-quota
Namespace: my-namespace
Resource Used Hard
-------- ---- ----
cpu 900m 1
memory 512Mi 2Gi
pods 8 10
CPU là nguyên nhân ở đây — đã dùng 900m trên tổng giới hạn cứng 1000m. Chỉ còn 100m, không đủ cho một pod yêu cầu 500m.
Để quét quota trên tất cả namespace cùng lúc:
kubectl get resourcequota --all-namespaces
Bước 2: Tìm thành phần đang tiêu thụ Quota
Trước khi thay đổi bất cứ thứ gì, hãy xác định các pod nào đang chiếm 900m đó:
kubectl get pods -n my-namespace -o custom-columns=NAME:.metadata.name,CPU:.spec.containers[*].resources.requests.cpu
Đã cài metrics-server? kubectl top hiển thị mức sử dụng thực tế, không chỉ là các request đã khai báo:
kubectl top pods -n my-namespace
Chú ý đến sự chênh lệch. Một pod khai báo request 500m CPU nhưng thực tế chỉ dùng trung bình 30m là mục tiêu điều chỉnh lý tưởng.
Bước 3: Các phương án khắc phục
Phương án A — Giảm Resource Request của Pod
Request khai báo quá cao là nguyên nhân phổ biến nhất. Nếu pod thực sự không cần 500m, hãy giảm xuống trong manifest:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
namespace: my-namespace
spec:
containers:
- name: my-container
image: my-image:latest
resources:
requests:
cpu: "100m" # was 500m, reduced to 100m
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
Chạy kubectl top pods trước để chọn giá trị thực tế. Đặt request là 100m cho pod có mức trung bình 80m sẽ tạo ra khoảng đệm an toàn mà không lãng phí quota.
Phương án B — Tăng giới hạn ResourceQuota
Đôi khi namespace đơn giản là cần thêm tài nguyên. Kiểm tra định nghĩa quota hiện tại trước:
kubectl get resourcequota my-quota -n my-namespace -o yaml
Patch trực tiếp:
kubectl patch resourcequota my-quota -n my-namespace \
--type='json' \
-p='[{"op": "replace", "path": "/spec/hard/cpu", "value": "2"}]'
Hoặc nếu bạn quản lý quota bằng file YAML (cách được khuyến nghị), hãy cập nhật và apply:
apiVersion: v1
kind: ResourceQuota
metadata:
name: my-quota
namespace: my-namespace
spec:
hard:
cpu: "2" # increased from 1 to 2
memory: 4Gi
pods: "20"
kubectl apply -f resourcequota.yaml
Phương án C — Xóa Pod không dùng hoặc Scale Down Deployment
Các pod đã hoàn thành hoặc thất bại vẫn được tính vào quota cho đến khi bị xóa. Hãy dọn sạch những thứ không còn cần thiết:
# Xóa các pod đã hoàn thành/thất bại
kubectl delete pods -n my-namespace --field-selector=status.phase==Succeeded
kubectl delete pods -n my-namespace --field-selector=status.phase==Failed
# Scale down một deployment không còn cần thiết
kubectl scale deployment old-deployment -n my-namespace --replicas=0
Nên kiểm tra điều này trước tiên — một namespace đầy các job Completed cũ có thể âm thầm chiếm hàng trăm millicores. Bạn có thể giải phóng đủ quota mà không cần chạm vào giới hạn.
Bước 4: Xác nhận sau khi sửa
Sau khi thực hiện thay đổi, hãy xác nhận quota còn dư trước khi thử lại:
# Kiểm tra mức sử dụng quota sau khi cập nhật
kubectl describe resourcequota -n my-namespace
# Thử tạo lại pod
kubectl apply -f my-pod.yaml
# Xác nhận pod đang chạy
kubectl get pod my-pod -n my-namespace
Kết quả mong đợi:
NAME READY STATUS RESTARTS AGE
my-pod 1/1 Running 0 10s
Lưu ý để tránh lỗi lần sau
- Luôn đặt resource requests và limits — namespace có ResourceQuota sẽ từ chối các pod không khai báo requests/limits. Dùng
LimitRangeđể đặt giá trị mặc định cho toàn namespace nếu bạn không muốn chỉ định trên từng pod. - Kết hợp LimitRange với ResourceQuota —
LimitRangeđặt giá trị mặc định cho từng container;ResourceQuotagiới hạn tổng tài nguyên của namespace. Hai thứ này được thiết kế để hoạt động cùng nhau. - Tích hợp kiểm tra quota vào CI/CD — thêm bước pre-deploy chạy
kubectl describe resourcequota -n $NAMESPACEvà fail pipeline nếu CPU còn lại thấp hơn lượng request của deployment. - Đặt requests dựa trên số liệu thực tế, không phải ước đoán — dùng
kubectl top podshoặc lấy dữ liệu p95 CPU trong một tuần từ Prometheus. Đó là cơ sở tốt hơn nhiều so với việc cảm tính "500m nghe có vẻ ổn". - Quota là chính sách, không phải giới hạn vật lý — lỗi này có nghĩa là bạn đã chạm trần giới hạn quản trị, không phải thiếu tài nguyên thực sự. Node có thể vẫn còn rất nhiều CPU trống. ResourceQuota hoàn toàn là giới hạn quản trị do cluster admin thiết lập.

