먼저 HPA(HorizontalPodAutoscaler)는 아래와 같은 매니페스트 예시로 생성할 수 있다.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  ...
spec:
  minReplicas: 2
  maxReplicas: 4
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: sample-deployment
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        averageUtilization: 60
        type: Utilization
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 120
      policies:
      - periodSeconds: 15
        type: Pods
        value: 4
      - periodSeconds: 15
        type: Percent
        value: 100
      selectPolicy: Max
    scaleDown:
      stabilizationWindowSeconds: 600
      policies:
      - periodSeconds: 15
        type: Percent
        value: 50
      selectPolicy: Max

 

설정 항목 중에 metrics 와 behavior 에 대해 자세히 알아본다.

 

1. metrics

metrics 는 오토스케일링이 수행되는 임계치를 설정하는 항목이다. metrics[].resource.name 항목에는 cpu 또는 memory 가 올 수 있지만, 실제로 애플리케이션에서 memory 는 부하에 따라 증감하지 않고 상시 일정량을 점유하기 때문에 잘 쓰이지 않는다. metrics[].resource.target.averageUtilization 은 임계치가 될 파드 평균 cpu 사용률을 의미하는데, 그 기준은 파드의 spec.containers[].resources.requests.cpu 항목이 된다. 말이 좀 어려운데, 아래 표의 예시를 살펴보자

spec.containers[].resources.requests.cpu
(pod)
averageUtilization(HPA) cpu 사용률 기준 스케일링 동작
100m 70 100밀리코어를 100% 로 취급 scale out : 파드의 평균 CPU 사용률 70% 초과시
scale in: 파드의 평균 CPU 사용률 70% 미만시
500m 80 500밀리코어를 100%로 취급 scale out : 파드의 평균 CPU 사용률 80% 초과시
scale in: 파드의 평균 CPU 사용률 80% 미만시

 

이때, 스케일링 이후의 desired 한 파드 갯수는 아래 계산 공식을 따른다.

스케일링 이후 파드의 수 = ceil(현재 파드 수 * (파드 평균 cpu 사용률 / HPA cpu 임계치))

 

예를 들어 아래와 같은 상황이라고 하자

HPA cpu 임계치(averageUtilization) 현재 파드 수 파드 평균 cpu 사용률
50 4 70

파드 평균 cpu 사용률(70%)이 임계치(50%)를 초과했으므로 스케일 아웃이 일어날테고, 스케일링 후의 파드 갯수는 아래와 같다.

4 * (70/50) = 5.6

=> 올림처리하여 6

 

다음과 같은 상황에는 scale in 이 일어난다.

HPA cpu 임계치(averageUtilization) 현재 파드 수 파드 평균 cpu 사용률
50 4 20

4 * (20/50) = 1.6

=> 올림처리하여 2

 

물론, 스케일링 되더라도 minReplicas ~ maxReplicas 범위를 벗어날 수 없다.

 

2. behavior

behavior 은 스케일링의 상세 동작을 설정하는 항목이다. behavio 하위의 scaleUp 과 scaleDown 은 아래와 같은 항목이다.

항목 설명
scaleUp 스케일 아웃 동작 상세설정. 항목명이 scaleUp 임에 유의
scaleDown 스케일 인 동작 상세설정. 항목명이 scaleDown 임에 유의

 

scaleUp, scaleDown 각 하위로는 아래와 같은 항목을 지정할 수 있다.

항목 설명 예시
stabilizationWindowSeconds 스케일링을 위해 metrics 조건에 부합한 채 유지해야 하는 시간(초) averageUtilization: 60 / scaleUp.stabilizationWindowSeconds: 120
인 경우, 파드 평균 cpu 사용률이 120초간 60%를 초과해야 스케일 아웃 수행됨
policies[] periodSeconds 스케일링 갯수 제한 주기(초) periodSeconds: 15
type: Pods
value: 2
=> 15초마다 최대 2개의 파드를 스케일링할 수 있음
---
periodSeconds: 20
type: Percent
value: 100
=> 20초마다 최대 "현재 파드 갯수"의 100% 만큼의 파드를 스케일링 할 수 있음
type 제한 방식
- Pods: 파드 갯수 지정 제한
- Percent: 현재 파드 기준 % 제한
value 제한 값
selectPolicy polices 가 여러개일 때 선택 방식
- Max: 가장 큰 숫자를 선택
- Min: 가장 작은 숫자를 선택
scaleUp:
  policies:
    - periodSeconds: 15
      type: Pods
      value: 4
    - periodSeconds: 15
      type: Percent
      value: 100
  selectPolicy: Max
=> 현재 파드 갯수가 2개인 경우라면, 첫번째 정책을 선택(4개)
=> 현재 파드 갯수가 5개인 경우라면, 두번째 정책을 선택(5개)

 

위와 같이 정리할 수 있지만, selectPolicy 의 동작에 대해서 의문이 든다. periodSeconds 가 동일하면 쉽게 계산할 수 있지만, 다르다면 어떤 기준으로 선택할까?

이는 쿠버네티스의 제어 루프 주기가 도달하는 시점이 스케일링 갯수 계산 시점이라는 점을 생각해야 한다. 마스터 노드에는 kube-controller-manager 가 존재하는데, 이 안에 HPA 컨트롤러가 포함된다. HPA 컨트롤러가 주기적으로(기본 15초) cpu 상태와 스케일링 정책을 계산하여 스케일링을 수행한다. 이 계산 시점 기준으로 각 policies 의 의해 스케일링 가능한 갯수를 산출하고, selectPolicy 에 따라 최대 or 최소 갯수를 선택한다.

 

예를 들어, 제어 루프 주기가 도달하여 파드 스케일링 갯수 계산공식에 의해 2 -> 10개로 스케일 아웃 갯수가 정해졌다. selectPolicy: Max 이며, behavior.scaleUp.polices 정책은 2개가 있고, 아래와 같다.

  • 15초 정책: 이번 주기(15초)에 늘릴 수 있는 남은 갯수가 4개
  • 60초 정책: 이번 주기(60초)에 늘릴 수 있는 남은 갯수가 10개

60초 정책이 더 많은 갯수(10개)를 늘릴 수 있으므로 선택된다.

 

3. HPA 동작 매커니즘

HPA 를 사용하다보면 stabilizationWindowSeconds 가 동일하더라도 cpu 사용률이 임계치를 넘어가는 시점과 실제 스케일링이 일어나는 시점의 차이가 매번 다르다고 느끼게 된다. 이는 HPA 의 동작 매커니즘에 따른 현상인데, 결론만 말하자면 여러 컴포넌트나 오브젝트가 각각 자원 사용량이나 임계값을 확인하는 주기와 관계가 있다. 아래는 그 모식도이다.

주체 대상 가져오는 정보 주기(초)
kubelet container runtime cpu/memory 사용량 10
metrics-server kubelet cpu/memory 사용량 60
kube-controller-manager metrics-server cpu/memory 사용량 15
HPA 스케일링 임계값

 

이에 따라서 운이 좋으면 실제 cpu 사용량이 임계값을 넘는 순간 바로 스케일링이 시작되겠지만, 운이 안좋으면 최대 85초 후 시작된다.

블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,