참고문서
https://kubernetes.io/ko/docs/tasks/run-application/horizontal-pod-autoscale/
Horizontal Pod Autoscaling
쿠버네티스에서, HorizontalPodAutoscaler 는 워크로드 리소스(예: 디플로이먼트 또는 스테이트풀셋)를 자동으로 업데이트하며, 워크로드의 크기를 수요에 맞게 자동으로 스케일링하는 것을 목표로 한
kubernetes.io
HPA 생성
[root@k8s-master ~]# k autoscale deployment hello-app --cpu-percent 80 --min 2 --max 5
생성 확인
[root@k8s-master ~]# k get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hello-app Deployment/hello-app cpu: <unknown>/80% 2 5 2 3d5h
metric을 측정하지 못 하는 것이 발견됨
Log 확인
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedGetResourceMetric 52m (x30 over 124m) horizontal-pod-autoscaler failed to get cpu utilization: missing request for cpu in container hello-app of Pod hello-app-6c5887b5f-fslmh
Warning FailedGetResourceMetric 2m12s (x440 over 127m) horizontal-pod-autoscaler failed to get cpu utilization: missing request for cpu in container hello-app of Pod hello-app-6c5887b5f-bs5xr
그래서 deployment의 resource에 아래와 같이 requests를 설정해야 한다
requests cpu 추가
spec:
template:
spec:
containers:
resources:
requests:
cpu: "100m"
metric 확인
[root@k8s-master ~]# k get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hello-app Deployment/hello-app cpu: 1%/80% 2 5 2 3d5h
HPA yaml
memory까지 임계치와 metric을 수집할 수 있도록 아래와 같이 HPA yaml 수정
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: hello-app
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: hello-app
minReplicas: 2
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
확인
[root@k8s-master ~]# k get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hello-app Deployment/hello-app cpu: 1%/80%, memory: <unknown>/70% 2 5 2 3d5h
CPU와 동일하게 memory도 metric이 수집되도록 requests 추가해주면 아래와 같이 metric이 확인됨
[root@k8s-master ~]# k get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hello-app Deployment/hello-app cpu: 1%/80%, memory: 1%/70% 2 5 2 3d5h
부하테스트
# 스크립트 작성
cat << 'EOF' > k6-hello.js
import http from 'k6/http';
import { sleep } from 'k6';
export let options = {
stages: [
{ duration: '1m', target: 100 }, // 워밍업
{ duration: '3m', target: 700 }, // 부하 증가
{ duration: '3m', target: 5000 }, // 강한 부하
{ duration: '2m', target: 0 }, // 종료
],
};
export default function () {
http.get('http://hello-app.default.svc.cluster.local');
sleep(1);
}
EOF
# configmap 생성
kubectl create configmap k6-script --from-file=k6-hello.js
# k6 yaml 생성
cat << 'EOF' > k6-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: k6-hello-test
spec:
backoffLimit: 0
template:
spec:
restartPolicy: Never
containers:
- name: k6
image: grafana/k6:latest
command: ["k6", "run", "/scripts/k6-hello.js"]
volumeMounts:
- name: k6-script
mountPath: /scripts
volumes:
- name: k6-script
configMap:
name: k6-script
EOF
# job 생성
kubectl apply -f k6-job.yaml
#결과 확인
[root@k8s-master ~]# k get job
NAME STATUS COMPLETIONS DURATION AGE
k6-hello-test Complete 1/1 9m20s 10m
k6 job이 완료되는 동안의 기록을 아래와 얻었다
기록을 확인하면 알 수 있는 것과 같이 부하가 임계치를 넘어 최대 pod 수인 5까지 생성되었다가,
job이 모두 끝난 후 시간이 지나자 최소 pod 수인 2로 다시 원복되는 것을 확인하였다.
[root@k8s-master ~]# k get hpa -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hello-app Deployment/hello-app cpu: 1%/80%, memory: 7%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 1%/80%, memory: 7%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 4%/80%, memory: 7%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 6%/80%, memory: 7%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 8%/80%, memory: 7%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 11%/80%, memory: 7%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 15%/80%, memory: 7%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 19%/80%, memory: 7%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 24%/80%, memory: 7%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 28%/80%, memory: 7%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 32%/80%, memory: 7%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 35%/80%, memory: 7%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 38%/80%, memory: 8%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 40%/80%, memory: 8%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 40%/80%, memory: 8%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 39%/80%, memory: 9%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 42%/80%, memory: 9%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 45%/80%, memory: 9%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 68%/80%, memory: 12%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 85%/80%, memory: 14%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 97%/80%, memory: 17%/70% 2 5 2 11d
hello-app Deployment/hello-app cpu: 103%/80%, memory: 19%/70% 2 5 3 11d
hello-app Deployment/hello-app cpu: 107%/80%, memory: 21%/70% 2 5 3 11d
hello-app Deployment/hello-app cpu: 83%/80%, memory: 16%/70% 2 5 3 11d
hello-app Deployment/hello-app cpu: 92%/80%, memory: 19%/70% 2 5 3 11d
hello-app Deployment/hello-app cpu: 105%/80%, memory: 21%/70% 2 5 4 11d
hello-app Deployment/hello-app cpu: 102%/80%, memory: 16%/70% 2 5 4 11d
hello-app Deployment/hello-app cpu: 87%/80%, memory: 18%/70% 2 5 4 11d
hello-app Deployment/hello-app cpu: 95%/80%, memory: 19%/70% 2 5 4 11d
hello-app Deployment/hello-app cpu: 96%/80%, memory: 20%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 89%/80%, memory: 17%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 64%/80%, memory: 17%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 47%/80%, memory: 17%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 37%/80%, memory: 17%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 30%/80%, memory: 17%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 21%/80%, memory: 17%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 15%/80%, memory: 17%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 6%/80%, memory: 17%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 2%/80%, memory: 16%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 1%/80%, memory: 16%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 1%/80%, memory: 16%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 1%/80%, memory: 16%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 1%/80%, memory: 16%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 1%/80%, memory: 16%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 1%/80%, memory: 16%/70% 2 5 5 11d
hello-app Deployment/hello-app cpu: 1%/80%, memory: 20%/70% 2 5 4 11d
hello-app Deployment/hello-app cpu: 1%/80%, memory: 24%/70% 2 5 3 11d
hello-app Deployment/hello-app cpu: 1%/80%, memory: 24%/70% 2 5 3 11d
hello-app Deployment/hello-app cpu: 1%/80%, memory: 30%/70% 2 5 2 11d
[root@k8s-master ~]# k get po -w
NAME READY STATUS RESTARTS AGE
hello-app-76f76c9cc8-dkfks 1/1 Running 1 7d22h
hello-app-76f76c9cc8-xv6bc 1/1 Running 1 7d22h
k6-hello-test-nrf67 0/1 ContainerCreating 0 6s
test-nginx-684bb88ff4-pg9xl 1/1 Running 2 33d
k6-hello-test-nrf67 1/1 Running 0 12s
hello-app-76f76c9cc8-wczgb 0/1 Pending 0 0s
hello-app-76f76c9cc8-wczgb 0/1 Pending 0 0s
hello-app-76f76c9cc8-wczgb 0/1 ContainerCreating 0 0s
hello-app-76f76c9cc8-wczgb 1/1 Running 0 2s
hello-app-76f76c9cc8-w7n49 0/1 Pending 0 0s
hello-app-76f76c9cc8-w7n49 0/1 Pending 0 0s
hello-app-76f76c9cc8-w7n49 0/1 ContainerCreating 0 0s
hello-app-76f76c9cc8-w7n49 1/1 Running 0 1s
hello-app-76f76c9cc8-bdjch 0/1 Pending 0 0s
hello-app-76f76c9cc8-bdjch 0/1 Pending 0 0s
hello-app-76f76c9cc8-bdjch 0/1 ContainerCreating 0 0s
hello-app-76f76c9cc8-bdjch 1/1 Running 0 2s
k6-hello-test-nrf67 0/1 Completed 0 9m18s
hello-app-76f76c9cc8-bdjch 1/1 Terminating 0 5m31s
hello-app-76f76c9cc8-bdjch 0/1 Error 0 5m31s
hello-app-76f76c9cc8-bdjch 0/1 Error 0 5m32s
hello-app-76f76c9cc8-bdjch 0/1 Error 0 5m32s
hello-app-76f76c9cc8-w7n49 1/1 Terminating 0 6m46s
hello-app-76f76c9cc8-w7n49 0/1 Error 0 6m46s
hello-app-76f76c9cc8-w7n49 0/1 Error 0 6m46s
hello-app-76f76c9cc8-w7n49 0/1 Error 0 6m46s
hello-app-76f76c9cc8-wczgb 1/1 Terminating 0 8m16s
hello-app-76f76c9cc8-wczgb 0/1 Error 0 8m16s
hello-app-76f76c9cc8-wczgb 0/1 Error 0 8m17s
hello-app-76f76c9cc8-wczgb 0/1 Error 0 8m17s
[root@k8s-master ~]# k get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
hello-app 5/5 5 5 67d
test-nginx 1/1 1 1 55d
[root@k8s-master ~]#
[root@k8s-master ~]#
[root@k8s-master ~]# k get po
NAME READY STATUS RESTARTS AGE
hello-app-76f76c9cc8-dkfks 1/1 Running 1 7d22h
hello-app-76f76c9cc8-w7n49 1/1 Running 0 6m37s
hello-app-76f76c9cc8-wczgb 1/1 Running 0 7m37s
hello-app-76f76c9cc8-xv6bc 1/1 Running 1 7d22h
k6-hello-test-nrf67 0/1 Completed 0 12m
test-nginx-684bb88ff4-pg9xl 1/1 Running 2 33d
[root@k8s-master ~]# k get po
NAME READY STATUS RESTARTS AGE
hello-app-76f76c9cc8-dkfks 1/1 Running 1 7d22h
hello-app-76f76c9cc8-xv6bc 1/1 Running 1 7d22h
k6-hello-test-nrf67 0/1 Completed 0 13m
test-nginx-684bb88ff4-pg9xl 1/1 Running 2 33d
[root@k8s-master ~]# k get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
hello-app 2/2 2 2 67d
test-nginx 1/1 1 1 55d
[root@k8s-master ~]#
이외에도 HPA를 활용하는 다양한 방법이 있는 것 같다.
외부와 연결한다든지 파드와 연결한다든지 metric을 다양하게 쓸 수 있다한다.
추후에 관련해서 보충 블로깅을 하고싶기는 하다.
'k8s' 카테고리의 다른 글
| Cilium 설치 (0) | 2026.02.03 |
|---|---|
| VPA (0) | 2025.12.24 |
| metric server 설치 (0) | 2025.09.02 |
| node join 및 delete (0) | 2025.08.28 |
| ansible 을 활용한 k8s 클러스터 구축 (0) | 2025.08.01 |