# LimitRange와 ResourceQuota

쿠버네티스 환경에서 리소스를 효율적으로 관리하지 않으면, 특정 Pod나 네임스페이스가 클러스터 자원을 독점해 다른 워크로드에 영향을 줄 수 있습니다. LimitRange와 ResourceQuota는 이러한 상황을 예방하기 위한 두 가지 핵심 메커니즘입니다.

# 1. LimitRange: Pod/컨테이너 수준의 리소스 가이드라인

# 1-1. LimitRange가 필요한 이유

Pod 스펙에 requestslimits를 지정하지 않으면 쿠버네티스 스케줄러는 자원의 요구량을 0으로 인식해 노드에 무분별하게 스케줄링할 수 있습니다. 그러면 노드 리소스가 고갈되고 다른 Pod가 제때 스케줄되지 못할 수 있습니다.

# 1-2. Admission Controller와의 관계

LimitRange는 LimitRanger Admission Controller가 적용합니다. Pod가 API 서버로 제출될 때:

  1. Pod 스펙에 요청/제한 값이 없으면 defaultRequest 및 default 값으로 자동 보정됩니다.
  2. 요청값이 최소(min) 또는 최대(max) 범위를 벗어나면 유효성 검사에서 실패합니다.

# 1-3. LimitRange와 QoS 클래스

LimitRange는 쿠버네티스 QoS(Quality of Service) 클래스에도 직접 영향을 줍니다:

  • Guaranteed: 모든 컨테이너가 request=limit 설정.
  • Burstable: request < limit.
  • BestEffort: request/limit 미설정(→ LimitRange로 최소 보정 가능).

QoS 클래스는 Pod OOM(Out-Of-Memory) 발생 시 eviction 우선순위를 결정하므로, LimitRange는 QoS 설계에도 중요한 역할을 합니다.

# 2. ResourceQuota: 네임스페이스 자원의 상한선

# 2-1. ResourceQuota 어드미션 플러그인

ResourceQuota 한도는 API 서버의 ResourceQuota Admission Controller(어드미션 플러그인)가 적용합니다. 네임스페이스의 사용량 집계(status.used)는 컨트롤러 매니저의 ResourceQuota 컨트롤러가 함께 갱신합니다.

  • Pod나 PVC가 생성될 때 현재 사용량(usage)을 조회하고 hard에 정의된 한도를 초과하면 API 서버가 Forbidden 에러를 반환합니다.
  • requests.cpu, limits.memory 같은 컴퓨트 리소스 쿼터가 있는 네임스페이스에서는 해당 리소스의 request/limit을 지정하지 않은 Pod가 0으로 계산되지 않고 생성이 거부됨. LimitRange로 기본값을 주입하면 이 거부를 피할 수 있음.

# 2-2. Pod 생성 폭주 방지

실서비스에서는 특정 팀/서비스가 스케일 아웃 시 수십 개 Pod를 동시에 생성할 수 있습니다. ResourceQuota는 이러한 Pod 생성 폭주를 막아 클러스터를 안정적으로 유지합니다.

# 3. LimitRange vs ResourceQuota: 내부 동작 차이

| 항목 | LimitRange | ResourceQuota | | | | - | | 적용 범위 | Pod/컨테이너 단위 | 네임스페이스 전체 | | 검증 시점 | Admission Controller 단계 (LimitRanger) | Admission Controller 단계 (ResourceQuota) | | 주요 목적 | 합리적인 리소스 요청 강제 | 네임스페이스별 자원 독점 방지 | | QoS 클래스에 영향 | O (defaultRequest/limit으로 결정) | X |

# 4. 실무 설계 패턴

# 4-1. 개발/테스트 vs 운영 환경

  • 개발/테스트:

    • LimitRange로 작은 defaultRequest 설정 (ex: cpu=100m, memory=128Mi).
    • ResourceQuota로 네임스페이스 CPU/메모리를 제한 (ex: requests.cpu=1, limits.memory=2Gi).
  • 운영 환경:

    • 서비스별로 충분한 리소스를 보장 (request=limit 설정으로 Guaranteed QoS 확보).
    • ResourceQuota를 느슨하게 설정하되, 팀 단위로 명확히 구분.

# 4-2. 헬름(Helm) 기반 템플릿화

운영 시 팀별 네임스페이스에 동일한 패턴을 적용하기 위해 LimitRange + ResourceQuota를 Helm Chart로 묶어 배포하면 관리하기 쉽습니다.

# 5. 운영 시 발생할 수 있는 문제와 해결책

# 문제 1: Pod 생성 거부 (exceeded quota / LimitRange 위반)

  • 원인: Pod의 request/limit을 더하면 ResourceQuota의 hard 한도를 초과하거나, LimitRange의 min/max 범위를 벗어나 API 서버가 Pod 생성을 거부. (Insufficient cpu/memory는 쿼터 거부가 아니라 노드 자원이 부족할 때 스케줄러가 남기는 메시지)
  • 해결: kubectl describe quota, kubectl describe limitrange 명령어로 원인 분석.

# 문제 2: QoS 클래스 BestEffort로 인한 Eviction

  • 원인: LimitRange 미적용 시 request=0 → BestEffort로 스케줄됨.
  • 해결: LimitRange로 request 최솟값 설정.

# 문제 3: PVC 초과 생성

  • ResourceQuota에 PVC 수를 제한하지 않으면, 과도한 볼륨 사용 가능.
  • 해결: persistentvolumeclaims 필드를 반드시 관리.

# 6. LimitRange + ResourceQuota 실전 YAML

# LimitRange
apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: team-a
spec:
  limits:
  - type: Container
    defaultRequest:
      cpu: 200m
      memory: 256Mi
    default:
      cpu: 400m
      memory: 512Mi
    min:
      cpu: 100m
      memory: 128Mi
    max:
      cpu: 1
      memory: 1Gi

# ResourceQuota
apiVersion: v1
kind: ResourceQuota
metadata:
  name: namespace-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "6"
    limits.memory: 12Gi
    pods: "20"
    persistentvolumeclaims: "10"

# 7. 실무 TIP: 설계 체크리스트

  1. LimitRange의 defaultRequest 값은 노드 리소스를 고려해 현실적인 값으로 설정.
  2. ResourceQuota 값은 팀별/네임스페이스별 리소스 할당량과 매칭.
  3. QoS 클래스(Guaranteed vs Burstable)를 의도적으로 관리하여 OOM 및 eviction 우선순위 제어.
  4. kubectl describe quotakubectl describe limitrange로 지속적으로 상태 점검.
  5. Prometheus로 ResourceQuota 사용량을 모니터링해 초과 위험 시 Alert.

# 8. 마무리

LimitRange와 ResourceQuota는 리소스를 제한하는 도구일 뿐 아니라 클러스터 리소스 전략의 핵심입니다.

  • LimitRange → Pod 단위 리소스 품질 보장 (QoS 클래스 제어)
  • ResourceQuota → 네임스페이스별 공평한 자원 분배

두 메커니즘을 함께 사용하면 클러스터를 안정적이고 예측 가능하게 운영할 수 있습니다.