1. Triển khai ứng dụng mẫu với Resource Requests và Limits
Bước đầu tiên là chuẩn bị một ứng dụng mẫu (workload) có cấu hình rõ ràng về tài nguyên. HPA cần dựa vào các giá trị Requests và Limits này để tính toán tỷ lệ sử dụng CPU/RAM thực tế so với mức yêu cầu.
1.1 Tạo Deployment với resource constraints
Chúng ta sẽ deploy một container chạy ứng dụng "php-apache" có thể chịu tải tính toán. Cần khai báo resources.requests (tài nguyên tối thiểu đảm bảo) và resources.limits (tài nguyên tối đa cho phép) để K3s và HPA có cơ sở so sánh.
Tạo file /tmp/sample-app-deployment.yaml với nội dung hoàn chỉnh:
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache
namespace: default
spec:
replicas: 1
selector:
matchLabels:
run: php-apache
template:
metadata:
labels:
run: php-apache
spec:
containers:
- name: php-apache
image: registry.k8s.io/hpa-example
ports:
- containerPort: 80
resources:
requests:
cpu: "200m"
memory: "64Mi"
limits:
cpu: "500m"
memory: "128Mi"
Áp dụng cấu hình này vào cụm K3s:
kubectl apply -f /tmp/sample-app-deployment.yaml
Kết quả mong đợi: Cluster trả về thông báo deployment.apps/php-apache created và pod chuyển sang trạng thái Running sau vài giây.
1.2 Tạo Service để tiếp nhận traffic
Để kịch bản load test có thể truy cập vào ứng dụng, cần tạo một Service loại LoadBalancer hoặc NodePort. Trên Proxmox/K3s, NodePort là cách nhanh nhất để test nội bộ mà không cần cấu hình LoadBalancer phức tạp.
Tạo file /tmp/sample-app-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: php-apache-service
namespace: default
spec:
type: NodePort
selector:
run: php-apache
ports:
- port: 80
targetPort: 80
nodePort: 30080
Áp dụng Service:
kubectl apply -f /tmp/sample-app-service.yaml
Kết quả mong đợi: Xuất hiện dòng service/php-apache-service created.
1.3 Verify Resource Configuration
Để đảm bảo HPA hoạt động chính xác, hãy kiểm tra lại xem pod đã được gán đúng resource constraints chưa.
kubectl describe deployment php-apache | grep -A 4 "Limits\|Requests"
Kết quả mong đợi: Thấy rõ các dòng CPU: 200m (Requests), 500m (Limits) và Memory: 64Mi (Requests), 128Mi (Limits).
2. Cấu hình Horizontal Pod Autoscaler (HPA)
Sau khi có ứng dụng, ta sẽ tạo HPA object để K3s tự động điều chỉnh số lượng pod dựa trên tỷ lệ sử dụng CPU hoặc Memory so với mức requests đã khai báo.
2.1 Tạo HPA dựa trên CPU
Chúng ta sẽ cấu hình HPA để mở rộng (scale up) khi CPU trung bình của các pod vượt quá 50% mức request (200m) và thu nhỏ (scale down) khi giảm xuống dưới 25%. Số lượng pod sẽ nằm trong khoảng 1 đến 5.
Tạo file /tmp/hpa-cpu.yaml:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache-hpa
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
Áp dụng HPA:
kubectl apply -f /tmp/hpa-cpu.yaml
Kết quả mong đợi: Thông báo horizontalpodautoscaler.autoscaling/php-apache-hpa created. Lưu ý: Nếu Metric Server (Phần 4) chưa chạy, HPA sẽ báo lỗi Unable to get the needed metrics.
2.2 Verify HPA Status
Để kiểm tra HPA đã liên kết đúng với Deployment và đang theo dõi metric chưa, hãy dùng lệnh describe.
kubectl describe hpa php-apache-hpa
Kết quả mong đợi: Trong phần Current Metrics sẽ hiển thị tỷ lệ CPU hiện tại (ví dụ: 0m (0%)) và Desired Replicas vẫn là 1 khi không có load.
3. Tạo kịch bản Load Test để kích hoạt Scaling
HPA sẽ không tự động scale nếu không có tải. Chúng ta cần một công cụ tạo request liên tục để đẩy CPU của container lên trên ngưỡng 50% đã cài đặt.
3.1 Sử dụng kubectl run để tạo load
Chúng ta sẽ tạo một pod tạm thời chạy lệnh while true để liên tục gọi API của ứng dụng php-apache. Pod này sẽ chạy song song và tạo áp lực lên CPU của các pod php-apache.
Thực hiện lệnh sau để tạo pod load test (chạy trong namespace default):
kubectl run -i --tty load-test --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://php-apache-service.default.svc.cluster.local; done"
Kết quả mong đợi: Terminal bị chiếm dụng bởi dòng lệnh và bắt đầu xuất ra log (nếu có) hoặc chạy im lặng. Pod load-test xuất hiện trong kubectl get pods.
3.2 Mở thêm terminal để monitor scaling
Mở một terminal mới (hoặc cửa sổ khác) để quan sát sự thay đổi số lượng pod theo thời gian thực.
watch -n 1 kubectl get hpa php-apache-hpa
Hoặc kiểm tra số lượng pod:
watch -n 1 kubectl get pods -l run=php-apache
3.3 Quan sát quá trình Scale Up
Chờ đợi khoảng 30-60 giây sau khi bắt đầu load test. Metric Server cần thời gian để thu thập dữ liệu, và HPA cần thời gian để xử lý logic scaling.
Khi CPU trung bình vượt quá 50%, bạn sẽ thấy:
- Trong lệnh
watch HPA, giá trị DESIRED tăng từ 1 lên 2, 3...
- Trong lệnh
watch Pod, số lượng pod có label run=php-apache tăng lên tương ứng.
- Khi đạt đến
maxReplicas: 5, quá trình dừng lại.
3.4 Kết thúc Load Test và Scale Down
Nhấn Ctrl+C trong terminal đang chạy lệnh load test để dừng việc tạo request.
Về lại terminal monitor, quan sát HPA:
watch -n 1 kubectl get hpa php-apache-hpa
Khi CPU giảm xuống dưới ngưỡng 25% (do không còn load), HPA sẽ bắt đầu giảm số pod. Lưu ý: Do cấu hình stabilizationWindowSeconds: 300 trong file HPA, quá trình scale down sẽ diễn ra chậm hơn để tránh hiện tượng "thrashing" (vừa tăng vừa giảm liên tục).
Kết quả mong đợi: Sau vài phút, DESIRED quay về 1 và các pod thừa sẽ bị xóa.
4. Verify kết quả cuối cùng
Kiểm tra toàn bộ trạng thái hệ thống sau khi hoàn thành kịch bản để đảm bảo HPA hoạt động ổn định.
4.1 Kiểm tra sự kiện (Events)
Xem lại các sự kiện đã xảy ra để xác nhận nguyên nhân scaling là do CPU metric.
kubectl get events --field-selector involvedObject.name=php-apache-hpa --sort-by='.lastTimestamp' | tail -n 20
Kết quả mong đợi: Thấy các dòng Scaling up và Scaling down với lý do cpu.
4.2 Kiểm tra Resource Usage thực tế
So sánh resource usage hiện tại của các pod đang chạy.
kubectl top pods -l run=php-apache
Kết quả mong đợi: Hiển thị lượng CPU và Memory đang tiêu thụ thực tế của từng pod. Nếu đang idle, CPU sẽ rất thấp (gần 0m), xác nhận HPA đã scale down đúng cách.
4.3 Dọn dẹp (Cleanup)
Xóa toàn bộ tài nguyên đã tạo để giữ môi trường sạch cho các phần tiếp theo.
kubectl delete hpa php-apache-hpa
kubectl delete deployment php-apache
kubectl delete service php-apache-service
kubectl delete pod load-test --force --grace-period=0 2>/dev/null || true
Kết quả mong đợi: Tất cả các object đã được xóa khỏi cụm K3s.
Điều hướng series:
Mục lục: Series: Xây dựng hạ tầng Kubernetes tự động (Auto-Scaling) với K3s và Helm trên Proxmox
« Phần 5: Cấu hình Cluster Autoscaler cho K3s
Phần 7: Tích hợp Proxmox API để mở rộng node tự động »