[Daily morning study] Kubernetes HPA (Horizontal Pod Autoscaler)
#daily morning study
HPA๋?
HPA(Horizontal Pod Autoscaler)๋ Kubernetes์์ Deployment๋ StatefulSet์ ํ๋ ์๋ฅผ ์๋์ผ๋ก ์กฐ์ ํ๋ ์ปจํธ๋กค๋ฌ๋ค. CPU ์ฌ์ฉ๋ฅ , ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ , ๋๋ ์ปค์คํ ๋ฉํธ๋ฆญ์ ๋ฐ๋ผ ํ๋๋ฅผ ๋๋ฆฌ๊ฑฐ๋ ์ค์ธ๋ค.
์์ง ํ์ฅ(Vertical Scaling)์ด ํ๋์ ๋ ๋ง์ ๋ฆฌ์์ค(CPUยท๋ฉ๋ชจ๋ฆฌ)๋ฅผ ์ฃผ๋ ๋ฐฉ์์ด๋ผ๋ฉด, ์ํ ํ์ฅ(Horizontal Scaling)์ ํ๋ ๊ฐ์ ์์ฒด๋ฅผ ๋๋ฆฌ๋ ๋ฐฉ์์ด๋ค. HPA๋ ํ์๋ฅผ ์๋ํํ๋ค.
๋์ ์๋ฆฌ
HPA๋ ์ปจํธ๋กค ๋ฃจํ(Control Loop)๋ก ๋์ํ๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก 15์ด๋ง๋ค Metrics Server๋ก๋ถํฐ ํ์ฌ ๋ฉํธ๋ฆญ์ ๊ฐ์ ธ์ ๋ชฉํ๊ฐ๊ณผ ๋น๊ตํ๊ณ , ํ์ํ ํ๋ ์๋ฅผ ๊ณ์ฐํ๋ค.
ํ๋ ์ ๊ณ์ฐ ๊ณต์:
desiredReplicas = ceil[currentReplicas ร (currentMetricValue / desiredMetricValue)]
์: ํ์ฌ ํ๋ 2๊ฐ, ๋ชฉํ CPU 50%, ํ์ฌ ํ๊ท CPU 80%
desiredReplicas = ceil[2 ร (80 / 50)] = ceil[3.2] = 4
ํ๋๋ฅผ 4๊ฐ๋ก ๋๋ฆฐ๋ค.
๊ตฌ์ฑ ์์
| ๊ตฌ์ฑ ์์ | ์ญํ |
|---|---|
| Metrics Server | ํ๋์ CPU/๋ฉ๋ชจ๋ฆฌ ๋ฉํธ๋ฆญ ์์ง |
| HPA Controller | ๋ฉํธ๋ฆญ ๊ธฐ๋ฐ์ผ๋ก ํ๋ ์ ๊ฒฐ์ |
| Deployment | ์ค์ ํ๋ ์๋ฅผ ์กฐ์ ํ๋ ๋์ |
HPA ์ค์ ๋ฐฉ๋ฒ
๊ธฐ๋ณธ YAML (CPU ๊ธฐ๋ฐ)
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
minReplicas: ์ต์ ํ๋ ์maxReplicas: ์ต๋ ํ๋ ์averageUtilization: ๋ชฉํ CPU ์ฌ์ฉ๋ฅ (%)
kubectl ๋ช ๋ น์ด๋ก ๋น ๋ฅด๊ฒ ์์ฑ
kubectl autoscale deployment my-app --cpu-percent=50 --min=2 --max=10
์ํ ํ์ธ
kubectl get hpa
kubectl describe hpa my-app-hpa
๋ฉํธ๋ฆญ ์ข ๋ฅ (v2 API)
Resource ๋ฉํธ๋ฆญ โ CPU, ๋ฉ๋ชจ๋ฆฌ ๊ฐ์ ๋ฆฌ์์ค ๊ธฐ๋ฐ
metrics:
- type: Resource
resource:
name: memory
target:
type: AverageValue
averageValue: 500Mi
External ๋ฉํธ๋ฆญ โ ํด๋ฌ์คํฐ ์ธ๋ถ ๋ฉํธ๋ฆญ (SQS ํ ๊ธธ์ด ๋ฑ)
metrics:
- type: External
external:
metric:
name: sqs_queue_length
target:
type: Value
value: "100"
Pods ๋ฉํธ๋ฆญ โ ํ๋ ์์ฒด์ ์ปค์คํ ๋ฉํธ๋ฆญ
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "100"
์ค์ผ์ผ๋ง ๋์ ์ ์ด (behavior)
๊ธ๊ฒฉํ ์ค์ผ์ผ ์
/๋ค์ด์ ๋ฐฉ์งํ๊ธฐ ์ํด behavior ํ๋๋ก ์๋๋ฅผ ์กฐ์ ํ ์ ์๋ค.
spec:
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 5๋ถ ์์ ํ ๊ตฌ๊ฐ
policies:
- type: Percent
value: 10
periodSeconds: 60 # 1๋ถ์ ์ต๋ 10%์ฉ ์ค์
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Pods
value: 4
periodSeconds: 15 # 15์ด๋ง๋ค ์ต๋ 4๊ฐ์ฉ ๋๋ฆผ
์ค์ผ์ผ ๋ค์ด์ ๊ฐ์๊ธฐ ์ค์ด๋ฉด ํธ๋ํฝ ์ฒ๋ฆฌ์ ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์์ด์ ์์ ํ ๊ตฌ๊ฐ์ ๊ธธ๊ฒ ์ก๋๋ค. ์ค์ผ์ผ ์ ์ ๋น ๋ฅด๊ฒ ๋ฐ์ํด์ผ ํ๋ฏ๋ก ์งง๊ฒ ์ค์ ํ๋ ๊ฒ ์ผ๋ฐ์ ์ด๋ค.
์ ์ ์กฐ๊ฑด
1. Metrics Server ์ค์น
HPA๊ฐ ๋์ํ๋ ค๋ฉด Metrics Server๊ฐ ํด๋ฌ์คํฐ์ ์ค์น๋์ด ์์ด์ผ ํ๋ค. ์ค์น๊ฐ ์ ๋์ด ์์ผ๋ฉด kubectl get hpa์์ <unknown>/50%์ฒ๋ผ ๋ฉํธ๋ฆญ์ ๋ชป ์ฝ๋ ์ํ๊ฐ ๋๋ค.
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl top pods
kubectl top nodes
2. resources.requests ์ค์
Deployment์ ํ๋ ์คํ์ resources.requests๊ฐ ๋ช
์๋์ด์ผ CPU ๊ธฐ๋ฐ HPA๊ฐ ์ ์ ๋์ํ๋ค. requests๊ฐ ์์ผ๋ฉด CPU ์ฌ์ฉ๋ฅ ๊ณ์ฐ ๊ธฐ์ค์ด ์์ด์ HPA๊ฐ ์๋ํ์ง ์๋๋ค.
resources:
requests:
cpu: "200m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
HPA vs VPA
| ํญ๋ชฉ | HPA | VPA (Vertical Pod Autoscaler) |
|---|---|---|
| ํ์ฅ ๋ฐฉ์ | ํ๋ ์ ์ฆ๊ฐ | ํ๋ ๋ฆฌ์์ค(CPU/๋ฉ๋ชจ๋ฆฌ) ์ฆ๊ฐ |
| ์ฌ์์ ์ฌ๋ถ | ๋ถํ์ | ๋ณดํต ํ๋ ์ฌ์์ ํ์ |
| ์ ํฉํ ์ํฉ | ๋ฌด์ํ(stateless) ์ฑ | ๋จ์ผ ์ธ์คํด์ค ๋๋ ์ํ ์๋ ์ฑ |
| ์ฌ์ฉ ๋น๋ | ๋์ | ๋ฎ์ |
HPA์ VPA๋ฅผ ๊ฐ์ด ์ธ ์ ์์ง๋ง, CPU/๋ฉ๋ชจ๋ฆฌ ๋ฉํธ๋ฆญ ๊ธฐ๋ฐ์ผ๋ก ๋ ๋ค ํ์ฑํํ๋ฉด ์ถฉ๋์ด ์๊ธด๋ค. ๋ณดํต HPA๋ ์ปค์คํ ๋ฉํธ๋ฆญ, VPA๋ ๋ฆฌ์์ค ์กฐ์ ์ฉ๋๋ก ๋ถ๋ฆฌํด์ ์ฌ์ฉํ๋ค.
์ค๋ฌด์์ ์ฃผ์ํ ์
- ์ค์ผ์ผ ๋ค์ด ์ง์ฐ: ๊ธฐ๋ณธ์ ์ผ๋ก ์ค์ผ์ผ ๋ค์ด์ 5๋ถ ์์ ํ ๊ตฌ๊ฐ์ ๊ฐ์ง๋ค. ํธ๋ํฝ์ด ๋น ์ ธ๋ ๋ฐ๋ก ์ค์ด์ง ์๋๋ค.
- Cold Start ๋ฌธ์ : ํ๋๊ฐ ์๋ก ๋จ๋ ๋ฐ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ ์ฑ์ด๋ผ๋ฉด
minReplicas๋ฅผ ๋๋ํ ์ก๊ฑฐ๋ Readiness Probe๋ฅผ ์ฒ ์ ํ ์ค์ ํด์ผ ํ๋ค. - Metrics Server ์ ๋ขฐ๋: ๋ฉํธ๋ฆญ ์์ง์ด ์ผ์์ ์ผ๋ก ์คํจํ๋ฉด HPA๋ ์ค์ผ์ผ๋ง์ ๋ฉ์ถ๋ค. ์๋ ์ค์ ์ ๊ถ์ฅํ๋ค.
- minReplicas: 0 ๋ถ๊ฐ: ๊ธฐ๋ณธ HPA๋ก๋ 0์ผ๋ก ์ค์ผ ์ ์๋ค. ์์ ์ข ๋ฃ๊ฐ ํ์ํ๋ฉด KEDA(Kubernetes Event-Driven Autoscaling)๋ฅผ ์จ์ผ ํ๋ค.