Resource Requests/Limits và Autoscaling (HPA)
Hai chuyện gắn bó: muốn Kubernetes autoscale theo tải, trước hết mỗi pod phải khai báo nó cần bao nhiêu tài nguyên. Bài này đi từ requests/limits (nền tảng để scheduler và autoscaler làm việc) tới HorizontalPodAutoscaler — và ta sẽ tạo tải thật để tận mắt thấy cluster tự thêm pod.
requests và limits: hai con số, hai vai trò
Trong spec container, bạn khai báo tài nguyên qua hai khái niệm thường bị nhầm:
resources:
requests: # mức ĐẢM BẢO — scheduler dựa vào đây để chọn node
cpu: 200m # 200 milli-CPU = 0.2 lõi
memory: 64Mi
limits: # mức TRẦN — vượt sẽ bị chặn/giết
cpu: 500m
memory: 128Mi
requestslà mức tài nguyên đảm bảo dành cho pod. Scheduler (Bài 1) dùng con số này để quyết định node nào còn đủ chỗ — pod chỉ được đặt lên node có đủrequestscòn trống. Đây là điều giúp Kubernetes xếp pod hợp lý mà không nhồi quá tải một node.limitslà trần. Vượt limit CPU → container bị throttle (chậm lại, không bị giết). Vượt limit memory → container bị OOMKilled (giết vì hết bộ nhớ). Limit bảo vệ cluster khỏi một pod lỗi ngốn sạch tài nguyên hàng xóm.
Đơn vị: CPU tính theo lõi,
1= một lõi,500m= nửa lõi (m = milli). Memory theo byte với hậu tốMi/Gi(mebibyte/gibibyte).
Việc đặt requests đúng quan trọng hơn người mới nghĩ: đặt quá thấp thì node bị nhồi quá tải (pod tranh nhau, chậm); đặt quá cao thì lãng phí (node trống mà scheduler tưởng đầy). Và như sẽ thấy, HPA cần requests để tính phần trăm sử dụng.
QoS: thứ tự bị "hi sinh" khi node cạn tài nguyên
Cách bạn đặt requests/limits quyết định QoS class của pod — và khi node hết bộ nhớ, Kubernetes giết pod theo lớp này:
- Guaranteed (requests = limits): được bảo vệ nhất, bị giết sau cùng.
- Burstable (có requests < limits): ở giữa.
- BestEffort (không khai báo gì): bị giết đầu tiên khi node thiếu tài nguyên.
Bài học: pod quan trọng nên đặt requests/limits rõ ràng để không bị xem là "hàng bỏ đi" lúc khủng hoảng.
HorizontalPodAutoscaler: tự tăng/giảm số pod
Scale tay bằng kubectl scale (Bài 4) là phản ứng thủ công. HPA tự động hoá: nó theo dõi một chỉ số (thường là CPU) và tự đổi số replicas để giữ chỉ số quanh mức mục tiêu. Tải cao → thêm pod; tải hạ → bớt pod.
HPA cần biết tải hiện tại, mà nguồn số liệu là metrics-server. Cluster trắng không có sẵn — trên minikube bật bằng addon:
minikube addons enable metrics-server
Có metrics-server rồi, kubectl top mới hoạt động:
kubectl top pods -l run=php-apache
NAME CPU(cores) MEMORY(bytes)
php-apache-69b4854d9f-t44x4 11m 21Mi
Dựng HPA và tạo tải thật
Triển khai một app demo (image hpa-example — một trang PHP cố tình tốn CPU mỗi request) với requests.cpu: 200m, rồi gắn HPA:
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=5
kubectl get hpa php-apache
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
php-apache Deployment/php-apache cpu: 0%/50% 1 5 1
HPA sẽ giữ CPU trung bình quanh 50% của requests, trong khoảng 1–5 bản sao. Đang rảnh nên CPU 0%, giữ 1 pod. Giờ đổ tải — một pod cứ gọi service liên tục:
kubectl run load-generator --image=busybox:1.36 --restart=Never -- \
/bin/sh -c "while true; do wget -q -O- http://php-apache; done"
Theo dõi HPA mỗi 15 giây:
[15s] cpu: 0%/50% REPLICAS 1
[45s] cpu: 94%/50% REPLICAS 1 ← tải tăng, vượt mục tiêu
[60s] cpu: 94%/50% REPLICAS 2 ← HPA thêm pod
[105s] cpu: 154%/50% REPLICAS 2 → 4 ← vẫn cao, thêm nữa
kubectl get pods -l run=php-apache
NAME READY STATUS AGE
php-apache-69b4854d9f-96vzq 1/1 Running 9s ← pod mới
php-apache-69b4854d9f-j58rj 1/1 Running 69s ← pod mới
php-apache-69b4854d9f-t44x4 1/1 Running 4m32s ← pod gốc
php-apache-69b4854d9f-tfxwh 1/1 Running 9s ← pod mới
Tận mắt: CPU vọt lên 94% rồi 154% (vượt xa mục tiêu 50%), HPA phản ứng bằng cách tăng dần từ 1 → 2 → 4 bản sao để chia tải. Không ai gõ lệnh — control loop của HPA tự làm. Đây là requests phát huy tác dụng: "154%" nghĩa là dùng gấp 1.5 lần requests.cpu (200m), nên HPA biết cần bao nhiêu pod để kéo trung bình về 50%.
Scale xuống và một lưu ý
Khi dừng tải, HPA cũng giảm pod — nhưng thận trọng và chậm hơn: mặc định nó chờ một khoảng ổn định (cỡ 5 phút) trước khi scale down, tránh "giật cục" khi tải dao động. Tăng nhanh để kịp phục vụ, giảm chậm để ổn định — một thiết kế hợp lý.
Ngoài HPA (scale số pod), Kubernetes còn VPA (đổi requests/limits của pod) và Cluster Autoscaler (thêm/bớt node). Ba tầng autoscale này thường phối hợp ở production. Series nền tảng này dừng ở HPA — phổ biến và dễ hiểu nhất.
Tổng kết
Mỗi container nên khai báo requests (mức đảm bảo — scheduler dùng để xếp pod, HPA dùng để tính %) và limits (trần — vượt CPU bị throttle, vượt memory bị OOMKilled). Cách đặt hai con số này quyết định QoS class (Guaranteed > Burstable > BestEffort) — tức thứ tự bị hi sinh khi node cạn tài nguyên. HorizontalPodAutoscaler tự đổi số bản sao để giữ chỉ số (thường CPU) quanh mục tiêu — cần metrics-server. Demo cho thấy HPA tăng 1→4 pod khi CPU vọt lên 154%, và scale xuống chậm có chủ đích.
Tới giờ ta toàn dùng Deployment cho app không trạng thái. Bài 12 gặp các loại workload khác — StatefulSet (app có trạng thái), DaemonSet (mỗi node một pod), Job/CronJob (chạy rồi xong) — và khi nào dùng cái nào.