리밋 레인지

리밋 레인지 (Limit Ranges)

기본적으로 컨테이너는 Kubernetes 클러스터에서 제한 없는 컴퓨트 리소스로 실행돼요. Kubernetes 리소스 쿼터(resource quotas)를 사용하면 관리자(또는 클러스터 운영자)가 특정 네임스페이스 안에서 CPU 시간, 메모리, 영구 스토리지 같은 클러스터 리소스의 소비와 생성을 제한할 수 있습니다.

네임스페이스 안에서는 Pod가 해당 네임스페이스에 적용된 ResourceQuota가 허용하는 만큼의 CPU와 메모리를 소비할 수 있어요. 하지만 클러스터 운영자나 네임스페이스 레벨 관리자 입장에서는, 단일 객체가 네임스페이스 안의 모든 가용 리소스를 독점할 수 없도록 하는 것도 중요하죠.

LimitRange는 네임스페이스 안의 각 적용 대상 객체 종류(예: Pod, PersistentVolumeClaim)에 대해 지정할 수 있는 리소스 할당(limits와 requests)을 제한하는 정책입니다.

_LimitRange_가 제공하는 제약은 다음과 같은 일을 할 수 있어요.

  • 네임스페이스 안의 Pod 또는 Container별 최소/최대 컴퓨트 리소스 사용을 강제합니다.
  • 네임스페이스 안의 PersistentVolumeClaim별 최소/최대 스토리지 요청을 강제해요.
  • 네임스페이스 안의 리소스에 대해 request와 limit 사이의 비율을 강제합니다.
  • 네임스페이스의 컴퓨트 리소스에 대한 기본 request/limit를 설정하고, 런타임에 컨테이너에 자동으로 주입해요.

네임스페이스에 LimitRange 객체가 하나라도 있으면, Kubernetes는 그 네임스페이스 안의 Pod에 대한 리소스 할당을 제한합니다. LimitRange 객체의 이름은 유효한 DNS 서브도메인 이름이어야 해요.

리소스 limits와 requests에 대한 제약 (Constraints on resource limits and requests)

  • 관리자가 네임스페이스에 LimitRange를 생성합니다.
  • 사용자가 그 네임스페이스에 Pod나 PersistentVolumeClaim 같은 객체를 생성(또는 생성 시도)합니다.
  • 먼저, LimitRange 어드미션 컨트롤러가 컴퓨트 리소스 요구사항을 설정하지 않은 모든 Pod(와 그 컨테이너)에 기본 request와 limit 값을 적용해요.
  • 다음으로, LimitRange는 사용량을 추적해 네임스페이스에 존재하는 어떤 LimitRange에도 정의된 리소스 최소값, 최대값, 비율을 초과하지 않도록 보장합니다.
  • LimitRange 제약을 위반하는 객체(Pod 또는 PersistentVolumeClaim)를 생성하거나 갱신하려 하면, API 서버에 대한 요청이 HTTP 상태 코드 403 Forbidden과 위반된 제약을 설명하는 메시지와 함께 실패해요.
  • cpumemory 같은 컴퓨트 관련 리소스에 적용되는 LimitRange를 네임스페이스에 추가하면, 그 값들에 대한 requests나 limits를 반드시 지정해야 합니다. 그렇지 않으면 시스템이 Pod 생성을 거부할 수 있어요.
  • LimitRange 검증은 Pod 어드미션 단계에서만 일어나며, 실행 중인 Pod에는 적용되지 않습니다. LimitRange를 추가하거나 수정해도 그 네임스페이스에 이미 존재하는 Pod는 그대로 유지돼요.
  • 네임스페이스에 LimitRange 객체가 둘 이상 있으면, 어떤 기본값이 적용될지는 비결정적입니다.

Pod에 대한 LimitRange와 어드미션 체크 (LimitRange and admission checks for Pods)

LimitRange는 자신이 적용하는 기본값의 일관성을 검사하지 않아요. 즉 LimitRange가 설정한 기본 limit 값이 클라이언트가 API 서버에 제출한 스펙에서 컨테이너에 지정한 request 값보다 작을 수 있습니다.

예를 들어, 다음 LimitRange가 있다고 해봅시다.

apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-resource-constraint
spec:
  limits:
  - default:      # 이 섹션은 기본 limits를 정의
      cpu: 500m
    defaultRequest:  # 이 섹션은 기본 requests를 정의
      cpu: 500m
    max:
      cpu: "1"
    min:
      cpu: 100m
    type: Container

이 LimitRange와 함께 CPU 리소스 request가 700m인데 limit는 지정하지 않은 Pod를 만들면, 요청이 다음과 같이 실패합니다.

Pod "example-conflict-with-limitrange-cpu" is invalid: spec.containers[0].resources.requests: Invalid value: "700m": must be less than or equal to cpu limit

같은 LimitRange가 있어도 requestlimit 둘 다 설정하면 새 Pod는 성공적으로 스케줄링됩니다.

리소스 제약 예시 (Example resource constraints)

LimitRange로 만들 수 있는 정책의 예시는 다음과 같아요.

  • 8 GiB RAM과 16코어 용량의 2노드 클러스터에서, 네임스페이스의 Pod가 CPU를 100m 요청하고 최대 500m 제한, 메모리를 200Mi 요청하고 최대 600Mi 제한하도록 제약합니다.
  • 기본 CPU limit와 request를 150m로, 기본 메모리 request를 300Mi로 정의합니다.

네임스페이스 전체 limit의 합이 Pod/Container limit의 합보다 작으면, 리소스에 대한 경쟁이 생길 수 있어요. 이 경우 Container나 Pod는 생성되지 않습니다. 리소스 경쟁이나 LimitRange 변경은 이미 생성된 리소스에는 영향을 주지 않아요.

더 알아보기

  • 리소스 쿼터(ResourceQuota)
  • 컨테이너 리소스 관리
  • 네임스페이스와 리소스 제한
  • 어드미션 컨트롤러