본문 바로가기
IT/Kubernetes

K8S Horizontal Pod Autoscaler (HPA)

by rapker 2023. 4. 17.
반응형
참고
 
 
K8S Autoscale 리서치 에 이어지는 내용입니다.
 

728x90
 
 
HPA (Horizontal Pod Autoscaler)
 
목표한 지표(cpu, memory 등)가 임계치에 도달 했을 때 동일한 pod를 여러개 늘리거나 줄여주는 기능을 합니다.
 
음... HPA에 대해 주절주절 기록을 남겼다가
정리차 몇 번 읽어보니까
'HPA는 무엇을 기준으로 pod의 수량을 조절해 준다' 내용 외 '어떻게 사용하는지'에 대한 정보 말고 따로 기록하는게 의미가 있나? 싶어서 
눈물을 머금고 삭제 했습니다. ㅠㅠ
 
HPA에 필요한 데이터는 System Metrics 정보 만으로 충분 하니까 모니터링에 대한 정보는 다음 기회에 찾아보기로 하고
HPA를 어떻게 사용하는지 구조를 확인해봅니다.
 
 
HPA 예시 (autoscaling/v1)
 
현재는 autoscaling/v2가 있어서 /v2가 주로 사용되겠지만 차이점을 알아보고자
autoscaling/v1에서 사용되던 예시를 잠깐 보고 지나 갑니다.
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: myweb-hpa
spec:
  minReplicas: 1
  maxReplicas: 10
  targetCPUUtilizationPercentage: 50
  scaleTargetRef:
    kind: Deployment
    name: myweb-dep
 
대상 pod
  • Deployment로 배포된 myweb-dep
scaleTargetRef:
    kind: Deployment
    name: myweb-dep
 
scale 범위
  • 최소 1개 최대 10개의 pod
minReplicas: 1
maxReplicas: 10
 
대상 지표
  • cpu percentage가 50가 되면 확장
targetCPUUtilizationPercentage: 50
 
저는 autoscale/v2를 먼저 접하고 나서  autoscaling/v1을 찾아본 케이스 인데요 /v2에 비해 /v1은 심플하네요
 
 
 
 
HPA 예시 (autoscaling/v2)
 
autoscaling/v2에서는 pod의 확장/축소에 대한 정책을 세부적으로 정의할 수 있습니다.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myweb-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myweb-pod
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50          # <-- 1차 끝
  behavior:                              # <-- 2차 시작
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
      - type: Percent
        value: 50
        periodSeconds: 15
      - type: Pods
        value: 4
        periodSeconds: 15
      selectPolicy: Max
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 10
        periodSeconds: 300
      - type: Pods
        value: 1
        periodSeconds: 120
      selectPolicy: Min
   
 
뭔가 갑자기 길어져서 복잡해 보이는 느낌이네요...  ㅡ.,ㅡ
 
autoscaling/v2로 올라오면서 해당 pod의 수를 늘리거나 줄이는 정책을 세부적으로 컨트롤할 수 있게 되었습니다.
 
autoscaling/v2는 매니패스트는 기니까 behavior를 기준 삼아 1차, 2차로 나누어 살펴보겠습니다.
 
 
1차
 
대상 pod
  • Deployment로 배포된 myweb-pod pod에 적용하는 HPA manifest이구요
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myweb-pod
 
scale 범위
  • pod의 확장 범위는 최소 1개에서 10개 입니다.
  minReplicas: 1
  maxReplicas: 10
 
대상 지표
  • Syatem Metrics(기본지표)인 cpu 사용량이 50%를 넘어가면 pod를 확장한다.
metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
 
metrics.type
  • Resource : cpu, memory 같은 기본 지표(System Metrics)
  • Pod : pod의 metrics이고, http 요청 횟수 등
  • Object : pod와 직접적인 관련 없는 지표로, ingress의 hit 및 latency등
  • External : k8s 외부 metrics
Object와 External data를 얻기 위해서는 Prometheus와 같은 외부 툴이 필요합니다.
 
metrics.resource.target.type
  • Value : 목표 수치에 도달 시
  • Utilization : 목표 퍼센테이지에 도달 시
  • AverageValue : 평균 수치에 도달 시
  • AverageUtilization : 평균 퍼센테이지에 도달 시
위 target.type들이 모든 metrics.type에 사용할 수 것은 아닙니다.
 
Value
Utilization
AverageValue
AverageUtilization
Resource
O
O
O
O
Pod
X
X
O
X
Object
O
X
O
X
External
O
X
O
X
 
 
그 외 그냥 한번쯤 읽고 넘어갈 만한 부분
 
metrics.resource.target 부분은 autoscaling/v1에서 targetCPUUtilizationPercentage 와 동일하게 동작한다고 합니다.
 
Metrics API
- 리소스 메트릭 : metrics.k8s.io
- 사용자 정의 메트릭 : custom.metrics.k8s.io
- 외부 메트릭 : external.metrics.k8s.io
 
 
 
2차
 
자 이제 autoscaling/v2에 핵심인 behavior부분을 살펴 봅니다.
 
behavior.scaleUp, behavior.scaleDown을 통해 pod가 확장되는 조건과 축소되는 정책을 정의할 수 있게 되었습니다.
(autoscaling/v2Beta2 부터 가능해졌습니다.)
 
scaleUp과 scaleDown은 작성방법이 동일하므로 scaleUp위주로 살펴보겠습니다.
behavior:
  scaleUp:
    stabilizationWindowSeconds: 0
      policies:
      - type: Percent
        value: 50
        periodSeconds: 15
      - type: Pods
        value: 4
        periodSeconds: 15
      selectPolicy: Max
 
 
유예 시간
  • 1차에서 정의한 지표가 얼만큼 유지되어야 확장을 진행 할 것인가에 대한 것으로
scaleUp:
    stabilizationWindowSeconds: 0
k8s 공식문서나 번역된 문서들에는 안정화윈도우 라고 표시 되어 있는데
지표가 목표치에 도달했을 때 얼마간의 유예시간 유지 후 확장하는 개념이라서 저는 유예시간이라고 부르겠습니다.
 
위 샘플에서는 stabilizationWindowSeconds값이 0으로 설정되어 있어서  cpu가 50% 초과 하자 마자 scaleUP을 진행하게 됩니다.
 
stabilizationWindowSeconds는 0에서 3600(1시간)까지 설정할 수 있습니다.
 
확장 정책
  • 얼만큼씩 확장을 할 것인가에 대한 정책입니다.
policies:
  - type: Percent
    value: 50
    periodSeconds: 15
  - type: Pods
    value: 4
    periodSeconds: 15
 
두 개의 확장 정책이 작성되어 있습니다.
  • 15초 간격으로 현재 배포된 pod의 50% 만큼 pod 확장
  • 15초 간격으로 4개의 pod 확장
 
periodSeconds는 0에서 1800(30분)까지 설정할 수 있습니다.
 
 
정책 선택
  • 정책이 여러 개 이면 어떤 정책으로 확장이 진행될까요?
selectPolicy: Max
두 개의 정책으로 계산된 pod의 수 중 큰 값을 적용하겠다고 정의되어 있습니다.
 
scaleDown은 안보려고 했는데 짧게 훑고 가겠습니다.
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 10
        periodSeconds: 300
      - type: Pods
        value: 1
        periodSeconds: 120 
      selectPolicy: Min
대상 지표의 목표한 수치 미만으로 300초 동안 유지되면 아래 둘 중 작은 값으로 축소
  • 현재 pod의 10%의 만큼 (300초 마다)
  • 무조건 1개 (120초 마다)
 
 
metrics.resource.target.type 별 매트릭 사용 예
 
개별 매트릭
혼합 매트릭
Resource
metrics:
- type: Resource
  resource:
    name: cpu
    target:
      type: Utilization
      averageUtilization: 50
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
  - type: Pods
    pods:
      metric:
        name: packets-per-second
      target:
        type: AverageValue
        averageValue: 1k
  - type: Object
    object:
      metric:
        name: requests-per-second
      describedObject:
        apiVersion: networking.k8s.io/v1
        kind: Ingress
        name: main-route
      target:
        type: Value
        value: 10k
status:
  observedGeneration: 1
  lastScaleTime: <some-time>
  currentReplicas: 1
  desiredReplicas: 1
  currentMetrics:
  - type: Resource
    resource:
      name: cpu
    current:
      averageUtilization: 0
      averageValue: 0
  - type: Object
    object:
      metric:
        name: requests-per-second
      describedObject:
        apiVersion: networking.k8s.io/v1
        kind: Ingress
        name: main-route
      current:
        value: 10k
Pod
metrics:
- type: Pods
  pods:
    metric:
      name: packets-per-second
    target:
      type: AverageValue
      averageValue: 1k
Object
metrics:
- type: Object
  object:
    metric:
      name: requests-per-second
    describedObject:
      apiVersion: networking.k8s.io/v1
      kind: Ingress
      name: main-route
    target:
      type: Value
      value: 2k
External
metrics:
- type: External
  external:
    metric:
      name: queue_messages_ready
      selector:
        matchLabels:
          queue: "worker_tasks"
    target:
      type: AverageValue
      averageValue: 30
 
 
위 혼합 매트릭 예시처럼 여러 개의 metrics 블록이 정의되어 있으면 각 매트릭을 차례로 고려한다.
(정의된 순서대로 비교를 한다는 뜻인거 같은데 정확하게 명시되어 있지는 않네요.)
 
목표에 도달한 매트릭(지표)이 있는경우
HPA는 각 매트릭에 대해 제안 된 레플리카 수를 계산하고, 그중 가장 높은 레플리카 수를 선정합니다.
 
metrics 조건을 확인할 때 어느정도 간격으로 체크를 하는지 확인하고 싶은데
어디 꼭꼭 숨겨 놨는지 확인할 수가 없네요
예전 어디선가 본 것만 같은 기억으로는 1분간격으로 체크 한다고 본거 같긴한데.... 찾을수가 없네요 ㅠ
 
반응형
LIST

'IT > Kubernetes' 카테고리의 다른 글

Helm으로 2 tier webapp 배포  (0) 2023.04.17
Helm에 대해 알아보자  (1) 2023.04.17
K8S Autoscale 리서치  (0) 2023.04.17
K8S resources.requests 필요한가?  (1) 2023.04.17
Loki 설치  (0) 2023.04.13