Kubernetes request, limit

김건호·2023년 7월 19일
1

개요

업무 중, 다음과 같은 질문을 받았습니다..

"현재 파드의 자원할당 설정 내용을 보면 리미트값과 리퀘스트 값이 존재하는데 8이라는 cpu값을 주고 싶고, 7이라는 cpu 값에 도달했을 때 파드의 재기동을 자동으로 유발시키려면 설정을 아래와 같이 하면 될까요?"

containers:
    - resources:
        limits:
          cpu: '7'
          memory: 64Gi
        requests:
          cpu: '8'
          memory: 64Gi

질문에서 시작된 requests, limits에 대해 알아보기..❗


resources 필드

아래는 explain으로 확인한 resources 필드입니다. 컨테이너에서 필요한 리소스를 정의하는 필드로 하위 필드로는 limits, requests가 있습니다. 지정할 수 있는 리소스는 CPU, Memory가 일반적이며 다른 리소스(hugepages-*)들도 있습니다.

# kubectl explain pod.spec.containers.resources
KIND:     Pod
VERSION:  v1

RESOURCE: resources <Object>

DESCRIPTION:
     Compute Resources required by this container. Cannot be updated. More info:
     https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

     ResourceRequirements describes the compute resource requirements.

FIELDS:
   limits       <map[string]string>
     Limits describes the maximum amount of compute resources allowed. More
     info:
     https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

   requests     <map[string]string>
     Requests describes the minimum amount of compute resources required. If
     Requests is omitted for a container, it defaults to Limits if that is
     explicitly specified, otherwise to an implementation-defined value. More
     info:
     https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

리소스 단위

CPU

CPU 단위는 코어로 정의 됩니다.
예시
1 = 1코어
0.5 = 0.5코어
500m = 0.5코어

쿠버네티스에서 CPU 리소스를 1m보다 더 정밀한 단위로 표기할 수 없습니다. 때문에, 0.005 보다는 5m으로 표기하는 것이 좋습니다.

Memeory

Memory 단위는 바이트로 정의 됩니다.
예시
4000000000= 4기가바이트

E, P, T, G, M, k 와 같은 수량 접미사 중 하나를 사용하여 메모리를 일반 정수 또는 고정 소수점 숫자로 표현할 수 있습니다.
129M = 129메가바이트

Ei, Pi, Ti, Gi, Mi, Ki와 같은 2의 거듭제곱을 사용할 수도 있습니다.
123Mi

대소문자에 주의하도록 합니다.
400메가바이트혹은 400메비바이트를 원할 경우
400m 400m은 0.4바이트입니다.
400M or 400Mi

limits

컨테이너는 limit보다 더 많은 리소스를 사용할 수 없습니다.
컨테이너에 limit를 설정한다면 kubelet, 컨테이너 런타임이 limit를 초과하여 사용하지 못하게 합니다.

CPU가 limits 초과하려 사용하려는 경우

CPU limit은 해당 컨테이너가 사용할 수 있는 CPU 시간에 대한 hard ceiling을 정의합니다. 각 스케줄링 간격(시간 조각)마다, 리눅스 커널은 이 제한이 초과되었는지를 확인하고, 만약 초과되었다면 cgroup의 실행 재개를 허가하지 않고 기다립니다.
--> 컨테이너가 비교적 긴 시간 동안 CPU 제한을 초과하는 것이 허용될 수도, 허용되지 않을 수도 있습니다. 하지만, 컨테이너 런타임은 과도한 CPU 사용률을 이유로 파드 또는 컨테이너를 종료시키지는 않습니다.

Memory가 limits 초과하려 사용하려는 경우

Memory가 limits 초과하려 사용하려는 경우 시스템 커널은 메모리 부족(out of memory, OOM) 오류와 함께 할당을 시도한 프로세스를 종료합니다. 해당 프로세스의 PID가 1이고, 컨테이너가 재시작 가능(restartable)으로 표시되어 있으면, 쿠버네티스가 해당 컨테이너를 재시작합니다.

requests

컨테이너는 requests만큼의 리소스를 할당 받을 수 있습니다. 이는 최소한 이 만큼의 양은 컨테이너가 사용할 수 있다는 것을 의미합니다.

CPU Requests

CPU Requests는 일반적으로 가중치 설정(weighting)을 정의합니다. 현재 부하율이 높은 시스템에서 여러 개의 컨테이너(cgroup)가 실행되어야 하는 경우, 큰 CPU 요청값을 갖는 워크로드가 작은 CPU 요청값을 갖는 워크로드보다 더 많은 CPU 시간을 할당받습니다.

Memeory Requests

메모리 Requests는 주로 (쿠버네티스) 파드 스케줄링 과정에서 사용됩니다. cgroup v2를 사용하는 노드에서, 컨테이너 런타임은 메모리 요청을 힌트로 사용하여 memory.min 및 memory.low을 설정할 수 있습니다.

requests, limits 주의점

CPU 설정되어 있지 않거나 너무 낮게 설정된 경우

CPU 자원을 많이 사용하게 되는 경우, 각 어플리케이션들은 초기에 요청한 자원만큼만 사용할 수 있어 CPU throttle이 발생하게 되고 어플리케이션 지연이 발생하게 됩니다.

너무 낮은 Memory limit 설정

CPU limit에 도달하는 경우에 CPU throttling이 발생하지만 메모리 limit에 도달하는 경우 Pod가 죽게 됩니다
-->OOMKill

OOMKill 발생 빈도를 줄이고 싶다면 메모리를 초과할당하지 말고 Guaranteed QoS(Quality of Service)로 설정하기 ( limit과 requests를 동일하게 설정)

  resources:
      requests:
        memory: "128Mi"
        cpu: 2
      limits:
        memory: "128Mi"
        cpu: 2

VerticalPodAutoscaler

자동으로 Pod의 리소스 사용량을 확장 시켜주는 GCP의 서비스.
CPU/메모리 사용량을 지켜보고 있다가 새롭게 리소스 제약을 설정해 줍니다.

결론

개요에서의 질문에 대한 답변

"현재 파드의 자원할당 설정 내용을 보면 리미트값과 리퀘스트 값이 존재하는데 8이라는 cpu값을 주고 싶고, 7이라는 cpu 값에 도달했을 때 파드의 재기동을 자동으로 유발시키려면 설정을 아래와 같이 하면 될까요?"

containers:
    - resources:
        limits:
          cpu: '7'
          memory: 64Gi
        requests:
          cpu: '8'
          memory: 64Gi

에 대한 답변은

쿠버네티스 파드내의 컨테이너에서의 request와 limit에 대한 정의는 다음과 같습니다.

  • 컨테이너는 request 정의된 리소스보다 더 많은 리소스 사용 가능.
  • 컨테이너는 limit 보다 더 많은 리소스를 사용할 수 없음.

따라서 request에 limit보다 많은 리소스를 정의할 수 없습니다.

CPU Limit는 해당 컨테이너가 사용할 수 있는 CPU 시간에 대한 hard ceiling을 정의합니다. 각 스케줄링 간격(시간 조각)마다, 리눅스 커널은 이 제한이 초과되었는지를 확인하고, 만약 초과되었다면 cgroup의 실행 재개를 허가하지 않고 기다립니다.

따라서 컨테이너 런타임은 과도한 CPU 사용률을 이유로 파드 또는 컨테이너를 종료시키지는 않습니다.

위 내용을 바탕으로 limit, request의 값으로 파드의 재기동을 자동으로 유발시키는 설정은 어려울 것으로 확인됩니다.

라는 답변을 드렸다..❗

참고 문서

Resource Management for Pods and Containers
[번역] 쿠버네티스에서 쉽게 저지르는 10가지 실수 by 커피고래
10 most common mistakes using kubernetes for "requests, limits 주의점"

profile
Ken, 🔽🔽 거노밥 유튜브(house icon) 🔽🔽

1개의 댓글

comment-user-thumbnail
2023년 7월 19일

좋은 글 잘 읽었습니다, 감사합니다.

답글 달기