리소스 쿼터

리소스 쿼터 (Resource Quotas)

ResourceQuota 객체로 정의되는 리소스 쿼터는 네임스페이스 단위의 총 리소스 소비를 제한하는 제약을 제공합니다. ResourceQuota는 또한 API 종류별로 네임스페이스에서 생성할 수 있는 객체의 수량, 그리고 총 컴퓨트 리소스 사용량까지 제한할 수 있어요.

ResourceQuota가 동작하는 방식 (How Kubernetes ResourceQuotas work)

ResourceQuota는 사용량을 추적해 그 안에 정의된 하드 리소스 한계를 초과하지 않도록 보장합니다. ResourceQuota에 스코프(scope)를 적용해 어디에 적용할지 제한할 수도 있어요.

  • 쿼터 제약을 위반하는 리소스를 생성하거나 갱신하면, 컨트롤 플레인이 해당 요청을 HTTP 상태 코드 403 Forbidden으로 거부합니다.
  • cpumemory 같은 리소스에 대해 네임스페이스에서 쿼터가 활성화되어 있으면, 사용자는 Pod를 정의할 때 그 값들에 대한 requests나 limits를 반드시 지정해야 해요.

참고:

  • cpumemory 리소스에 대해 ResourceQuota는 그 네임스페이스의 모든 (새) Pod가 해당 리소스에 대한 limit을 설정하도록 강제합니다. cpumemory 중 하나에 대해 네임스페이스에서 리소스 쿼터를 적용하면, 여러분과 다른 클라이언트는 제출하는 모든 새 Pod에 대해 그 리소스의 requests 또는 limits반드시 지정해야 해요. 그렇지 않으면 컨트롤 플레인이 해당 Pod의 어드미션을 거부할 수 있습니다.
  • 다른 리소스에 대해서는 ResourceQuota가 동작하며, 그 리소스에 대한 limit이나 request를 설정하지 않은 네임스페이스의 Pod는 무시해요. 즉 리소스 쿼터가 임시 스토리지(ephemeral storage)를 제한하더라도, limit/request 없이 새 Pod를 만들 수 있다는 뜻입니다.

리소스 쿼터의 종류 (Types of resource quota)

ResourceQuota 메커니즘을 사용하면 다양한 종류의 제한을 강제할 수 있어요. 이 섹션에서는 강제할 수 있는 제한의 종류를 설명합니다.

인프라 리소스 쿼터 (Quota for infrastructure resources)

리소스 이름 설명
limits.cpu 종료되지 않은(비터미널) 상태의 모든 Pod에서 CPU limits의 합이 이 값을 초과할 수 없음
requests.cpu 종료되지 않은 상태의 모든 Pod에서 CPU requests의 합이 이 값을 초과할 수 없음
requests.memory 종료되지 않은 상태의 모든 Pod에서 메모리 requests의 합이 이 값을 초과할 수 없음
hugepages-<size> 종료되지 않은 상태의 모든 Pod에서 지정된 크기의 huge page requests 수가 이 값을 초과할 수 없음
cpu requests.cpu와 같음
memory requests.memory와 같음

객체 수 쿼터 (Quota on object count)

예를 들어 PodTemplate API는 코어 API 그룹에 속하므로, 네임스페이스에서 PodTemplate 객체 수를 제한하려면 count/podtemplates를 사용해요.

쿼터 보기와 설정 (Viewing and Setting Quotas)

cat <<EOF > compute-resources.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-resources
spec:
  hard:
    requests.cpu: "1"
    requests.memory: "1Gi"
    limits.cpu: "2"
    limits.memory: "2Gi"
    requests.nvidia.com/gpu: 4
EOF
Name:                    compute-resources
Namespace:               myspace
Resource                 Used  Hard
--------                 ----  ----
limits.cpu               0     2
limits.memory            0     2Gi
requests.cpu             0     1
requests.memory          0     1Gi

쿼터와 클러스터 용량 (Quota and Cluster Capacity)

  • 클러스터 전체 리소스를 여러 팀에 비례적으로 나눌 수 있어요.
  • 각 테넌트가 필요에 따라 리소스 사용량을 늘릴 수 있게 하되, 우발적인 리소스 고갈을 막을 수 있도록 넉넉한 한도를 두는 방식으로요.
  • 한 네임스페이스의 수요를 감지해 노드를 추가하고 쿼터를 늘릴 수 있습니다.

이런 정책은 ResourceQuotas를 빌딩 블록으로 사용해 구현할 수 있어요. 쿼터 사용량을 감시하고 다른 신호에 따라 각 네임스페이스의 쿼터 하드 한계를 조정하는 "컨트롤러"를 작성하면 됩니다.

쿼터 스코프 (Quota scopes)

PriorityClass 스코프 (PriorityClass scope)

scopeSelector 필드를 사용해 쿼터를 PriorityClass에 대해 스코프하면, ResourceQuota는 다음 리소스만 추적(및 제한)할 수 있어요.

  • pods
  • cpu
  • memory
  • ephemeral-storage
  • limits.cpu
  • limits.memory
  • limits.ephemeral-storage
  • requests.cpu
  • requests.memory
  • requests.ephemeral-storage

기본적으로 PriorityClass 소비 제한하기 (Limiting PriorityClass consumption by default)

이 메커니즘으로 운영자는 특정 높은 우선순위 클래스의 사용을 제한된 수의 네임스페이스로 한정할 수 있고, 모든 네임스페이스가 기본적으로 그 우선순위 클래스를 소비할 수 있게 하지 않아요.

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: "ResourceQuota"
  configuration:
    apiVersion: apiserver.config.k8s.io/v1
    kind: ResourceQuotaConfiguration
    limitedResources:
    - resource: pods
      matchScopes:
      - scopeName: PriorityClass
        operator: In

그리고 kube-system 네임스페이스에 리소스 쿼터 객체를 생성합니다.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: pods-cluster-services
spec:
  scopeSelector:
    matchExpressions:
    - operator: In
      scopeName: PriorityClass
      values: ["cluster-services"]

더 알아보기

  • 네임스페이스와 쿼터
  • 리밋 레인지(LimitRange)
  • 우선순위 클래스(PriorityClass)
  • 어드미션 컨트롤러