Hrizontal Pod Autoscaler
는 지정한 메트릭을 관찰하여 부하 정도에 따라 Pod
개수를 자동으로 Scaling
한다.
이번 글에서는 CPU 사용률
에 따라서 Pod
의 개수가 자동으로 늘어났다 줄어들었다할 수 있도록 HPA
를 세팅해 본다.
HPA
나 kubectl top
명령어를 사용하려면 클러스터에 metrics-server
가 설치되어 있어야 한다.
다음 명령어를 통해 metrics-server
를 설치한다.
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
설치 확인
$ kubectl get apiservices | grep metrics-server
v1beta1.metrics.k8s.io kube-system/metrics-server True 3h23m
이번 글에서 사용하는 api 코드의 일부이다.
cpu 부하를 주기위해 반복문을 사용했다.
app.get('/api/load-cpu', (req, res) => {
let load = 0;
for (let i = 0; i < 100000000; i++) {
load += i;
}
res.json({load: load});
});
위 코드를 작성하고 도커 이미지를 만들어 ECR에 업로드하였다.
도커 이미지 : public.ecr.aws/p4g1u1f9/23724-k8s/api:13
Deployment
에 도커 이미지를 지정하고 HPA
테스트를 위해 Service
를 nodePort
유형으로 생성해준다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-api
spec:
selector:
matchLabels:
app: test-api
tier: back
template:
metadata:
labels:
app: test-api
tier: back
spec:
containers:
- name: test-api
image: public.ecr.aws/p4g1u1f9/23724-k8s/api:13
ports:
- containerPort: 8080
resources:
limits:
cpu: 200m
memory: 500Mi
requests:
cpu: 100m
memory: 300Mi
---
apiVersion: v1
kind: Service
metadata:
name: test-api
spec:
type: NodePort
selector:
app: test-api
tier: back
ports:
- port: 8080
nodePort: 30000
Deployment
에 .spec.replicas
를 지정하지 않았기 때문에 기본으로 Pod
하나가 생성되었다.
아직은 api
호출을 하지 않았기 때문에 CPU
가 0m
이다.
$ kubectl top po
NAME CPU(cores) MEMORY(bytes)
test-api-7fc5955f97-8f8fp 0m 29Mi
curl node-ip/nodePort
로 api 호출 테스트를 해보면 살짝 딜레이 후 response
가 오는 것을 볼 수 있을 것이다.
$ curl 24.0.3.177:30000/api/load-cpu
{"load":4999999950000000}
이제 api
를 무한으로 호출하는 쉘 스크립트를 작성한다. (load-cpu.sh
)
#!/bin/bash
count=0
while :
do
curl 24.0.3.177:30000/api/load-cpu > /dev/null 2>&1
if [ `expr $count % 100` -eq 0 ]
then
echo $count
fi
((count++))
done
이제 HPA
를 생성해보자.
명령어
또는 yaml
을 정의하여 생성할 수 있는데 아래는 모두 cpu 사용량 50%
를 기준으로 하여 Pod
의 개수를 1부터 10
사이로 유지하는 Horizontal Pod Autoscaler
를 의미한다.
$ kubectl autoscale deployment test-api --cpu-percent=50 --min=1 --max=10
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: test-api
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: test-api
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
명령어
를 실행하거나 yaml
파일을 apply
해주면 HPA
가 생성된다.
부하를 주기 전에 HPA
를 조회해보면 기준 50%
에 현재는 0%
인 것을 볼 수 있다.
$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
test-api Deployment/test-api 0%/50% 1 10 1 3m39s
위에서 작성한 load-cpu.sh
을 실행시킨다.
$ ./load-cpu.sh &
얼마 지나지 않아 Pod
의 CPU 사용률
을 조회해보면 201m
으로 늘어나 있다.
$ kubectl top po
NAME CPU(cores) MEMORY(bytes)
test-api-7fc5955f97-8f8fp 201m 29Mi
HPA
의 TARGETS
를 보아도 알 수 있다.
$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
test-api Deployment/test-api 201%/50% 1 10 1 4m27s
Pod
를 조회해 보면 부하를 분산하기 위해 자동으로 3개의 Pod
가 새로 생성되었다.
$ kubectl get po
NAME READY STATUS RESTARTS AGE
test-api-7fc5955f97-4wcw8 1/1 Running 0 9s
test-api-7fc5955f97-8f8fp 1/1 Running 0 6m53s
test-api-7fc5955f97-8jbkr 1/1 Running 0 9s
test-api-7fc5955f97-qc4l4 1/1 Running 0 9s
실제로 CPU 사용률을 보면 여러 Pod들이 각각 부하를 분산하여 처리하는 것을 볼 수 있다.
(몇초 사이에 hr7cr
이 추가로 생성되어 총 5개의 Pod가 됨)
$ kubectl top po
NAME CPU(cores) MEMORY(bytes)
test-api-7fc5955f97-4wcw8 46m 28Mi
test-api-7fc5955f97-8f8fp 69m 29Mi
test-api-7fc5955f97-8jbkr 47m 28Mi
test-api-7fc5955f97-hr7cr 15m 29Mi
test-api-7fc5955f97-qc4l4 63m 29Mi
$ kubectl top po
NAME CPU(cores) MEMORY(bytes)
test-api-7fc5955f97-4wcw8 74m 28Mi
test-api-7fc5955f97-8f8fp 0m 30Mi
test-api-7fc5955f97-8jbkr 34m 29Mi
test-api-7fc5955f97-hr7cr 39m 29Mi
test-api-7fc5955f97-qc4l4 19m 29Mi
$ kubectl top po
NAME CPU(cores) MEMORY(bytes)
test-api-7fc5955f97-4wcw8 50m 29Mi
test-api-7fc5955f97-8f8fp 0m 29Mi
test-api-7fc5955f97-8jbkr 0m 29Mi
test-api-7fc5955f97-hr7cr 53m 29Mi
test-api-7fc5955f97-qc4l4 77m 29Mi
$ kubectl top po
NAME CPU(cores) MEMORY(bytes)
test-api-7fc5955f97-4wcw8 57m 28Mi
test-api-7fc5955f97-8f8fp 33m 29Mi
test-api-7fc5955f97-8jbkr 36m 29Mi
test-api-7fc5955f97-hr7cr 39m 29Mi
test-api-7fc5955f97-qc4l4 73m 29Mi
이제 쉘 스크립트를 종료한다.
$ fg
./load-cpu.sh
^C
모든 Pod
의 CPU 사용률
이 내려갔다.
$ kubectl top po
NAME CPU(cores) MEMORY(bytes)
test-api-7fc5955f97-4wcw8 0m 29Mi
test-api-7fc5955f97-8f8fp 0m 29Mi
test-api-7fc5955f97-8jbkr 0m 29Mi
test-api-7fc5955f97-hr7cr 0m 29Mi
test-api-7fc5955f97-qc4l4 0m 29Mi
시간이 지나고 다시 Pod
가 1개로 줄어들었다.
$ kubectl get po
NAME READY STATUS RESTARTS AGE
test-api-7fc5955f97-8f8fp 1/1 Running 0 20m
참고