ข้ามไปยังเนื้อหา

Horizontal Pod Autoscaling

HorizontalPodAutoscaler จับตา metric เทียบกับ target แล้วปรับ replicas ของ Deployment ให้อยู่ระหว่างค่าต่ำสุดกับสูงสุด เพื่อดึง metric นั้นให้ใกล้ target — แค่นั้นเอง

HorizontalPodAutoscaler (autoscaling/v2) ฟังดูง่าย แต่จะไม่ทำอะไรเลยแบบเงียบ ๆ ถ้าสองอย่างนี้ยังไม่จริง

  1. Pod ของ workload ต้องตั้ง resource requests ไว้ โดย default HPA scale ตาม CPU หรือ memory utilization และ utilization คำนวณเป็นเปอร์เซ็นต์ของสิ่งที่ Pod request ไว้ — ไม่มี requests ก็ไม่มีตัวหารมาคำนวณเปอร์เซ็นต์
  2. metrics-server (หรือ custom/external metrics adapter) ต้องถูกติดตั้งใน cluster HPA เองไม่วัดอะไรเลย แค่อ่าน metric ที่อะไรบางอย่างเก็บและ expose ผ่าน metrics API ไม่มีแหล่ง metric ก็ไม่มีการตัดสินใจ scale เกิดขึ้นเลย
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: web-app:3.2.0
resources:
requests:
cpu: "250m"
memory: "256Mi"
Terminal window
# metrics-server has to actually be running before HPA can read any utilization
kubectl get deployment metrics-server -n kube-system

เมื่อตั้ง requests ไว้แล้วและ metrics-server รันอยู่ object HPA เองก็แค่ระบุ target กับ metric

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
Terminal window
kubectl get hpa web-app
kubectl describe hpa web-app

ค่านี้หมายความว่า คุม average CPU utilization ของ Pod web-app ทุกตัวให้อยู่ใกล้ 60% ของ CPU ที่ request ไว้ โดย scale Deployment ระหว่าง 3 ถึง 20 replica เพื่อรักษาระดับนั้น HPA ยังรองรับการ scale ตาม custom metric ที่ไม่ใช่ resource ด้วย เช่น queue depth หรือ requests-per-second ผ่าน API custom.metrics.k8s.io และ external.metrics.k8s.io สำหรับทีมที่ bottleneck ไม่ได้อยู่ที่ CPU หรือ memory เลย

ควรพูดให้ชัดตรงเส้นแบ่งนี้ เพราะมี autoscaler อีกสองตัวที่ฟังดูคล้ายกันแต่ทำหน้าที่คนละอย่างโดยสิ้นเชิง

  • HorizontalPodAutoscaler เปลี่ยนจำนวน replica ของ Deployment หรือ StatefulSet นี่คืองานทั้งหมดของตัวเอง
  • VerticalPodAutoscaler (VPA) เปลี่ยน requests/limits ของ Pod ที่มีอยู่แล้ว คือปรับขนาด Pod แทนที่จะเพิ่มจำนวน
  • Cluster Autoscaler เปลี่ยนจำนวน Node ของ cluster เพิ่มหรือลดเครื่องที่อยู่ข้างใต้ทุกอย่าง (บทถัดไปพูดถึงเรื่องนี้)
flowchart LR
  pods["Deployment Pods"] --> ms["metrics-server"]
  ms --> hpa["HorizontalPodAutoscaler controller"]
  hpa -->|"raise or lower"| replicas["Deployment.spec.replicas"]
metrics-server feeding Pod CPU utilization into the HPA controller, which adjusts a Deployment's replica count
ต้องติดตั้งอะไรใน cluster ก่อน HPA จะตัดสินใจ scale ได้เลย
ทำไม resource requests ถึงเป็นข้อบังคับสำหรับ HPA ที่ scale ตาม CPU/memory
HorizontalPodAutoscaler เปลี่ยนอะไร เทียบกับ VerticalPodAutoscaler และ Cluster Autoscaler
นอกจาก CPU กับ memory แล้ว HPA ยัง scale ตามอะไรได้อีก