Kubernetes HPA และ VPA — คู่มือ Autoscaling ฉบับสมบูรณ์สำหรับ Production 2026
ถ้าคุณเคย deploy แอปบน Kubernetes แล้วเจอปัญหา pod crash เพราะ memory ไม่พอตอน traffic spike หรือจ่ายค่า cloud แพงเกินไปเพราะ provision resource มากเกินจำเป็น — Autoscaling คือสิ่งที่คุณต้องเรียนรู้ตอนนี้เลย ผมดูแล Kubernetes cluster มากว่า 8 ปี ตั้งแต่ยุค Kubernetes 1.6 จนถึง 1.29 ในปัจจุบัน ดูแล cluster ที่มี 500+ nodes รัน 3,000+ pods ทุกวัน สิ่งที่ผมเรียนรู้คือ — Autoscaling ที่ดีคือความแตกต่างระหว่างระบบที่ stable กับระบบที่ล่มตอนตี 3
บทความนี้จะอธิบายทุกอย่างเกี่ยวกับ Kubernetes Autoscaling ทั้ง HPA (Horizontal Pod Autoscaler), VPA (Vertical Pod Autoscaler) และ Cluster Autoscaler พร้อม YAML manifests ที่ใช้ได้จริง เทคนิคขั้นสูงที่ไม่ค่อยมีคนพูดถึง และ pitfalls ที่ต้องระวัง
สิ่งที่จะได้เรียนรู้:
- HPA คืออะไร ทำงานอย่างไร — ทุก parameter ที่ต้องรู้
- VPA คืออะไร เมื่อไหร่ควรใช้แทน HPA
- Cluster Autoscaler — scale nodes อัตโนมัติ
- Custom Metrics — scale ด้วย metrics ที่คุณกำหนดเอง
- KEDA — Event-driven autoscaling
- Production best practices จากประสบการณ์จริง
- Pitfalls ที่ทำให้ autoscaling ไม่ทำงาน
ทำความเข้าใจ Kubernetes Autoscaling 3 ระดับ
Kubernetes มี autoscaling 3 ระดับที่ทำงานร่วมกัน:
- HPA (Horizontal Pod Autoscaler) — เพิ่ม/ลดจำนวน pods ตาม metrics เช่น CPU, memory, custom metrics
- VPA (Vertical Pod Autoscaler) — ปรับ resource requests/limits ของ pod ให้เหมาะสมอัตโนมัติ
- Cluster Autoscaler — เพิ่ม/ลดจำนวน nodes เมื่อ pods ไม่มีที่รัน หรือ nodes ว่างเกินไป
ทั้ง 3 ตัวนี้ทำงานร่วมกันเป็น chain: HPA เพิ่ม pods → pods ไม่มีที่รัน → Cluster Autoscaler เพิ่ม nodes → pods ถูก schedule ลง nodes ใหม่ เมื่อ traffic ลด HPA ลด pods → nodes ว่าง → Cluster Autoscaler ลด nodes → ประหยัดค่าใช้จ่าย
HPA — Horizontal Pod Autoscaler แบบเจาะลึก
พื้นฐาน: HPA ทำงานอย่างไร
HPA ทำงานเป็น control loop ที่ตรวจสอบ metrics ทุก 15 วินาที (default) แล้วคำนวณจำนวน pods ที่ต้องการด้วยสูตร:
desiredReplicas = ceil(currentReplicas × (currentMetricValue / desiredMetricValue))
ตัวอย่าง: ถ้าตอนนี้มี 3 pods, CPU utilization เฉลี่ย 80%, target คือ 50%:
desiredReplicas = ceil(3 × (80 / 50)) = ceil(4.8) = 5
HPA จะ scale จาก 3 เป็น 5 pods
HPA v2 — YAML ที่ใช้จริงใน Production
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 3
maxReplicas: 50
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 100
periodSeconds: 60
- type: Pods
value: 5
periodSeconds: 60
selectPolicy: Max
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 120
selectPolicy: Min
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 75
มาอธิบายทีละส่วน:
minReplicas และ maxReplicas
minReplicas: 3 — ต่ำสุด 3 pods เสมอ เพื่อ high availability (กระจายข้าม 3 AZs) อย่าตั้ง minReplicas เป็น 1 ใน production เด็ดขาด เพราะถ้า pod นั้นตาย จะมี downtime ระหว่างที่ pod ใหม่ start
maxReplicas: 50 — สูงสุด 50 pods เป็น safety net ป้องกัน runaway scaling ที่อาจเกิดจาก bug หรือ DDoS ตั้งค่านี้ให้เหมาะกับ capacity ของ cluster และ budget ของคุณ
Scaling Behavior — ส่วนที่สำคัญที่สุด
นี่คือส่วนที่คนส่วนใหญ่ไม่ตั้งค่า แล้วก็เจอปัญหา:
Scale Up:
stabilizationWindowSeconds: 60— รอ 60 วินาทีก่อน scale up เพื่อป้องกัน flapping (scale up/down ไปมา)- ใช้ 2 policies: เพิ่มได้สูงสุด 100% หรือ 5 pods ต่อนาที เลือกค่าที่มากกว่า (
selectPolicy: Max) - ทำให้ scale up เร็ว — ถ้ามี 10 pods สามารถเพิ่มเป็น 20 pods ได้ภายใน 1 นาที
Scale Down:
stabilizationWindowSeconds: 300— รอ 5 นาทีก่อน scale down เพื่อป้องกัน premature scale down- ลดได้สูงสุด 10% ทุก 2 นาที เลือกค่าที่น้อยกว่า (
selectPolicy: Min) - ทำให้ scale down ช้า — ป้องกันไม่ให้ลด pods เร็วเกินไปแล้ว traffic กลับมา
หลักการสำคัญ: Scale up เร็ว, Scale down ช้า — นี่คือ golden rule ของ autoscaling
CPU Target — ทำไมไม่ควรตั้ง 80%
หลายคนตั้ง CPU target ที่ 80% คิดว่า "ใช้ให้คุ้ม" แต่ในความเป็นจริง ถ้า CPU ถึง 80% แล้ว HPA เพิ่ม pods pod ใหม่ต้องใช้เวลา start (30 วินาที - 2 นาที) ระหว่างนั้น pods เดิมอาจ overload จน response time พุ่ง
ผมแนะนำ:
- API servers: target 50-60% — ต้อง scale ก่อนที่จะ overload
- Background workers: target 70-80% — ไม่ส่งผลต่อ user experience โดยตรง
- Batch jobs: target 85-90% — ใช้ resource ให้คุ้มที่สุด
ผู้เชี่ยวชาญแนะนำ - siamlancard
แนะนำ: | |
ผมเคยเขียนเรื่องที่เกี่ยวข้องไว้ใน kubernetes hpa vpa career development it
🎬 วิดีโอที่เกี่ยวข้อง — YouTube @icafefx
Custom Metrics — Scale ด้วย Business Metrics
CPU และ memory เป็นแค่ proxy metrics ที่ไม่ได้บอกสถานะจริงของแอปเสมอไป ตัวอย่าง: แอปอาจใช้ CPU น้อยแต่ response time สูงเพราะรอ database ในกรณีนี้ต้องใช้ custom metrics
ติดตั้ง Prometheus Adapter
# ติดตั้งด้วย Helm
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus-adapter prometheus-community/prometheus-adapter \
-n monitoring \
-f prometheus-adapter-values.yaml
prometheus-adapter-values.yaml
rules:
custom:
- seriesQuery: 'http_requests_per_second{namespace!="",pod!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
pod: {resource: "pod"}
name:
matches: "^(.*)$"
as: "${1}"
metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'
- seriesQuery: 'http_request_duration_seconds_bucket{namespace!="",pod!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
pod: {resource: "pod"}
name:
as: "http_request_duration_p99"
metricsQuery: 'histogram_quantile(0.99, sum(rate(<<.Series>>{<<.LabelMatchers>>}[5m])) by (le, <<.GroupBy>>))'
HPA ที่ใช้ Custom Metrics
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa-custom
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 3
maxReplicas: 50
metrics:
# Scale ตาม requests per second
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "100"
# Scale ตาม p99 latency
- type: Pods
pods:
metric:
name: http_request_duration_p99
target:
type: AverageValue
averageValue: "500m" # 500ms
HPA นี้จะ scale เมื่อ requests per second เกิน 100 ต่อ pod หรือ p99 latency เกิน 500ms ใช้ค่าที่ต้องการ replicas มากกว่า (เพราะ HPA ใช้ max ของทุก metrics)
VPA — Vertical Pod Autoscaler
VPA คืออะไร ต่างจาก HPA อย่างไร
ถ้า HPA เพิ่ม/ลดจำนวน pods (horizontal) VPA จะปรับ CPU/memory requests และ limits ของแต่ละ pod (vertical) ให้เหมาะสมกับ actual usage
VPA มี 3 modes:
- Off — แค่แนะนำค่าที่เหมาะสม ไม่เปลี่ยนอะไร (ใช้ดู recommendation)
- Initial — ตั้งค่า requests เมื่อ pod ถูกสร้างใหม่ ไม่แก้ pods ที่รันอยู่
- Auto — ปรับค่า requests อัตโนมัติ (จะ evict pod แล้วสร้างใหม่ด้วยค่าที่ปรับแล้ว)
ติดตั้ง VPA
# Clone VPA repository
git clone https://github.com/kubernetes/autoscaler.git
cd autoscaler/vertical-pod-autoscaler
# ติดตั้ง
./hack/vpa-up.sh
# ตรวจสอบ
kubectl get pods -n kube-system | grep vpa
VPA YAML สำหรับ Production
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: api-server-vpa
namespace: production
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
updatePolicy:
updateMode: "Off" # เริ่มจาก Off ก่อน ดู recommendation
resourcePolicy:
containerPolicies:
- containerName: api-server
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: 4
memory: 8Gi
controlledResources: ["cpu", "memory"]
controlledValues: RequestsOnly
ดู VPA Recommendations
# ดู recommendation
kubectl describe vpa api-server-vpa -n production
# Output จะแสดง:
# Recommendation:
# Container Recommendations:
# Container Name: api-server
# Lower Bound: Cpu: 250m, Memory: 256Mi
# Target: Cpu: 500m, Memory: 512Mi
# Uncapped Target: Cpu: 500m, Memory: 512Mi
# Upper Bound: Cpu: 2, Memory: 2Gi
คำแนะนำสำคัญ: เริ่มจาก updateMode: "Off" เสมอ ดู recommendation สัก 1-2 สัปดาห์ก่อน ถ้าค่าที่แนะนำสมเหตุสมผล ค่อยเปลี่ยนเป็น "Auto"
⚠️ HPA กับ VPA ใช้ด้วยกันได้ไหม?
ได้ แต่ต้องระวัง! ห้ามให้ HPA และ VPA ใช้ metric เดียวกัน เช่น ถ้า HPA scale ตาม CPU อย่าให้ VPA ปรับ CPU requests เพราะจะ conflict กัน:
- HPA scale ตาม CPU → VPA ปรับ CPU requests/limits
- HPA scale ตาม custom metrics → VPA ปรับ CPU + memory ✅
- HPA scale ตาม CPU → VPA ปรับ memory only ✅
KEDA — Event-Driven Autoscaling
KEDA (Kubernetes Event-Driven Autoscaling) เป็น autoscaler ที่ scale ตาม event sources เช่น Kafka queue depth, RabbitMQ messages, AWS SQS, Prometheus queries และอีกมากมาย
ติดตั้ง KEDA
helm repo add kedacore https://kedacore.github.io/charts
helm install keda kedacore/keda -n keda --create-namespace
Scale ตาม Kafka Lag
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: kafka-consumer-scaler
namespace: production
spec:
scaleTargetRef:
name: kafka-consumer
minReplicaCount: 1
maxReplicaCount: 30
pollingInterval: 15
cooldownPeriod: 300
triggers:
- type: kafka
metadata:
bootstrapServers: kafka-broker:9092
consumerGroup: my-consumer-group
topic: orders
lagThreshold: "100"
offsetResetPolicy: latest
KEDA จะ scale kafka-consumer pods ตาม consumer lag ถ้า lag เกิน 100 messages จะเพิ่ม pods ถ้า lag เป็น 0 จะลดเหลือ minReplicaCount
Scale to Zero
จุดเด่นของ KEDA คือ scale to zero ได้ — ถ้าไม่มี events เข้ามา pods จะถูกลดเป็น 0 ประหยัด resource ทั้งหมด เมื่อมี events เข้ามาใหม่ KEDA จะสร้าง pods ขึ้นมาอัตโนมัติ เหมาะกับ batch processing, event consumers และ scheduled jobs
📌 บทความแนะนำจาก siamlancard: | |
สำหรับรายละเอียดเพิ่มเติม ดู kubernetes hpa vpa finops cloud cost
Cluster Autoscaler — Scale Nodes อัตโนมัติ
ทำงานอย่างไร
Cluster Autoscaler ทำ 2 อย่าง:
- Scale Up: เมื่อมี pods ที่ Pending (ไม่มี node ที่มี resource พอ) จะเพิ่ม nodes
- Scale Down: เมื่อ node มี utilization ต่ำกว่า threshold (default 50%) เป็นเวลา 10 นาที จะย้าย pods ไป node อื่นแล้วลบ node นั้น
AWS EKS Cluster Autoscaler
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-autoscaler
namespace: kube-system
spec:
template:
spec:
containers:
- name: cluster-autoscaler
image: registry.k8s.io/autoscaling/cluster-autoscaler:v1.29.0
command:
- ./cluster-autoscaler
- --v=4
- --stderrthreshold=info
- --cloud-provider=aws
- --skip-nodes-with-local-storage=false
- --expander=least-waste
- --balance-similar-node-groups
- --skip-nodes-with-system-pods=false
- --scale-down-delay-after-add=10m
- --scale-down-unneeded-time=10m
- --scale-down-utilization-threshold=0.5
- --max-node-provision-time=15m
Karpenter — ทางเลือกที่ดีกว่า (AWS)
ถ้าใช้ AWS EKS ผมแนะนำ Karpenter แทน Cluster Autoscaler เพราะ:
- เร็วกว่า — provision node ใหม่ภายใน 60 วินาที (CA ใช้ 3-5 นาที)
- ฉลาดกว่า — เลือก instance type ที่เหมาะสมที่สุดอัตโนมัติ
- ประหยัดกว่า — ใช้ Spot instances ได้อย่างชาญฉลาด
- ไม่ต้อง manage node groups
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot", "on-demand"]
- key: node.kubernetes.io/instance-type
operator: In
values: ["m5.large", "m5.xlarge", "m5.2xlarge", "c5.large", "c5.xlarge"]
- key: topology.kubernetes.io/zone
operator: In
values: ["ap-southeast-1a", "ap-southeast-1b", "ap-southeast-1c"]
limits:
cpu: 1000
memory: 1000Gi
disruption:
consolidationPolicy: WhenUnderutilized
expireAfter: 720h
(อ้างอิง: kubernetes hpa vpa distributed system)
Troubleshooting Autoscaling ที่พบบ่อย
ปัญหา 1: HPA ไม่ scale — ค้างที่ unknown
# ตรวจสอบ HPA status
kubectl get hpa -n production
# NAME REFERENCE TARGETS MINPODS MAXPODS
# api-server-hpa Deployment/api /60% 3 50
# สาเหตุ: ไม่มี metrics-server หรือ pod ไม่มี resource requests
# แก้ 1: ติดตั้ง metrics-server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# แก้ 2: ตั้ง resource requests ใน Deployment
resources:
requests:
cpu: 200m
memory: 256Mi
สำคัญมาก: HPA ต้องการ resource requests ถ้า pod ไม่มี requests, HPA จะไม่สามารถคำนวณ utilization percentage ได้
ปัญหา 2: Scale up ช้าเกินไป
# ตรวจสอบ HPA events
kubectl describe hpa api-server-hpa -n production
# ดู scaling behavior
# ถ้า stabilizationWindowSeconds สูงเกินไป จะ scale ช้า
# แก้: ลด stabilizationWindowSeconds สำหรับ scaleUp
behavior:
scaleUp:
stabilizationWindowSeconds: 0 # scale ทันทีเมื่อ metrics เกิน threshold
ปัญหา 3: Flapping — scale up/down ไปมา
# สาเหตุ: stabilizationWindowSeconds ต่ำเกินไป หรือ target ใกล้ actual usage เกินไป
# แก้: เพิ่ม stabilization window สำหรับ scale down
behavior:
scaleDown:
stabilizationWindowSeconds: 600 # รอ 10 นาทีก่อน scale down
ปัญหา 4: Pod ใหม่ start ช้า ทำให้ scale ไม่ทัน
# แก้ 1: ลด container startup time
# - ใช้ smaller image (multi-stage build)
# - ลด initialization time
# - ใช้ startup probe แทน readiness probe ตอน start
# แก้ 2: ใช้ PodDisruptionBudget
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-server-pdb
spec:
minAvailable: "80%"
selector:
matchLabels:
app: api-server
หากสนใจเพิ่มเติม อ่านได้ที่ kubernetes hpa vpa observability stack
Production Best Practices
- ตั้ง resource requests เสมอ — ไม่มี requests = HPA ไม่ทำงาน + scheduler ไม่รู้จะ schedule ที่ไหน
- ใช้ VPA ในโหมด Off ก่อน — ดู recommendation 1-2 สัปดาห์ก่อนเปิด Auto
- Scale up เร็ว, Scale down ช้า — golden rule ที่ต้องจำ
- ใช้ PodDisruptionBudget — ป้องกัน scale down ทำให้ service ล่ม
- Monitor autoscaling events — ตั้ง alert เมื่อ HPA hit maxReplicas
- Test ด้วย load testing — ใช้ k6, Locust หรือ Vegeta ทดสอบว่า autoscaling ทำงานจริง
- ตั้ง maxReplicas ให้เหมาะสม — ไม่สูงเกินไป (ค่าใช้จ่าย) ไม่ต่ำเกินไป (รับ traffic ไม่ไหว)
- ใช้ Pod Topology Spread — กระจาย pods ข้าม AZs
- ใช้ Pod Priority — ให้ critical pods ได้ resource ก่อน
คำถามที่พบบ่อย (FAQ)
Q: HPA กับ VPA ใช้ด้วยกันได้ไหม?
A: ได้ แต่ห้ามใช้ metric เดียวกัน เช่น HPA scale ตาม custom metrics + VPA ปรับ memory only
Q: ควรตั้ง CPU target เท่าไหร่?
A: API servers: 50-60%, Workers: 70-80%, Batch: 85-90% ขึ้นอยู่กับ startup time ของ pod
Q: KEDA กับ HPA ต่างกันอย่างไร?
A: KEDA เป็น superset ของ HPA — มันสร้าง HPA ให้อัตโนมัติ แต่รองรับ event sources มากกว่า 60+ ตัว และ scale to zero ได้
Q: Cluster Autoscaler กับ Karpenter เลือกอะไรดี?
A: ถ้าใช้ AWS EKS เลือก Karpenter เพราะเร็วกว่าและฉลาดกว่า ถ้าใช้ GKE/AKS ใช้ Cluster Autoscaler
Q: ทำไม HPA ไม่ scale ทั้งที่ CPU สูง?
A: ตรวจสอบ 3 อย่าง: 1) metrics-server ทำงานไหม 2) pod มี resource requests ไหม 3) HPA status แสดง unknown ไหม
Q: Scale to zero ได้ไหม?
A: HPA ทำไม่ได้ (minReplicas ต้อง >= 1) แต่ KEDA ทำได้
สรุป — เริ่มใช้ Autoscaling วันนี้
Kubernetes Autoscaling เป็นสิ่งที่ทุก production cluster ต้องมี ไม่ใช่ optional อีกต่อไป เริ่มจาก HPA กับ CPU/memory metrics ก่อน จากนั้นเพิ่ม custom metrics เมื่อต้องการ ใช้ VPA ในโหมด Off เพื่อดู recommendation แล้วค่อยเปิด Auto เมื่อมั่นใจ
สิ่งที่สำคัญที่สุดคือ test autoscaling ด้วย load testing จริง อย่าแค่ deploy แล้วหวังว่ามันจะทำงาน ต้องพิสูจน์ว่ามันทำงานจริงก่อนที่ traffic จริงจะมา
ถ้ามีคำถาม สอบถามได้ที่ SiamCafe Forum ครับ
💡 เรียนรู้เพิ่มเติม: | | — จาก ผู้เชี่ยวชาญประสบการณ์กว่า 13 ปี
🎬 ดูวิดีโอเพิ่มเติม
เรียนรู้ IT, Forex Trading และเทคนิค Server จากประสบการณ์จริง 30 ปี