Kubernetes HPA (Horizontal Pod Autoscaler)
목차
- 수평적 Pod 자동 조정기(scale-out)로 시스템의 가동 상황에 맞춰 시스템을 유연하게 확장 축소
- CPU, Memory 사용량을 관찰하여 Deployment, ReplicaSet, StatefulSet의 Pod 개수를 자동 확장(DaemonSet 제외)
- 컨트롤러는 관찰된 평균 CPU 사용률이 사용자가 지정한 대상과 일치하도록 Deployment에서 replicas 개수를 주기적으로 조정
- 워크로드의 크기를 수요에 맞게 자동으로 스케일링하는 것이 목표
HPA 매커니즘, 적정 Pod 개수 지정 알고리즘
- HPA 컨트롤러는 원하는(desired) Metric값과 현재(current) Metric값 사이의 비율로 작동
- Metric값이 200m이고 원하는 값 100m 인경우 200.0/100.0 == 2.0 이므로 복제본 수가 두배가 됨
- Metric값이 50m 이면 50.0/100.0==0.5이므로 복제본수를 반으로 줄임
- 조정할 레플리카 갯수 =
ceil [ 현재 레플리카 갯수 * ( 현재 Metric / 원하는 Metric) ] - 주로 Deployment에 연결하고, 옵션으로 resources를 반드시 포함해야한다.
작동 순서
- metric 수집
- metric server가 집계
- 수집한 정보(metric) APIserver에 전달
- APIserver가 HPA에 전달(Get Memory, CPU → default: 15sec)
- HPA가 Replicaset에 전달
- Replicaset이 scale 정보를 APIserver에 전달
- etcd에 기록, scheduler가 Pod 생성 node 지정
- Node kubelet이 scale 정보확인
- Pod 생성 / 축소 (scale in/out)
HPA를 위한 metric server 구성
# 최신 정보 , https://github.com/kubernetes-sigs/metrics-server/releases/
$ kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
#비활성화 상태
$ kubectl -n kube-system get deployments.apps metrics-server
NAME READY UP-TO-DATE AVAILABLE AGE
metrics-server 0/1 1 0 96s
$ kubectl get apiservices | grep metrics
v1beta1.metrics.k8s.io kube-system/metrics-server False (MissingEndpoints) 4m12s
#활성화
$ kubectl edit -n kube-system deployments.apps metrics-server
...
spec:
containers:
- args:
- --cert-dir=/tmp
- --secure-port=4443
- --kubelet-insecure-tls # 추가, 저장후 반영되기까지 시간 소요 약 20초 이상
...
$ kubectl get apiservices | grep metrics
v1beta1.metrics.k8s.io kube-system/metrics-server True 4m43s
$ kubectl -n kube-system get deployments.apps metrics-server
NAME READY UP-TO-DATE AVAILABLE AGE
metrics-server 1/1 1 1 5m5s
#정보확인 kubectl top
$ kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-master 273m 6% 5759Mi 73%
k8s-node1 139m 3% 3662Mi 46%
k8s-node2 152m 3% 3658Mi 46%
$ kubectl top po
cm-volume-pod 0m 4Mi
cmtest-pod 0m 7Mi
kubeshark-front-5d78866868-z5kq5 1m 4Mi
kubeshark-hub-697dfcbd8b-ktfv7 7m 22Mi
kubeshark-worker-daemon-set-crc7b 9m 114Mi
kubeshark-worker-daemon-set-l7lsh 10m 118Mi
kubeshark-worker-daemon-set-v2crv 10m 110Mi
nginx-app-pod 0m 4Mi
openebs-pod 0m 3MiHPA 테스트
사전 설정
$ kubectl create deployment hpa-test --image nginx --port 80 --replicas=2
deployment.apps/hpa-test created
$ kubectl expose deployment hpa-test --name hpa-test-svc --type NodePort --port 80 --target-port 80
service/hpa-test-svc exposed
$ kubectl edit deployment hpa-test
#아래의 내용 추가
...
spec:
...
template:
...
spec:
containers:
- image: nginx
...
resources:
requests:
cpu: 10m
limits:
cpu: 20m
#확인
$ kubectl describe deployments.apps hpa-test
Name: hpa-test
Namespace: default
CreationTimestamp: Mon, 22 Apr 2024 13:46:18 +0900
Labels: app=hpa-test
Annotations: deployment.kubernetes.io/revision: 2
Selector: app=hpa-test
Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=hpa-test
Containers:
nginx:
Image: nginx
Port: 80/TCP
Host Port: 0/TCP
Limits:
cpu: 20m
Requests:
cpu: 10m
$ kubectl get po,svc -o wide | grep hpa
pod/hpa-cpu50-deploy-85d5cf789-hdlh9 1/1 Running 0 8m25s 10.111.156.111 k8s-node1 <none> <none>
pod/hpa-cpu50-deploy-85d5cf789-qr6w5 1/1 Running 0 8m25s 10.109.131.37 k8s-node2 <none> <none>
pod/hpa-test-554d698b6d-4mwss 1/1 Running 0 84s 10.111.156.113 k8s-node1 <none> <none>
pod/hpa-test-554d698b6d-9s6q5 1/1 Running 0 76s 10.109.131.39 k8s-node2 <none> <none>
service/hpa-test-svc NodePort 10.103.52.170 <none> 80:30746/TCP 3m43s app=hpa-test
#curl yourNodeIP:NodePort
$ curl 10.10.10.91:30746
...테스트
hpa.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
creationTimestamp: null
name: hpa-test
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: hpa-test
targetCPUUtilizationPercentage: 50
status:
currentReplicas: 0
desiredReplicas: 0수정된 hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
creationTimestamp: null
name: hpa-test
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: hpa-test
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
status:
currentReplicas: 0
desiredReplicas: 0#hpa 생성
$ kubectl autoscale deployment hpa-test --cpu-percent 50 --min 1 --max 10 --dry-run=client -o yaml > hpa.yaml
$ kubectl api-resources | grep -i hpa
horizontalpodautoscalers hpa autoscaling/v2 true HorizontalPodAutoscaler
#hpa 수정 위의 내용 참조
$ vi hpa.yaml
#hpa 실행
$ kubectl apply -f hpa.yaml
horizontalpodautoscaler.autoscaling/hpa-test created
#부하 테스트 및 확인
#모니터링을 통해 레플리카가 증가하는 것 확인 가능
#워크로드 종료후 레플리카 감소 하는것 확인 가능
#추가 터미널 모니터링
$ kubectl get hpa -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hpa-test Deployment/hpa-test 0%/50% 1 10 2 15s
hpa-test Deployment/hpa-test 35%/50% 1 10 2 60s
hpa-test Deployment/hpa-test 55%/50% 1 10 2 75s
hpa-test Deployment/hpa-test 55%/50% 1 10 3 90s
hpa-test Deployment/hpa-test 40%/50% 1 10 3 105s
hpa-test Deployment/hpa-test 36%/50% 1 10 3 2m
hpa-test Deployment/hpa-test 33%/50% 1 10 3 3m1s
hpa-test Deployment/hpa-test 36%/50% 1 10 3 3m16s
#추가2 대량 workload 수행
$ while true; do curl 10.10.10.91:30746; sleep 0.05; done