이전 장에서는 HorizontalPodAutoscaler에 대한 기본적인 내용에 대해 알아보았다. HorizontalPodAutoscaler에 대해 처음 들어보았다면 아래 글을 먼저 읽어보는 것이 좋다.
2025.01.05 - [DevOps/Kubernetes] - Kubernetes HPA (파드 오토스케일링) [1] - 기초
autoscaling/v2
버전의 HorizontalPodAutoscaler을 사용한다면 behavior
필드를 사용하여 scale-out / scale-in의 세부 동작을 구성할 수 있다. HPA에서는 파드 수평 확장/축소를 scale-up / scale-down으로 명명하고 있다는 점을 참고하자.
behavior.scaleUp
: 파드 수평확장 (scale-out) 에 대한 동작 구성behavior.scaleDown
: 파드 수평축소 (scale-in) 에 대한 동작 구성
Pod 갯수 기반
behavior에서는 scale-up / scale-down 시작 시 파드의 갯수를 제한시킬 수 있다.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: todo-api
namespace: todo
spec:
minReplicas: 1
maxReplicas: 5
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: todo-api
metrics:
- resource:
name: cpu
target:
averageUtilization: 50
type: Utilization
type: Resource
behavior:
scaleUp:
policies:
- type: Pods
value: 1
periodSeconds: 60
scaleDown:
policies:
- type: Pods
value: 1
periodSeconds: 60
spec.behavior.scaleUp.policies
: 스케일업에 대한 세부 정책을 여러개 등록할 수 있다. (scaleDown도 마찬가지)spec.behavior.scaleUp.policies[].type
: 스케일업 정책 시 기준이 되는 타입이며, 여기에는 Pods, Percent 등이 올 수 있다.spec.behavior.scaleUp.policies[].value
: 스케일업 정책 시 기준이 되는 타입에 대한 값으로, type이 Pods인 경우 스케일업이 되는 조건이 되면 최대value
개수만큼 추가 레플리카를 생성한다.spec.behavior.scaleUp.policies[].periodSeconds
: 스케일업 정책 시 스케일업 시간으로, 해당 정책이 유지되어야 하는 시간을 의미한다. 한번 스케일 업이 이루어지면,periodSeconds
동안 추가적인 스케일업/다운이 진행되지 않는다.
위의 예시에서는 스케일업이 진행되는 경우, 파드를 최대 1개씩 1분 주기로 증가시키며, 스케일다운이 진행되는 경우, 파드를 최대 1개씩 1분 주기로 감소시킨다. 위와 같이 HPA를 적용시킨 후 부하테스트를 진행한 경과를 보여주면 다음과 같다.
부하테스트 (100ms)
$ while true; do; curl -XGET http://todo-api.beer1.com/todoList; sleep 0.1; done
부하테스트 결과
$ while true; do; kubectl get hpa; sleep 10; done
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
todo-api Deployment/todo-api 6%/50% 1 5 1 17h ## 부하테스트 시작
todo-api Deployment/todo-api 5%/50% 1 5 1 17h
todo-api Deployment/todo-api 76%/50% 1 5 1 17h
todo-api Deployment/todo-api 76%/50% 1 5 1 17h ## scale-up
todo-api Deployment/todo-api 191%/50% 1 5 2 17h
todo-api Deployment/todo-api 242%/50% 1 5 2 17h
todo-api Deployment/todo-api 242%/50% 1 5 2 17h
todo-api Deployment/todo-api 110%/50% 1 5 2 17h
todo-api Deployment/todo-api 107%/50% 1 5 2 17h
todo-api Deployment/todo-api 107%/50% 1 5 2 17h ## scale-up
todo-api Deployment/todo-api 61%/50% 1 5 3 17h
todo-api Deployment/todo-api 59%/50% 1 5 3 17h
todo-api Deployment/todo-api 59%/50% 1 5 3 17h
todo-api Deployment/todo-api 54%/50% 1 5 3 17h
todo-api Deployment/todo-api 79%/50% 1 5 3 17h
todo-api Deployment/todo-api 79%/50% 1 5 3 17h ## scale-up
todo-api Deployment/todo-api 67%/50% 1 5 4 17h
todo-api Deployment/todo-api 63%/50% 1 5 4 17h
todo-api Deployment/todo-api 63%/50% 1 5 4 17h ## 부하테스트 종료
todo-api Deployment/todo-api 52%/50% 1 5 4 17h
todo-api Deployment/todo-api 45%/50% 1 5 4 17h
todo-api Deployment/todo-api 45%/50% 1 5 4 17h
todo-api Deployment/todo-api 19%/50% 1 5 4 17h
todo-api Deployment/todo-api 5%/50% 1 5 4 17h
todo-api Deployment/todo-api 5%/50% 1 5 4 17h
todo-api Deployment/todo-api 7%/50% 1 5 4 17h
todo-api Deployment/todo-api 6%/50% 1 5 4 17h
todo-api Deployment/todo-api 6%/50% 1 5 4 17h
todo-api Deployment/todo-api 6%/50% 1 5 4 17h
todo-api Deployment/todo-api 11%/50% 1 5 4 17h
todo-api Deployment/todo-api 11%/50% 1 5 4 17h
todo-api Deployment/todo-api 6%/50% 1 5 4 17h
todo-api Deployment/todo-api 7%/50% 1 5 4 17h
todo-api Deployment/todo-api 7%/50% 1 5 4 17h
todo-api Deployment/todo-api 7%/50% 1 5 4 17h
todo-api Deployment/todo-api 7%/50% 1 5 4 17h
todo-api Deployment/todo-api 7%/50% 1 5 4 17h
todo-api Deployment/todo-api 5%/50% 1 5 4 17h
todo-api Deployment/todo-api 5%/50% 1 5 4 17h
todo-api Deployment/todo-api 5%/50% 1 5 4 17h
todo-api Deployment/todo-api 6%/50% 1 5 4 17h
todo-api Deployment/todo-api 5%/50% 1 5 4 17h
todo-api Deployment/todo-api 5%/50% 1 5 4 17h
todo-api Deployment/todo-api 7%/50% 1 5 4 17h
todo-api Deployment/todo-api 4%/50% 1 5 4 17h
todo-api Deployment/todo-api 4%/50% 1 5 4 17h
todo-api Deployment/todo-api 7%/50% 1 5 4 17h
todo-api Deployment/todo-api 4%/50% 1 5 4 17h
todo-api Deployment/todo-api 4%/50% 1 5 4 17h
todo-api Deployment/todo-api 5%/50% 1 5 4 17h
todo-api Deployment/todo-api 4%/50% 1 5 4 17h ## scale-down
todo-api Deployment/todo-api 8%/50% 1 5 3 17h
todo-api Deployment/todo-api 8%/50% 1 5 3 17h
todo-api Deployment/todo-api 5%/50% 1 5 3 17h
todo-api Deployment/todo-api 6%/50% 1 5 3 17h
todo-api Deployment/todo-api 6%/50% 1 5 3 17h
todo-api Deployment/todo-api 4%/50% 1 5 3 17h ## scale-down
todo-api Deployment/todo-api 7%/50% 1 5 2 17h
todo-api Deployment/todo-api 7%/50% 1 5 2 17h
todo-api Deployment/todo-api 5%/50% 1 5 2 17h
todo-api Deployment/todo-api 6%/50% 1 5 2 17h
todo-api Deployment/todo-api 6%/50% 1 5 2 17h
todo-api Deployment/todo-api 5%/50% 1 5 2 17h ## scale-down
todo-api Deployment/todo-api 7%/50% 1 5 1 17h
todo-api Deployment/todo-api 7%/50% 1 5 1 17h
todo-api Deployment/todo-api 4%/50% 1 5 1 17h
todo-api Deployment/todo-api 4%/50% 1 5 1 17h
todo-api Deployment/todo-api 4%/50% 1 5 1 17h
todo-api Deployment/todo-api 5%/50% 1 5 1 17h
todo-api Deployment/todo-api 4%/50% 1 5 1 17h
todo-api Deployment/todo-api 4%/50% 1 5 1 17h
- 첫 번째 scale-up이 일어났을 때는 평균 CPU 사용율이 76%이고, 계산하면
ceil(76/50) = ceil(1.52)
이다. 이 때 레플리카는 2가 된다. - 실제로 두 번째 scale-up이 일어나기 전에도 평균 CPU 사용율이 50%가 넘어가지만 behavior에 의해 1분동안 파드 스케일업이 진행되지 않는다.
- 두 번째 scale-up이 일어났을 때의 평균 CPU 사용율이 107%이고, 계산하면
ceil(2*107 / 50) = ceil(4.28)
으로 레플리카는 5가 되어 3개의 레플리카가 추가로 증설이 되어야 하지만 behavior에 의해 레플리카는 1개만 추가된다. 즉, 여기서 레플리카 갯수는 3이 된다. - 부하테스트가 종료된 후 5분동안은 scale-down 조건을 만족하지만 컨트롤러의
--horizontal-pod-autoscaler-downscale-stabilization
설정에 의해 scale-down이 일어나지 않는다. - 첫 번째 scale-down이 일어났을 때는 5분동안은 scale-down 조건을 만족하는 경우 발생하는데, 이 때 CPU 평균 사용율이 4%이고, 계산하면
ceil(4*4 / 50) = ceil(0.32)
으로 레플리카는 1이 되어야 하지만 behavior에 의해 레플리카는 1개만 줄어든다. 즉, 여기서 레플리카 갯수는 3이 된다. - 실제로 두 번째 scale-down이 일어나기 전에도 평균 CPU 사용율이 한참 낮지만 behavior에 의해 1분동안 파드 스케일다운이 진행되지 않는다.
Percent 기반 및 stabilizationWindowSeconds
behavior에서는 scale-up / scale-down 시작 시 현재 레플리카에 대한 비율로 파드를 늘리고 줄일 수도 있다. 그리고 scale-up / down에 대해 각각 stabilizationWindowSeconds
을 지정할 수 있는데, 이는 스케일 업/다운 조건이 만족하는 경우에 해당 시간동안 계속 스케일 업/다운 조건이 만족하면 실제로 스케일 다운이 일어나도록 하는 설정이다. --horizontal-pod-autoscaler-downscale-stabilization
의 HPA별 개별 설정으로 이해하면 된다.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: todo-api
namespace: todo
spec:
minReplicas: 1
maxReplicas: 10
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: todo-api
metrics:
- resource:
name: cpu
target:
averageUtilization: 50
type: Utilization
type: Resource
behavior:
scaleUp:
policies:
- type: Percent
value: 100
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 50
periodSeconds: 60
spec.behavior.scaleUp.policies[].value
: 스케일업 정책 시 기준이 되는 타입에 대한 값으로, type이 Percent인 경우 스케일업이 되는 조건이 되면 최대현재 레플리카 수 * value / 100
개수만큼 추가 레플리카를 생성한다.
위의 설정으로 HPA를 변경한 후 똑같이 부하 테스트를 해보면 다음과 같다.
$ while true; do; kubectl get hpa; sleep 10; done
todo-api Deployment/todo-api 8%/50% 1 10 1 18h ## 부하테스트 시작
todo-api Deployment/todo-api 5%/50% 1 10 1 18h
todo-api Deployment/todo-api 87%/50% 1 10 1 18h ## scale-up
todo-api Deployment/todo-api 131%/50% 1 10 2 18h
todo-api Deployment/todo-api 131%/50% 1 10 2 18h
todo-api Deployment/todo-api 75%/50% 1 10 2 18h
todo-api Deployment/todo-api 126%/50% 1 10 2 18h
todo-api Deployment/todo-api 126%/50% 1 10 2 18h
todo-api Deployment/todo-api 120%/50% 1 10 2 18h ## scale-up
todo-api Deployment/todo-api 94%/50% 1 10 4 18h
todo-api Deployment/todo-api 94%/50% 1 10 4 18h
todo-api Deployment/todo-api 55%/50% 1 10 4 18h
todo-api Deployment/todo-api 69%/50% 1 10 4 18h
todo-api Deployment/todo-api 69%/50% 1 10 4 18h
todo-api Deployment/todo-api 66%/50% 1 10 4 18h ## scale-up
todo-api Deployment/todo-api 60%/50% 1 10 6 18h
todo-api Deployment/todo-api 60%/50% 1 10 6 18h
todo-api Deployment/todo-api 51%/50% 1 10 6 18h ## 부하테스트 종료
todo-api Deployment/todo-api 9%/50% 1 10 6 18h
todo-api Deployment/todo-api 9%/50% 1 10 6 18h
todo-api Deployment/todo-api 5%/50% 1 10 6 18h
todo-api Deployment/todo-api 6%/50% 1 10 6 18h
todo-api Deployment/todo-api 6%/50% 1 10 6 18h
todo-api Deployment/todo-api 5%/50% 1 10 6 18h ## scale-down
todo-api Deployment/todo-api 11%/50% 1 10 3 18h
todo-api Deployment/todo-api 11%/50% 1 10 3 18h
todo-api Deployment/todo-api 5%/50% 1 10 3 18h
todo-api Deployment/todo-api 5%/50% 1 10 3 18h
todo-api Deployment/todo-api 5%/50% 1 10 3 18h
todo-api Deployment/todo-api 5%/50% 1 10 3 18h ## scale-down
todo-api Deployment/todo-api 7%/50% 1 10 1 18h
todo-api Deployment/todo-api 7%/50% 1 10 1 18h
- 첫 번째 scale-up이 일어났을 때 평균 CPU 사용률은 87%이며, 계산하면
ceil(87/50) = ceil(1.74)
이며 레플리카 수는 2가 된다. - 실제로 두 번째 scale-up이 일어나기 전에도 평균 CPU 사용율이 50%가 넘어가지만 behavior에 의해 1분동안 파드 스케일업이 진행되지 않는다.
- 두 번째 scale-up이 일어났을 때의 평균 CPU 사용율이 120%이고, 계산하면
ceil(2*120 / 50) = ceil(4.8)
으로 레플리카는 5가 되어 3개의 레플리카가 추가로 증설이 되어야 하지만 behavior에 의해 레플리카는 2개(2 * 1.0)
만 추가된다. 즉, 여기서 레플리카 갯수는 4이 된다. - 세 번째 scale-up이 일어났을 때의 평균 CPU 사용율이 66%이고, 계산하면
ceil(4*66 / 50) = ceil(5.28)
으로 레플리카는 6가 되어 2개의 레플리카가 추가로 증설이 되어야 한다. behavior에 의해 레플리카는 2개(4 * 1.0)
까지 추가되기 때문에 2개의 레플리카가 정상적으로 증설이 된다. - 부하테스트가 종료된 후 CPU 사용율이 현저히 줄어들어 스케일다운 조건을 만족하지만
stabilizationWindowSeconds
에 의해 약 1분동안 스케일다운 조건을 만족하는지 평가한다. - 1분동안 스케일 다운 조건이 만족하여 첫 번째 스케일다운 작업이 진행되며, 여기서 평균 CPU 사용율은 5%이고, 계산하면
ceil(6*5/50) = ceil(0.6)
이며 레플리카는 1이 되어야하지만 behavior에 의해 레플리카는 3개(6 * 0.5)
까지만 줄어들기 때문에 3개의 파드만 줄어든다. 여기서 레플리카 갯수는 3이 된다. - 두 번째 스케일다운 작업이 진행되며, 여기서 평균 CPU 사용율은 5%이고, 계산하면
ceil(6*5/50) = ceil(0.6)
이며 레플리카는 1이 되어야한다. behavior에 의해 레플리카는 1.5개(3 * 0.5)
까지만 줄어드는데 실제로 2개가 줄어들었기 때문에 퍼센트 기반은 ceil으로 평가되는 것 같다.
혼합
policies
는 배열타입이기 때문에 여러 정책을 넣을 수 있다. 다음과 같이 Pod, Percent 기반을 동시에 사용할 수도 있다.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: todo-api
namespace: todo
spec:
minReplicas: 1
maxReplicas: 10
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: todo-api
metrics:
- resource:
name: cpu
target:
averageUtilization: 50
type: Utilization
type: Resource
behavior:
scaleUp:
policies:
- type: Percent
value: 100
periodSeconds: 60
- type: Pods
value: 3
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 50
periodSeconds: 60
여기서 주목해야 할 점은 두 개 이상의 policies가 있다면, 기본적으로 두 개 모두 평가한 다음 둘 중 큰 것이 우선으로 작용한다. 예를 들어, 현재 레플리카가 5개 있고 평균 CPU 사용율이 90%라면 Percent 기반은 5개, 파드 갯수 기반은 3개이며 실제로 적용되는 것은 Percent 기반이고, 현재 레플리카가 1개 있고 평균 CPU 사용율이 90%라면 Percent 기반은 2개, 파드 갯수 기반은 3개이며 실제로 적용되는 것은 파드 갯수 기반이다.
작은 것이 우선이 될 수도 있는데. 이에 대한 설정은 behavior.scaleUp(scaleDown).selectPolicy
필드에서 설정할 수 있으며 Min
/ Max
둘 중 하나로 설정하면 된다. (default: Max
)
실제로 어떻게 적용되는지 확인하기 위해 마찬가지로 부하테스트를 진행한 결과는 다음과 같다.
$ while true; do; kubectl get hpa; sleep 10; done
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
todo-api Deployment/todo-api 6%/50% 1 10 1 18h ## 부하테스트 시작
todo-api Deployment/todo-api 6%/50% 1 10 1 18h
todo-api Deployment/todo-api 187%/50% 1 10 1 18h
todo-api Deployment/todo-api 187%/50% 1 10 1 18h ## scale-up
todo-api Deployment/todo-api 236%/50% 1 10 4 18h
todo-api Deployment/todo-api 218%/50% 1 10 4 18h
todo-api Deployment/todo-api 218%/50% 1 10 4 18h
todo-api Deployment/todo-api 85%/50% 1 10 4 18h
todo-api Deployment/todo-api 88%/50% 1 10 4 18h
todo-api Deployment/todo-api 88%/50% 1 10 4 18h ## scale-up
todo-api Deployment/todo-api 82%/50% 1 10 8 19h
todo-api Deployment/todo-api 54%/50% 1 10 8 19h
todo-api Deployment/todo-api 54%/50% 1 10 8 19h ## 부하테스트 종료
todo-api Deployment/todo-api 41%/50% 1 10 8 19h
todo-api Deployment/todo-api 33%/50% 1 10 8 19h
todo-api Deployment/todo-api 33%/50% 1 10 8 19h
todo-api Deployment/todo-api 11%/50% 1 10 8 19h
todo-api Deployment/todo-api 6%/50% 1 10 8 19h
todo-api Deployment/todo-api 6%/50% 1 10 8 19h ## scale-down
todo-api Deployment/todo-api 7%/50% 1 10 6 19h
todo-api Deployment/todo-api 6%/50% 1 10 6 19h
todo-api Deployment/todo-api 6%/50% 1 10 6 19h ## scale-down
todo-api Deployment/todo-api 6%/50% 1 10 4 19h
todo-api Deployment/todo-api 8%/50% 1 10 4 19h
todo-api Deployment/todo-api 8%/50% 1 10 4 19h ## scale-down
todo-api Deployment/todo-api 15%/50% 1 10 3 19h
todo-api Deployment/todo-api 8%/50% 1 10 3 19h
todo-api Deployment/todo-api 8%/50% 1 10 3 19h ## scale-down
todo-api Deployment/todo-api 6%/50% 1 10 2 19h
todo-api Deployment/todo-api 6%/50% 1 10 2 19h
todo-api Deployment/todo-api 6%/50% 1 10 2 19h ## scale-down
todo-api Deployment/todo-api 6%/50% 1 10 1 19h
- 첫 번째 scale-up이 일어났을 때 평균 CPU 사용률은 187%이며, 계산하면
ceil(187/50) = ceil(3.74)
이며 레플리카 수는 4가 된다. 그런데 behavior에 의해 실제로 늘어나는 레플리카가 조절되는데, Pods 기반은 3, Percent 기반은 2이기 때문에 여기서는 Pods 기반이 채택된다. 스케일업에 의해 레플리카 수는 4개가 된다. - 두 번째 scale-up이 일어났을 때 평균 CPU 사용률은 88%이며, 계산하면
ceil(4*88/50) = ceil(7.04)
이며 레플리카 수는 8이 된다. 그런데 behavior에 의해 실제로 늘어나는 레플리카가 조절되는데, Pods 기반은 3, Percent 기반은 4이기 때문에 여기서는 Percent 기반이 채택된다. 스케일업에 의해 레플리카 수는 8개가 된다. - 첫 번째 scale-down이 일어났을 때 평균 CPU 사용률은 6%이며, 계산하면
ceil(8*6/50) = ceil(0.96)
이며 레플리카 수는 1이 된다. 그런데 behavior에 의해 줄어드는 파드 갯수는 4개(8*0.5)
여야하는데 실제로는 2개가 줄어든다. (의문 1) - 두 번째 scale-down이 일어나는 시점은 첫 번째 scale-down이 일어나는 시점으로부터 30초 후이다. 그런데
stabilizationWindowSeconds
에 의해 1분이어야 하는데 30초가 된다. (의문 2)
scale-up / down 비활성화
HPA에 해당 필드를 추가함으로써 의도적으로 scale-up 및 down을 비활성화 시킬 수 있다.
behavior:
scaleDown:
selectPolicy: Disabled
기본 동작
HPA에 behavior를 설정하지 않는 경우에는 다음과 같이 기본동작이 적용된다고 한다.
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
마무리
이번 장에서는 HPA에서의 scale-up / down 시 세부 정책에 대해 알아보았다. 마지막 혼합 설정에서 scale-down 시 의도대로 되지 않는다는 점에서 약간의 의문점은 있지만 behavior를 통해 실제로 스케일업이나 다운이 발생할 때 세부적으로 제어할 수 있다는 점에서 오토스케일을 좀 더 전략적으로 잘 사용할 수 있을 것으로 보인다.
'DevOps > Kubernetes' 카테고리의 다른 글
Kubernetes HPA (파드 오토스케일링) [1] - 기초 (0) | 2025.01.05 |
---|---|
Kubernetes Scheduling - Node Affinity (0) | 2024.05.02 |
Kubernetes Scheduling 소개 및 NodeSelector (1) | 2024.05.01 |
[1] 쿠버네티스 확장 - kubectl plugin (0) | 2023.10.29 |
Helm Chart Repository 만들기 (2) - Harbor OCI registry (0) | 2023.10.12 |
댓글