# Kubernetes: 리소스 제한 (Resource Quotas)

#### 리소스 제한의 개요

Kubernetes에서 리소스 제한(Resource Quotas)은 네임스페이스 내에서 사용 가능한 자원을 제한하는 메커니즘이다. 리소스 제한은 클러스터 관리자에게 특정 네임스페이스에 할당된 자원의 사용량을 제어하고 관리할 수 있는 도구를 제공한다. 이는 다중 테넌트 환경에서 특히 중요하며, 네임스페이스 간의 자원 분배를 공평하게 하고, 자원 오버프로비저닝을 방지할 수 있다.

#### 리소스 제한의 목적과 필요성

Kubernetes 클러스터는 여러 네임스페이스로 분할될 수 있으며, 각 네임스페이스는 특정 팀이나 프로젝트에 할당된다. 이 경우 자원의 무분별한 사용을 방지하고 각 네임스페이스가 적절한 자원을 사용하도록 하기 위해 리소스 제한을 설정할 필요가 있다.

* **자원 오버프로비저닝 방지**: 제한 없이 자원을 사용할 경우, 특정 네임스페이스가 과도한 자원을 소비하여 다른 네임스페이스에 영향을 미칠 수 있다. 리소스 제한을 통해 이를 방지할 수 있다.
* **공평한 자원 분배**: 클러스터 관리자들은 여러 팀이나 프로젝트가 동일한 클러스터를 사용할 때, 리소스를 공평하게 분배하고자 한다. 리소스 제한은 이를 달성하기 위한 핵심 도구이다.
* **클러스터 안정성 유지**: 자원의 과다 사용은 클러스터 전체의 성능 저하 및 불안정성을 초래할 수 있다. 리소스 제한을 통해 이러한 위험을 줄일 수 있다.

#### 리소스 제한의 구성 요소

리소스 제한은 다양한 유형의 자원에 대해 설정될 수 있으며, 각 리소스는 특정 메트릭을 기반으로 제한될 수 있다.

* **Pod**: 네임스페이스 내에서 생성할 수 있는 Pod의 수를 제한한다.
* **CPU와 메모리**: 네임스페이스가 사용할 수 있는 총 CPU와 메모리 자원의 양을 제한한다. 이는 네임스페이스 내의 모든 Pod와 컨테이너의 자원 사용량을 합산한 값에 적용된다.
* **스토리지**: 네임스페이스가 사용할 수 있는 총 스토리지 용량을 제한한다. PersistentVolumeClaims (PVCs)의 합산된 용량에 적용된다.
* **오브젝트 수**: ConfigMap, Secret, PersistentVolumeClaim 등과 같은 특정 오브젝트의 수를 제한할 수 있다. 이는 클러스터 내의 오브젝트가 과도하게 생성되는 것을 방지하기 위한 것이다.

#### 리소스 제한의 동작 원리

리소스 제한은 네임스페이스 수준에서 설정되며, 네임스페이스 내에서의 자원 사용을 지속적으로 모니터링하여 설정된 제한을 초과하지 않도록 관리한다.

* **리소스 할당과 검증**: 새로운 리소스가 네임스페이스에 추가되거나 기존 리소스가 확장될 때, Kubernetes는 현재 사용 중인 리소스와 제한된 리소스를 비교한다. 요청된 리소스가 제한을 초과할 경우, Kubernetes는 해당 요청을 거부한다.
* **리소스 사용량 추적**: Kubernetes는 네임스페이스 내의 리소스 사용량을 지속적으로 추적한다. 이는 API 서버를 통해 조회할 수 있으며, 클러스터 관리자는 이를 기반으로 자원의 사용 현황을 모니터링하고 필요 시 조정을 수행할 수 있다.
* **다중 리소스 제한**: 여러 종류의 자원에 대해 동시에 제한을 설정할 수 있다. 예를 들어, CPU, 메모리, 스토리지 및 Pod 수에 대해 각각의 제한을 설정하여 네임스페이스가 각 리소스를 적절하게 사용할 수 있도록 할 수 있다.

#### 리소스 제한의 적용 방법

리소스 제한은 Kubernetes의 리소스 제한 객체(ResourceQuota)로 정의되며, YAML 형식의 매니페스트 파일로 설정할 수 있다. 리소스 제한을 적용하는 기본적인 절차는 다음과 같다.

* **리소스 제한 객체 정의**: 먼저, 네임스페이스 내에서 리소스를 제한하기 위해 ResourceQuota 객체를 정의한다. 이 객체는 제한할 자원의 종류와 양을 명시한다.

```yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: example-quota
  namespace: example-namespace
spec:
  hard:
    pods: "10"
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    persistentvolumeclaims: "5"
    requests.storage: "100Gi"
```

* **리소스 제한 적용**: 정의된 ResourceQuota 객체를 네임스페이스에 적용하면, Kubernetes는 자동으로 해당 네임스페이스 내에서 설정된 제한을 관리한다.
* **리소스 제한 관리**: 리소스 제한은 필요에 따라 수정하거나 업데이트할 수 있다. 이는 네임스페이스의 자원 사용 패턴에 따라 유연하게 대응할 수 있도록 한다.

#### 리소스 제한의 제약 및 한계

리소스 제한은 강력한 도구이지만, 몇 가지 제약 사항도 존재한다. 이러한 제약을 이해하고 적절히 대응하는 것이 중요하다.

* **네임스페이스 간 자원 공유**: 리소스 제한은 네임스페이스 간의 자원 공유를 직접적으로 관리하지 않는다. 네임스페이스 간의 자원 사용 불균형이 발생할 경우, 클러스터 관리자는 이를 모니터링하고 수동으로 조정해야 할 수도 있다.
* **복잡한 설정**: 여러 자원에 대해 복잡한 제한을 설정하는 경우, 잘못된 설정이 클러스터 운영에 부정적인 영향을 미칠 수 있다. 따라서 설정을 신중하게 구성하고, 사전에 충분히 테스트하는 것이 중요하다.
* **동적 자원 할당**: 리소스 제한은 정적으로 설정되지만, 클러스터의 자원 사용 패턴은 동적으로 변화할 수 있다. 이러한 변화에 대응하기 위해 자동화 도구를 활용하거나 주기적인 모니터링이 필요하다.

#### 리소스 제한과 관련된 확장 기능

리소스 제한은 다양한 확장 기능과 함께 사용될 수 있으며, 이를 통해 Kubernetes의 자원 관리를 더욱 정교하게 다룰 수 있다.

* **리소스 요청(Requests)과 제한(Limits)**: Pod 및 컨테이너 단위에서 리소스 요청과 제한을 설정할 수 있다. 이는 개별 리소스가 사용하는 CPU 및 메모리의 상한과 하한을 정의하며, 전체 리소스 제한과 상호작용한다.
* **우선순위 및 선점(Priority and Preemption)**: 우선순위 클래스(Priority Class)를 통해 특정 Pod가 더 높은 우선순위를 가질 수 있도록 설정할 수 있다. 리소스 제한이 초과되었을 때, 우선순위가 낮은 Pod가 종료되어 높은 우선순위의 Pod가 자원을 사용할 수 있게 된다.
* **리미트레인지(LimitRange)**: 네임스페이스 내에서 각 컨테이너의 리소스 사용량을 제한하는 정책을 설정할 수 있다. 이는 네임스페이스 내에서 과도한 자원 사용을 방지하고, 자원 사용의 균형을 맞추는 데 기여한다.

***

관련 자료:

* Kubernetes Documentation: Resource Quotas, Kubernetes.io. <https://kubernetes.io/docs/concepts/policy/resource-quotas/>
* Kubernetes Up & Running, Kelsey Hightower, Brendan Burns, Joe Beda, O'Reilly Media, 2017.
* Managing Kubernetes Resources, Bilgin Ibryam and Roland Huß, *The Kubernetes Book*, 2019.
