쿠버네티스 리소스 요청(Requests) 및 제한(Limits) 마스터링으로 최고의 성능 달성하기
쿠버네티스는 컨테이너화된 애플리케이션의 배포, 확장 및 관리를 자동화하는 강력한 기능을 제공합니다. 하지만 클러스터 전반에 걸쳐 최고의 성능을 실현하고 안정성을 유지하는 것은 워크로드에 대한 리소스 요구 사항을 어떻게 정의하느냐에 달려 있습니다. 잘못 구성된 리소스 설정은 성능 병목 현상, 예측 불가능한 스케줄링 및 비효율적인 클러스터 활용의 주요 원인입니다.
이 가이드는 쿠버네티스의 리소스 요청(Resource Requests) 및 제한(Limits)에 대해 심층적으로 다룹니다. 이 둘의 차이점을 이해하고 올바르게 적용하는 것은 애플리케이션의 서비스 품질(QoS)을 보장하고, '시끄러운 이웃(noisy neighbors)'을 방지하며, 인프라 비용을 최적화하는 데 필수적입니다. 이 설정들이 쿠버네티스 스케줄러 및 기본 운영 체제와 어떻게 상호 작용하는지 살펴보겠습니다.
핵심 개념 이해하기: 요청(Requests) 대 제한(Limits)
쿠버네티스에서 파드(Pod) 내의 모든 컨테이너 사양은 resources.requests 및 resources.limits를 사용하여 예상 리소스 소비량을 정의해야 합니다. 이 설정들은 애플리케이션 상태에 가장 중요한 두 가지 리소스인 CPU와 메모리를 제어합니다.
1. 리소스 요청 (requests)
요청(Requests)은 컨테이너가 스케줄링될 때 보장받는 리소스 양을 나타냅니다. 이는 kube-scheduler가 파드를 배치할 노드를 결정할 때 사용하는 최소 리소스 양입니다.
- 스케줄링: 새 파드가 스케줄링되려면 노드에 모든 파드 요청의 합계를 충족할 만큼 충분한 사용 가능한 할당 가능 리소스가 있어야 합니다.
- 보장: 나중에 노드의 리소스가 부족해지더라도 해당 컨테이너는 요청된 양을 최소한 계속 받게 됩니다 (단, 이브릭션 대상이 되지 않는 한).
2. 리소스 제한 (limits)
제한(Limits)은 컨테이너가 소비하도록 허용되는 리소스의 최대 양을 정의합니다. 이러한 제한을 초과하면 CPU 및 메모리에 대해 특정하게 정의된 동작이 발생합니다.
- CPU 제한: 컨테이너가 제한보다 더 많은 CPU를 사용하려고 시도하면 Linux 커널의 cgroups가 사용량을 스로틀링(제한)하여 추가 사이클 소비를 방지합니다.
- 메모리 제한: 컨테이너가 메모리 제한을 초과하면 운영 체제는 즉시 프로세스를 종료합니다 (OOMKill: 메모리 부족 종료).
CPU 대 메모리 동작
쿠버네티스가 CPU와 메모리 경계를 시행하는 방식의 질적인 차이를 이해하는 것이 중요합니다.
| 리소스 | 제한 초과 시 동작 | 적용 메커니즘 |
|---|---|---|
| CPU | 스로틀링 (속도 저하) | cgroups (cpu 대역폭 제어) |
| 메모리 | 종료 (OOMKill) | 커널 OOM Killer |
팁: CPU 스로틀링은 일반적으로 OOMKill보다 중단이 덜하므로, 일반적인 최대 사용량보다 약간 높은 CPU 제한을 설정하고 노드 안정성을 방지하기 위해 엄격한 메모리 제한을 설정하는 것이 가장 좋습니다.
파드 사양에 리소스 정의하기
리소스는 spec.containers[*].resources 블록 내에서 정의됩니다. 수량은 표준 쿠버네티스 접미사(예: 밀리 CPU의 경우 m, 메비바이트의 경우 Mi)를 사용하여 지정됩니다.
CPU 단위 정의
1CPU 단위는 1개의 전체 코어(또는 클라우드 제공 업체의 vCPU)와 같습니다.1000m(밀리코어)는 1 CPU 단위와 같습니다.
메모리 단위 정의
Mi(메비바이트) 또는Gi(기비바이트)가 일반적입니다.1024Mi=1Gi.
예시 YAML 구성
최소 500m CPU 및 256Mi 메모리는 보장되어야 하지만, 1 CPU 및 512Mi를 절대 초과해서는 안 되는 컨테이너를 고려해 보겠습니다.
resources:
requests:
memory: "256Mi"
cpu: "500m"
limits:
memory: "512Mi"
cpu: "1"
서비스 품질(QoS) 클래스
요청과 제한의 관계는 파드에 할당되는 서비스 품질(QoS) 클래스를 결정합니다. 이 클래스는 리소스가 부족해져서 노드가 메모리를 회수해야 할 때(이브릭션) 파드의 우선순위를 결정합니다.
쿠버네티스는 세 가지 QoS 클래스를 정의합니다.
1. Guaranteed (보장)
정의: 파드 내의 모든 컨테이너는 CPU 및 메모리에 대해 동일하고 0이 아닌 요청(Requests)과 제한(Limits)을 가져야 합니다.
- 이점: 이러한 파드는 리소스 압박 시 가장 나중에 이브릭션되어 최대 안정성을 보장합니다.
- 사용 사례: 엄격한 성능 격리가 필요한 중요한 시스템 구성 요소 또는 데이터베이스.
2. Burstable (버스터 가능)
정의: 파드 내의 적어도 하나의 컨테이너에 정의된 요청이 있지만, 모든 컨테이너에 대해 요청과 제한이 동일하지 않거나, 일부 리소스에 제한이 없는 경우입니다 (단, 제한을 설정하는 것이 강력히 권장됨).
- 이점: 컨테이너가 요청을 초과하여 노드의 사용되지 않는 용량을 활용할 수 있도록 허용하며, 이는 정의된 제한 내에서 가능합니다.
- 이브릭션 우선순위: Guaranteed 파드 다음이지만 BestEffort 파드 이전에 이브릭션됩니다.
- 사용 사례: 약간의 지연 시간 변화가 허용되는 대부분의 표준 무상태 애플리케이션.
3. BestEffort (최선 노력)
정의: 컨테이너에 대해 정의된 요청이나 제한이 전혀 없는 파드입니다.
- 이점: 단순성 외에는 없습니다.
- 위험: 이러한 파드는 노드가 리소스 압박을 경험할 때 가장 먼저 이브릭션 대상이 됩니다. 또한 노드 용량이 초과되면 즉시 스로틀링 또는 OOMKill 대상이 됩니다.
- 사용 사례: 쉽게 다시 시작할 수 있는 중요하지 않은 일괄 작업 또는 로깅 에이전트.
실용적인 최적화 전략
효과적인 리소스 관리는 측정, 반복 및 신중한 계획을 필요로 합니다.
전략 1: 요청을 정확하게 측정하고 설정하기
요청은 애플리케이션이 필요로 하는 일반적인 또는 최소한의 지속 가능한 부하를 반영해야 합니다. 요청을 너무 높게 설정하면 컨테이너가 사용하지 않더라도 스케줄러가 해당 리소스를 예약하므로 클러스터 용량이 낭비됩니다.
모범 사례: 모니터링 도구(Prometheus/Grafana 등)를 사용하여 과거 사용량 데이터를 분석합니다. 일반적인 작동 중 관찰된 사용량의 90번째 백분위수 근처에 요청을 설정하십시오.
전략 2: 보수적인 제한 설정하기
제한은 안전망 역할을 합니다. 메모리의 경우, 충돌을 방지하기 위해 항상 측정된 최대치보다 약간 높게 제한을 설정하십시오. CPU의 경우, 제한을 설정하면 하나의 폭주하는 프로세스가 동일 노드의 중요한 형제 프로세스에 대한 리소스를 고갈시키는 것을 방지할 수 있습니다.
CPU 제한에 대한 경고: CPU 제한을 너무 공격적으로 설정하면(예: 실제 필요량의 50%) 지속적인 스로틀링으로 인해 심각한 성능 저하가 발생합니다. Guaranteed 격리가 특별히 필요한 경우가 아니면 항상 Burstable QoS를 선호하십시오.
전략 3: 수직 파드 자동 크기 조정(VPA) 활용하기
수동으로 리소스를 조정하는 것은 어렵고 시간이 많이 소요됩니다. 수직 파드 자동 크기 조정기(VPA)는 런타임 사용량을 모니터링하고 시간이 지남에 따라 파드 사양에 정의된 요청과 제한을 자동으로 조정합니다. VPA는 구성이 잘못된 상태(또는 BestEffort)에서 최적의 Burstable 또는 Guaranteed 구성으로 워크로드를 전환하는 데 도움이 됩니다.
전략 4: 네임스페이스에 대한 리소스 할당량 사용하기
팀이나 환경 전반에 걸친 리소스 독점을 방지하기 위해 관리자는 네임스페이스 수준에서 리소스 할당량(Resource Quotas)을 사용해야 합니다. ResourceQuota는 해당 네임스페이스 내에 존재할 수 있는 총 CPU/메모리 요청 및 제한에 대한 집계 제한을 부과하여 공정성을 보장합니다.
예시 네임스페이스 할당량
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: development
spec:
hard:
requests.cpu: "10"
limits.memory: "20Gi"
이를 통해 development 네임스페이스의 모든 파드에 걸친 총 요청 CPU는 10 코어를 초과할 수 없으며, 총 메모리 제한은 20Gi를 초과할 수 없습니다.
결론
쿠버네티스 리소스 요청 및 제한을 마스터하는 것은 단순히 충돌을 방지하는 것 이상입니다. 이는 예측 가능한 성능을 달성하고 인프라 투자 수익을 극대화하는 것입니다. 스케줄링 보장을 위한 요청과 폭주하는 소비에 대한 안전을 위한 제한을 올바르게 설정함으로써, 귀하의 파드를 원하는 QoS 클래스(가급적 Burstable 또는 Guaranteed)로 승격시킬 수 있습니다. 성능 지표를 정기적으로 검토하고 애플리케이션이 발전함에 따라 최적의 리소스 정렬을 유지하기 위해 VPA와 같은 도구 활용을 고려하십시오.