쿠버네티스의 리소스 관리

Chanmin, Kim·2022년 4월 21일
0

Kubernetes

목록 보기
1/3


한번 500MB의 메모리를 갖고 있는 워커 노드 A가 있다고 가정해 보겠습니다.

그런데 어떤 파드가 실행되어 스케줄러가 이를 배치하려 할 때, 만약 파드가 사용할 메모리가 1GB를 넘어선다면 이 파드는 노드 A에 배치될 수 있을까요?

스케줄러가 파드를 효과적으로 배치하려면 각 파드가 최소 / 최대로 사용하고자 하는 자원이 어느 정도인지를 알고 있어야 할 텐데요, 쿠버네티스는 여러 종류의 자원 중 CPU와 메모리를 관리할 수 있습니다.

✅ 다만 CPU와 메모리 사용량 외에 디스크 I/O 작업(IOPS)이나 네트워크 대역폭 등의 정보는 알지 못합니다.

이번 글에서는 컨테이너에서 사용할 CPU 및 메모리를 관리하는 방법인 리소스 요청 / 제한에 대해 소개해보도록 하겠습니다.

리소스 요청 및 제한

쿠버네티스의 리소스 요청(Resource request)는 파드를 실행하기 위한 최소한의 자원을 요청하는 것을 의미합니다.

예를 들어 100 밀리CPU와 250MB의 메모리를 요청한다는 것은 요청된 리소스보다 적은 리소스를 보유한 노드에는 파드를 배치할 수 없는 데요, 만약 자원이 부족해 배치할 수 있는 노드가 없는 상황이라면 파드는 실행되지 않고 pending 상태를 유지하게 됩니다.

CPU와 메모리의 단위

리소스를 요청 / 제한하기 전, 리소스의 단위에 대해 짚고 넘어가도록 하겠습니다.


  • CPU 리소스
    • CPU의 경우 1개 CPU가 단위가 되며, 언제나 절대량을 표시합니다.
      (Ex. 클러스터가 쿼드코어 CPU라고 해도, 0.5를 명시한다면 코어 2개가 아닌 0.5코어를 의미한다.)
    •  m은 밀리를 의미하며, "1000m" 이 1코어를 의미합니다.
  • 메모리 리소스
    • 메모리 리소스의 경우 1바이트가 단위가 되며, 대소문자를 구분합니다.
      (Ex. 400m → 0.4바이트 / 400M → 400 메가바이트)

리소스 요청 및 제한 설정 적용하기

리소스 요청이 파드 실행을 위해 필요한 최소한의 자원을 명시했다면, 리소스 제한은 파드가 최대로 사용할 수 있는 자원을 의미합니다.

이 때 CPU와 메모리의 리소스 제한 동작이 약간 다른데요, 만약 파드가 배정된 CPU 이상을 사용하려 한다면 쓰로틀링에 걸리게 되며 성능이 저하되게 됩니다.

그에 비해, 파드가 배정된 메모리 이상을 사용하려 한다면 해당 파드는 메모리 부족(out of memory, OOM) 오류와 함께 즉시 종료되고 재실행됩니다.

이제 리소스 요청 정보를 디플로이먼트에 추가해, 컨테이너가 사용할 최소 자원을 명시해 보겠습니다.

TIP - 쿠버네티스가 파드를 적절히 관리 및 스케줄하기 위해, 항상 컨테이너가 사용할 리소스 요청량과 제한을 명시하는 것이 권장됩니다.

디플로이먼트에 리소스 요청 속성을 추가한 예시

spec:
  containers:
    - name: myHello
      image: spacesangsoo/myHello
      ports:
      - containerPort: 8888
      
      # 컨테이너를 실행하기 위해 필요한 최소 자원을 명시합니다.
      resources:
        requests:
          memory: "10Mi"
          cpu: "100m" # 100 밀리코어 (= 0.1 CPU 코어)를 의미합니다.

디플로이먼트에 리소스 제한 속성을 추가한 예시

spec:
  containers:
    - name: myHello
      image: spacesangsoo/myHello
      ports:
      - containerPort: 8888
      resources:
        # 파드가 사용할 수 있는 최대 리소스 제한을 설정합니다.
        limits:
          memory: "20Mi"
          cpu: "250m"
  • 만약 리소스 제한을 명시하고 리소스 요청량을 명시하지 않는다면, 쿠버네티스는 자동으로 리소스 제한에 명시된 만큼의 자원을 컨테이너에 할당합니다.

QoS(Quality of Service) 클래스

이렇게 파드가 사용할 자원을 명시함으로써 쿠버네티스는 보다 지능적인 스케줄링을 수행할 수 있는데요, 지정된 리소스 요청과 제한값에 따라 파드를 3종류로 구분합니다.

  • Guaranteed (1순위 우선순위)
  • Burstable (2순위 우선순위)
  • BestEffort (3순위 우선순위)

Guaranteed 클래스

Guranteed 클래스는 스케줄링 시 가장 중요한 파드 로 구분되는 유형으로, 중요한 작업을 수행하는 파드에 적합합니다.

Guaranteed 클래스의 파드는 리소스 제한량을 초과하지 않는 이상 제거되지 않습니다.

다음의 조건을 모두 만족하면 Guaranteed 클래스가 부여됩니다.

  • 파드 내 모든 컨테이너가 메모리 요청과 제한을 지정했으면서, 메모리 요청값과 제한값이 동일한 경우

  • 파드 내 모든 컨테이너가 CPU 요청과 제한을 지정했으면서, CPU 요청값과 제한값이 동일한 경우

Guaranteed 클래스를 부여받는 파드 예시

주어진 조건대로 리소스 요청과 제한이 모두 명시되어 있고, 요청값과 제한값이 동일한 파드를 생성해 보겠습니다.

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo
  namespace: qos-example
spec:
  containers:
    - name: qos-demo-ctr
      image: nginx
      resources:
        limits:
          memory: "200Mi"
          cpu: "700m"
        requests:
          memory: "200Mi"
          cpu: "700m"

이후 kubectl get pod qos-demo --namespace=qos-example --output=yaml 커맨드로 실행중인 파드 정보를 조회해보면 qosClass 가 Guaranteed 인 것을 확인할 수 있습니다.

출력된 파드 정보

apiVersion: v1
kind: Pod
  ...
  qosClass: Guaranteed
  startTime: "2022-04-24T02:49:00Z"

Burstable 클래스

Burstable 클래스는 Guaranteed 클래스보다는 우선순위가 낮으며, 노드 내 가용 리소스의 최대치 또는 리소스 제한값에 명시한 만큼의 자원을 부여합니다.

Burstable 클래스의 파드는 Guranteed 클래스에 의해 리소스가 선점된 상황에서, 노드 내 남아있는 자원이 요청한 자원보다 적을 경우에 제거됩니다.

다음의 조건을 만족하면 Burstable 클래스가 부여됩니다.

  • 파드가 Guaranteed 클래스에 속하지 않는 경우
    (= 리소스 요청 & 제한 속성에 뭔가 누락된 내용이 있을 경우)

  • 파드 내 하나 이상의 컨테이너가 리소스 요청 또는 제한값을 가질 경우

Burstable 클래스를 부여받는 파드 예시

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo-2
  namespace: qos-example
spec:
  containers:
    - name: qos-demo-2-ctr
      image: nginx
      resources:
        limits:
          memory: "200Mi"
        requests:
          memory: "100Mi"

출력된 파드 정보

apiVersion: v1
kind: Pod
  ...
  qosClass: Burstable
  startTime: "2022-04-24T03:23:35Z"

BestEffort 클래스

파드 내 모든 컨테이너가 리소스 요청 & 제한 정보를 명시하지 않으면 스케줄링 우선순위가 가장 낮은 BestEffort 클래스가 부여됩니다.

BestEffort 파드는 노드 내 가용 자원을 필요한 만큼 사용할 수 있지만, 클러스터 내에 더 높은 우선순위를 갖는 파드가 자원을 필요로 할 경우 제일 먼저 제거됩니다.

Burstable 클래스를 부여받는 파드 예시

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo-3
  namespace: qos-example
spec:
  containers:
    - name: qos-demo-3-ctr
      image: nginx

출력된 파드 정보

apiVersion: v1
kind: Pod
  ...
  qosClass: BestEffort
  startTime: "2022-04-24T03:32:08Z"
profile
Public Cloud 및 Cloud Native 기술에 관심이 많습니다.

0개의 댓글