Featured image of post 리소스관리와 오토스케일링

리소스관리와 오토스케일링

리소스관리와 오토스케일링

리소스 관리와 오토 스케일링

리소스 제한

CPU/메모리 리소스 제한

  • CPU는 클럭 수가 아닌 1vCPU를 1,000m 단위로 지정
  • 단위
리소스 유형 단위
CPU 1 = 1000m = 1 vCPU
메모리 1G = 1000M (1Gi = 1024Mi)
  • Requests: 사용하는 리소스 최솟값
    • 지정한 양의 리소스가 노드에 존재하지 않으면 스케줄링 되지 않음
  • Limits: 사용할 리소스의 최댓값
    • 노드에 Limits로 지정한 리소스가 없어도 스케줄링 됨
  • Requests만 설정한 경우 Limits는 자동 설정되지 않고 부하가 최대로 상승할 때까지 리소스 계속 소비
    • 파드가 많이 가동하는 노드에서 리소스 뻇기 발생, OOM 발생
  • Limits만 설정한 경우 은 값이 Requests에 설정

시스템에 할당된 리소스와 Eviction 매니저

  • 일반 리소스는 고갈 시 쿠버네티스 자체가 동작하지 않거나 그 노드 전체에 영향 가능성
  • 각 노드에는 kube-reserved, system-reserved 두 가지 리소스가 시스템용으로 확보
  • 실제 파드 할당 가능 리소스는 리소스 총량 - (kube-reserved, system-reserved)
  • Eviction 매니저가 시스템 전체가 과부하되지 않도록 관리
    • Allocatable, system-reserved, kube-reserved 실제 사용되는 리소스 합계가 Eviction Threshold 넘지 않는지 정기적으로 확인, 초과한 경우 파드 Evict
  • Eviction Threshold는 soft, hard 두 가지 존재
    • soft: SIGTERM 신호를 보내 지정한 시간 후 파드 정지
    • hard: SIGKILL 신호를 보내 바로 파드 정지
  • Evict 우선 순위
    1. Requests에 할당된 양보다 초과하여 리소스를 소비하고 있는 것
    2. PodPriority가 낮은 것
    3. Requests에 할당된 양보다 초과하여 소비하고 있는 리소스 양이 더 많은 것

GPU 등의 리소스 제한

엔비디아 GPU
1
2
3
4
5
resources:
  requests:
    nvidia.com/gpu: 2
  limits:
    nvidia.com/gpu: 2

오버커밋과 리소스 부족

  • 스케일 아웃을 해도 리소스가 없으면 추가되는 파드 중 리소스를 할당할 수 없는 파드는 Pending 상태가 됨
  • 생성된 파드에 부하가 증가시 리소스 사용량이 100%를 초과하더라도 오버커밋하여 실행

Cluster Autoscaler와 리소스 부족

  • Cluster Autoscaler는 수요에 따라 노드를 자동으로 추가하는 기능
  • pending 상태의 파드 발생시 처음으로 Cluster Autoscaler 동작
  • 기본적으로 리소스에 의한 스케줄링은 Requests(최소) 기준으로 동작
    • Requests와 Limits에 너무 큰 차이를 주지 않을 것
    • Requests를 너무 크게 설정하지 않을 것
  • 실제 값을 정할 때 Requests, Limits를 낮게 설정하고 성능 테스트를 통해 올려가는 것이 좋음
    • 메모리의 경우 OOM이 발생하지 않을 정도의 리소스 할당

LimitRange를 사용한 리소스 제한

  • 파드, 컨테이너, 영구볼륨 대해 리소스의 최솟값과 최댓값, 기본값 등을 설정 가능
  • 신규 파드가 생성될 때 사용, 기존 파드에는 영향 X
  • 설정 가능 항목
설정 항목 개요
default 기본 Limits
defaultRequest 기본 Requests
max 최대 리소스
min 최소 리소스
maxLimitRequestRatio Limits/Requests의 비율
  • LimitRange를 설정할 수 있는 리소스와 설정 항목
타입 사용 가능한 설정 항목
컨테이너 default/defaultRequest/max/min/maxLimitRequetsRatio
파드 max/min/maxLimitRequestRatio
PVC max/min

컨테이너에 대한 LimitRange

  • type: Container의 LimitRange로 설정

파드에 대한 LimitRange

  • type: Pod의 LimitRange로 설정
  • 컨테이너에서 사용하는 리소스 합계로 최대/최소 리소스 제한

PVC에 대한 LimitRange

  • type: PersistentVolumeClaim의 LimitRange로 설정
  • 일정 용량 이상으로 볼륨을 생성하지 못하게 할 수 있음

QoS Class

  • 사용자가 직접 설정하지 않고 파드의 Requests/Limits 설정에 따라 자동으로 설정
Qos Class 조건 우선순위
BestEffort Requests/Limits 모두 미지정 3
Guaranteed Requests/Limits 같고 CPU, 메모리 모두 지정 1
Burstable Guranteed 충족하지 못하고 한 개 이상의 Requests/Limits 설정 2
  • 쿠버네티스가 컨테이너에 oom score 설정할 때 사용
    • oom score: -1000(최고 순위) ~ 1000(최저 순위)
  • Guaranteed의 경우 쿠버네티스 시스템 구성 요소(oom score=-999) 외에 우선순위가 높은 컨테이너가 없어 좀 더 안정적 실행 가능
QoS Class 조건
BestEffort 1000
Guaranteed -998
Burstable min(max(2, 1000 - (1000 * 메모리의 Requests) / 머신 메모리 용량), 999)
1
2
## 파드 목록과 QoS Class 표시
$ kubectl get pods -o custom-columns="NAME:{.metadata.name},QOS Class:{.status.qosClass}"

BestEffort

  • 리소스 제한이 전혀 없음
  • LimitRange가 설정된 환경에서는 지정되지 않은 경우에도 자동으로 리소스 제한이 설정되므로 되지 않음

Guaranteed

  • 최소한으로 사용하는 리소스와 최대한으로 사용하는 리소스에 차이가 없는 상태
  • 모든 파드를 Guaranteed로 한다면, 부하 증가에 따른 다른 파드로의 영향을 피할 수 있지만, 집약률 낮아짐

Burstable

  • 특정 리소스만 제한 설정
  • Requests보다 Limits가 큰 경우
  • 최악의 경우 노드가 과부하를 받을 가능성

리소스 쿼터를 사용한 네임스페이스 리소스 쿼터 제한

  • 각 네임스페이스마다 사용 가능한 리소스를 제한
  • 이미 생성된 리소스에는 영향 X
  • 생성 가능한 리소스 수 제한과 리소스 사용량 제한으로 나눌 수 있음
  • 리소스 쿼터가 설정된 경우 제한된 항목 설정은 필수

생성 가능한 리소스 수 제한

  • count/RESOURCE.GROUP 구문을 사용

리소스 사용량 제한

  • CPU/메모리에 대해 컨테이너에 할당 가능한 리소스 양 제한
  • 스토리지는 Limits는 존재하지 않고 Requests만 지정 가능
  • 스토리지클래스마다 제한을 둘 수 있음(SSD, HDD, …)

HorizontalPodAutoscaler

  • 디플로이먼트/레플리카셋/레플리케이션 컨트롤러의 레플리카 수를 CPU 부하 등에 따라 자동으로 스케일링하는 리소스
  • 부하가 높아지면 스케일 아웃, 낮아지면 스케일 인
  • 파드에 Resource Requests가 설정되어 있지 않은 경우 동작하지 않음
  • 30초에 한번씩 오토 스케일링 여부 확인
    • 필요한 레플리카 수 = ceil(sum(파드의 현재 CPU 사용률) / targetAverageUtilization)
    • CPU 사용률은 metrics-server에서 가져온 각 파드의 1분간 평균값 사용
  • 최대 3분에 1회 스케일 아웃, 최대 5분에 1회 스케일 인 실행
    • 스케일 아웃 조건 식: avg(파드의 현재 CPU 사용률) / targetAverageUtilization > 1.1
    • 스케일 인 조건 식: avg(파드의 현재 CPU 사용률) / targetAverageUtilization < 0.9
1
2
## CLI로 HPA 생성
$ kubectl autoscale deployment sample-deployment --cpu-percent=50 --min=1 --max=10
  • CPU 이외의 리소스를 사용하여 오토 스케일링 하는 경우 프로메테우스나 그 외의 메트릭 서버와 연계하기 위한 설정 별도 필요

VerticalPodAutoscaler

  • 파드에 할당하는 CPU/메모리의 Requests는 실제 성능을 측정하려면 서비스 환경에 배포해야 하므로 조절이 어려움
  • VPA는 컨테이너에 할당하는 리소스를 자동으로 스케일해주는 기능
  • 스케일 아웃이 아닌 스케일 업
  • 대상이 되는 워크로드 리소스, 파드 내부 컨테이너 제한, 업데이트 정책 세 부분으로 구성
  • Requests를 변경하려면 파드 재기동 필요 - 성능에 악영향 가능성
  • 추천값 계산만 하고 참고로만 확인할 수 있는 옵션도 존재
  • 쿠버네티스의 핵심 기능이 아니기 때문에 별도 구성 요소 설치해야 함
updateMode 내용
Off Requests의 추천값을 계산만 하고 실제 변경은 없음
Initial 파드가 재생성된 시점에만 추천값을 Requests로 변경
Recreate 추천값이 변경될 때 파드가 재생성되고 Requests를 변경
Inplace(미구현) 추천값이 변경될 때 파드를 기동한 상태로 Requests 변경
Auto 추천값이 변경될 때 Inplace 또는 Recreate로 Requests 변경
1
2
## vpa 상태 확인
$ kubectl describe vpa sample-vpa
모드 내용
Lower Bound Requests의 최소 추천값, 밑도는 경우 성능에 큰 영향
Upper Bound Requests의 최대 추천값, 웃도는 경우 낭비
Target Requests의 추천값, 가장 효율적
Uncapped Target 리소스 제약을 고려하지 않은 Requests 추천 값
  • Requests 변경으로 파드 재작성이 빈번하게 실행되는 것을 막기 위해 Target이 변경된 후 Requests를 Lower Bound보다 작거나 Upper Bound 보다 크게 설정하면 파드 변경됨
  • PodDisruptionBudget을 고려해 점차적으로 파드 변경
    • 설정되지 않은 경우 절반씩 변경
Hugo로 만듦
JimmyStack 테마 사용 중