EKS Scaling & Auto Scaling
Phần này trình bày các chiến lược scaling trong EKS: từ scale Pod (HPA, VPA, KEDA) đến scale Node (Cluster Autoscaler, Karpenter), giúp hệ thống tự động scale theo nhu cầu thực tế.
📌 1. Tổng quan Scaling trong EKS
Scaling trong EKS chia thành 2 tầng chính:
| Tầng | Đối tượng | Công cụ |
|---|---|---|
| Pod-level | Pod / Container | HPA, VPA, KEDA |
| Node-level | EC2 Instance / Fargate | Cluster Autoscaler, Karpenter |
Luồng hoạt động điển hình:
- Traffic tăng → HPA/KEDA tăng số Pod
- Pod mới ở trạng thái
Pending(không đủ resource trên Node hiện tại) - Cluster Autoscaler / Karpenter phát hiện → thêm Node mới
- Pod được schedule lên Node mới
- Traffic giảm → HPA/KEDA giảm Pod → Node trống → scale-in Node
⚡ 2. Horizontal Pod Autoscaler (HPA)
2.1. HPA là gì?
HPA tự động điều chỉnh số lượng Pod replicas dựa trên metrics (CPU, Memory, hoặc custom metrics). Đây là cơ chế scaling phổ biến nhất trong Kubernetes.
Yêu cầu: Cần cài Metrics Server (xem bài Addons).
2.2. Cách hoạt động
Công thức tính replicas:
$$ \text{desiredReplicas} = \left\lceil \text{currentReplicas} \times \frac{\text{currentMetricValue}}{\text{desiredMetricValue}} \right\rceil $$
Ví dụ: Hiện tại 3 Pod, CPU trung bình 80%, target 50%:
$$ \text{desiredReplicas} = \lceil 3 \times \frac{80}{50} \rceil = \lceil 4.8 \rceil = 5 $$
2.3. Cấu hình HPA
Cách 1: Dùng kubectl
kubectl autoscale deployment my-app \
--cpu-percent=50 \
--min=2 \
--max=10
Cách 2: Khai báo YAML
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
behavior:
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Pods
value: 4
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
2.4. Kiểm tra HPA
kubectl get hpa
kubectl describe hpa my-app-hpa
Output mẫu:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
my-app-hpa Deployment/my-app 45%/50% 2 10 3
- Luôn set
resources.requestscho container — HPA dựa vào giá trị này để tính toán. - Dùng
behaviorđể kiểm soát tốc độ scale-up/scale-down, tránh flapping. - Kết hợp nhiều metrics (CPU + Memory) để quyết định chính xác hơn.
- Không dùng HPA cùng VPA trên cùng metric (ví dụ: cả hai đều dựa vào CPU).
📐 3. Vertical Pod Autoscaler (VPA)
3.1. VPA là gì?
VPA tự động điều chỉnh resource requests/limits (CPU, Memory) của container dựa trên usage thực tế. Phù hợp với workload không thể scale horizontally (ví dụ: database, single-threaded app).
3.2. Các mode hoạt động
| Mode | Hành vi |
|---|---|
| Off | Chỉ đưa ra recommendation, không tự động thay đổi |
| Initial | Chỉ set resource khi Pod được tạo mới |
| Auto | Tự động restart Pod để áp dụng resource mới |
3.3. Cài đặt VPA
git clone https://github.com/kubernetes/autoscaler.git
cd autoscaler/vertical-pod-autoscaler
./hack/vpa-up.sh
3.4. Cấu hình VPA
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-app-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
updatePolicy:
updateMode: "Off"
resourcePolicy:
containerPolicies:
- containerName: app
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: 2
memory: 4Gi
3.5. Xem recommendation
kubectl describe vpa my-app-vpa
Output mẫu:
Recommendation:
Container Recommendations:
Container Name: app
Lower Bound: Cpu: 100m, Memory: 256Mi
Target: Cpu: 250m, Memory: 512Mi
Upper Bound: Cpu: 500m, Memory: 1Gi
- Mode
Autosẽ restart Pod để áp dụng resource mới — cần cân nhắc với stateful workload. - Không dùng VPA mode
Autocùng HPA trên cùng metric (CPU/Memory). - Nên bắt đầu với mode
Offđể xem recommendation trước khi bậtAuto.
🚀 4. KEDA (Kubernetes Event-Driven Autoscaling)
4.1. KEDA là gì?
KEDA mở rộng khả năng auto-scaling bằng cách hỗ trợ event-driven scaling từ nhiều nguồn: SQS, Kafka, Prometheus, Cron, CloudWatch,... KEDA có thể scale Pod từ 0 đến N (HPA chỉ có thể từ 1 đến N).
4.2. Cài đặt KEDA trên EKS
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda \
--namespace keda \
--create-namespace
4.3. Ví dụ: Scale theo SQS Queue
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: sqs-scaledobject
spec:
scaleTargetRef:
name: queue-processor
minReplicaCount: 0
maxReplicaCount: 20
pollingInterval: 15
cooldownPeriod: 60
triggers:
- type: aws-sqs-queue
authenticationRef:
name: keda-aws-credentials
metadata:
queueURL: https://sqs.ap-southeast-1.amazonaws.com/123456789/my-queue
queueLength: "5"
awsRegion: ap-southeast-1
4.4. Ví dụ: Scale theo Cron schedule
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: cron-scaledobject
spec:
scaleTargetRef:
name: my-app
minReplicaCount: 1
triggers:
- type: cron
metadata:
timezone: Asia/Ho_Chi_Minh
start: 0 8 * * 1-5
end: 0 20 * * 1-5
desiredReplicas: "10"
- Workload xử lý message queue (SQS, Kafka, RabbitMQ)
- Cần scale từ 0 Pod (tiết kiệm chi phí)
- Scale theo lịch (business hours)
- Scale theo custom metrics từ Prometheus/CloudWatch
🖥️ 5. Cluster Autoscaler (CAS)
5.1. Cluster Autoscaler là gì?
Cluster Autoscaler tự động điều chỉnh số lượng Node trong cluster dựa trên Pod pending (thiếu resource) hoặc Node underutilized (thừa resource).
5.2. Cách hoạt động
5.3. Cài đặt bằng Helm
helm repo add autoscaler https://kubernetes.github.io/autoscaler
helm repo update
helm install cluster-autoscaler autoscaler/cluster-autoscaler \
--namespace kube-system \
--set autoDiscovery.clusterName=my-eks \
--set awsRegion=ap-southeast-1 \
--set rbac.serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::123456789:role/ClusterAutoscalerRole
5.4. Cấu hình bằng Terraform
resource "helm_release" "cluster_autoscaler" {
name = "cluster-autoscaler"
repository = "https://kubernetes.github.io/autoscaler"
chart = "cluster-autoscaler"
namespace = "kube-system"
set {
name = "autoDiscovery.clusterName"
value = var.cluster_name
}
set {
name = "awsRegion"
value = var.region
}
set {
name = "rbac.serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn"
value = aws_iam_role.cluster_autoscaler.arn
}
}
5.5. IAM Policy cần thiết
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeScalingActivities",
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup",
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeInstanceTypes",
"eks:DescribeNodegroup"
],
"Resource": ["*"]
}
]
}
- Phụ thuộc vào ASG (Auto Scaling Group) — phải cấu hình đúng instance types.
- Tốc độ scale-up chậm (phải đợi EC2 launch + join cluster).
- Không tối ưu chi phí tốt — không tự chọn instance type phù hợp nhất.
- Với cluster lớn, nên cân nhắc chuyển sang Karpenter.
🎯 6. Karpenter
6.1. Karpenter là gì?
Karpenter là node autoscaler thế hệ mới do AWS phát triển, thay thế Cluster Autoscaler. Karpenter không dùng ASG mà gọi trực tiếp EC2 Fleet API, giúp chọn instance type tối ưu, launch nhanh hơn, và tiết kiệm chi phí.
6.2. So sánh Karpenter vs Cluster Autoscaler
| Tiêu chí | Cluster Autoscaler | Karpenter |
|---|---|---|
| Phụ thuộc ASG | ✔ | ❌ |
| Tốc độ scale | Chậm (qua ASG) | Nhanh (EC2 Fleet API) |
| Chọn instance type | Cố định theo ASG | Tự động chọn tối ưu |
| Spot support | Hạn chế | Tích hợp sâu |
| Consolidation | Không có | Tự động gom Pod, giảm Node |
| Drift detection | Không có | Tự động thay Node khi AMI mới |
6.3. Cài đặt Karpenter
helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter \
--version "1.0.8" \
--namespace karpenter \
--create-namespace \
--set "settings.clusterName=my-eks" \
--set "serviceAccount.annotations.eks\.amazonaws\.com/role-arn=arn:aws:iam::123456789:role/KarpenterRole"
6.4. Cấu hình NodePool
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
requirements:
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand", "spot"]
- key: karpenter.k8s.aws/instance-category
operator: In
values: ["c", "m", "r"]
- key: karpenter.k8s.aws/instance-generation
operator: Gt
values: ["4"]
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: default
limits:
cpu: 100
memory: 400Gi
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 1m
6.5. Cấu hình EC2NodeClass
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
name: default
spec:
amiSelectorTerms:
- alias: al2023@latest
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: my-eks
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: my-eks
role: KarpenterNodeRole
- Dùng
consolidationPolicy: WhenEmptyOrUnderutilizedđể tối ưu chi phí. - Kết hợp On-Demand + Spot instances cho workload không critical.
- Set
limits(cpu, memory) để kiểm soát chi phí tổng. - Dùng
instance-categorythay vì chỉ định cụ thể instance type — để Karpenter tự chọn tối ưu.
📊 7. So sánh tổng quan các giải pháp Scaling
| Giải pháp | Tầng | Scale gì | Scale từ 0 | Dựa trên |
|---|---|---|---|---|
| HPA | Pod | Số replicas | ❌ (min=1) | CPU, Memory, Custom metrics |
| VPA | Pod | Resource requests | ❌ | Usage history |
| KEDA | Pod | Số replicas | ✔ | Events (SQS, Kafka, Cron,...) |
| Cluster Autoscaler | Node | Số EC2 instances | ❌ | Pending Pods |
| Karpenter | Node | Số EC2 instances | ❌ | Pending Pods |
🏗️ 8. Kiến trúc Scaling khuyến nghị cho Production
Kết hợp phổ biến
Checklist trước khi lên Production
- ✔ Mọi Deployment đều có
resources.requestsvàresources.limits - ✔ HPA được cấu hình cho stateless workload
- ✔ KEDA cho workload event-driven (nếu có)
- ✔ VPA mode
Offđể thu thập recommendation - ✔ Karpenter (hoặc CAS) cho node scaling
- ✔ Set
PodDisruptionBudgetcho critical workload - ✔ Monitoring: theo dõi HPA metrics, Karpenter events, pending Pods
- ✔ Giới hạn
maxReplicas(HPA) vàlimits(Karpenter) để kiểm soát chi phí
9. Tổng kết
Scaling trong EKS là sự kết hợp giữa Pod-level và Node-level:
- HPA - Giải pháp cơ bản và phổ biến nhất, dựa trên CPU/Memory
- VPA - Tối ưu resource requests cho workload không scale horizontal
- KEDA - Event-driven scaling, hỗ trợ scale từ 0
- Cluster Autoscaler - Node scaling truyền thống qua ASG
- Karpenter - Node scaling thế hệ mới, nhanh hơn và tối ưu chi phí hơn
Tham khảo: