メインコンテンツまでスキップ

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ượngCông cụ
Pod-levelPod / ContainerHPA, VPA, KEDA
Node-levelEC2 Instance / FargateCluster Autoscaler, Karpenter

Luồng hoạt động điển hình:

  1. Traffic tăng → HPA/KEDA tăng số Pod
  2. Pod mới ở trạng thái Pending (không đủ resource trên Node hiện tại)
  3. Cluster Autoscaler / Karpenter phát hiện → thêm Node mới
  4. Pod được schedule lên Node mới
  5. 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
Best Practices cho HPA
  • Luôn set resources.requests cho 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

ModeHành vi
OffChỉ đưa ra recommendation, không tự động thay đổi
InitialChỉ set resource khi Pod được tạo mới
AutoTự độ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
Lưu ý khi dùng VPA
  • Mode Auto sẽ restart Pod để áp dụng resource mới — cần cân nhắc với stateful workload.
  • Không dùng VPA mode Auto cùng HPA trên cùng metric (CPU/Memory).
  • Nên bắt đầu với mode Off để xem recommendation trước khi bật Auto.

🚀 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"
Khi nào dùng KEDA?
  • 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": ["*"]
}
]
}
Hạn chế của Cluster Autoscaler
  • 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 AutoscalerKarpenter
Phụ thuộc ASG
Tốc độ scaleChậm (qua ASG)Nhanh (EC2 Fleet API)
Chọn instance typeCố định theo ASGTự động chọn tối ưu
Spot supportHạn chếTích hợp sâu
ConsolidationKhông cóTự động gom Pod, giảm Node
Drift detectionKhô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
Best Practices cho Karpenter
  • 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-category thay 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ápTầngScale gìScale từ 0Dựa trên
HPAPodSố replicas❌ (min=1)CPU, Memory, Custom metrics
VPAPodResource requestsUsage history
KEDAPodSố replicasEvents (SQS, Kafka, Cron,...)
Cluster AutoscalerNodeSố EC2 instancesPending Pods
KarpenterNodeSố EC2 instancesPending 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.requestsresources.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 PodDisruptionBudget cho 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-levelNode-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: