EKS Pod 리소스 최적화 가이드
📅 작성일: 2026-02-12 | 수정일: 2026-02-14 | ⏱️ 읽는 시간: 약 46분
📌 기준 환경: EKS 1.30+, Kubernetes 1.30+, Metrics Server v0.7+
개요
Kubernetes 환경에서 Pod 리소스 설정은 클러스터 효율성과 비용에 직접적인 영향을 미칩니다. 컨테이너의 50%가 요청한 CPU의 1/3만 사용하며, 이는 평균 40-60%의 리소스 낭비로 이어집니다. 이 가이드는 Pod 레벨 리소스 최적화를 통해 클 러스터 효율성을 극대화하고 비용을 30-50% 절감하는 실전 전략을 제공합니다.
관련 문서와의 차이점
- karpenter-autoscaling.md: 노드 레벨 오토스케일링 (이 문서는 Pod 레벨)
- cost-management.md: 전체 비용 전략 (이 문서는 리소스 설정에 집중)
- eks-resiliency-guide.md: 리소스 설정을 체크리스트 항목으로만 다룸
핵심 내용
- Requests vs Limits 심층 이해: CPU throttling과 OOM Kill 메커니즘
- QoS 클래스 전략: Guaranteed, Burstable, BestEffort의 실전 활용
- VPA 완벽 가이드: 자동 리소스 조정과 HPA 공존 패턴
- Right-Sizing 방법론: P95 기반 리소스 산정 및 Goldilocks 활용
- 비용 영향 분석: 리소스 최적화의 실제 절감 효과
학습 목표
이 가이드를 완료하면 다음을 수행할 수 있습니다:
- CPU와 Memory requests/limits의 정확한 동작 원리 이해
- 워크로드 특성에 맞는 QoS 클래스 선택
- VPA와 HPA를 안전하게 공존시키는 구성
- 실제 사용량 기반 Right-Sizing 수행
- 리소스 효율성 30% 이상 개선
사전 요구사항
필요한 도구
| 도구 | 버전 | 용도 |
|---|---|---|
| kubectl | 1.28+ | Kubernetes 클러스터 관리 |
| helm | 3.12+ | VPA, Goldilocks 설치 |
| metrics-server | 0.7+ | 리소스 메트릭 수집 |
| kubectl-top | 내장 | 리소스 사용량 확인 |
필요한 권한
# RBAC 권한 확인
kubectl auth can-i get pods --all-namespaces
kubectl auth can-i get resourcequotas
kubectl auth can-i create verticalpodautoscaler
선행 지식
- Kubernetes Pod, Deployment 기본 개념
- YAML 매니페스트 작성 경험
- Linux cgroups 기본 이해 (권장)
- Prometheus/Grafana 기본 사용법 (권장)
Resource Requests & Limits 심층 이해
2.1 Requests vs Limits의 정확한 의미
Resource requests와 limits는 Kubernetes 리소스 관리의 핵심 개념입니다.
Requests (요청량)
- 정의: 스케줄러가 Pod 배치 시 보장하는 최소 리소스
- 역할: 노드 선택 기준, QoS 클래스 결정
- 보장: kubelet이 이 양을 항상 확보
Limits (제한량)
- 정의: kubelet이 강제하는 최대 리소스
- 역할: 리소스 고갈 방지, 노이지 네이버(noisy neighbor) 제한
- 강제: CPU는 throttling, Memory는 OOM Kill
핵심 차이점
| 속성 | CPU | Memory |
|---|---|---|
| Requests 초과 시 | 다른 Pod가 사용 안 하면 사용 가능 | 다른 Pod가 사용 안 하면 사용 가능 |
| Limits 초과 시 | Throttling (프로세스 속도 저하) | OOM Kill (프로세스 강제 종료) |
| 압축 가능 여부 | 압축 가능 (Compressible) | 압축 불가 (Incompressible) |
| 초과 사용 위험 | 성능 저하 | 서비스 중단 |
2.2 CPU 리소스 깊이 이해
CPU Millicore 단위
# CPU 표기법
resources:
requests:
cpu: "500m" # 500 millicore = 0.5 CPU core
cpu: "1" # 1000 millicore = 1 CPU core
cpu: "2.5" # 2500 millicore = 2.5 CPU cores
1 CPU core = 1000 millicore
- AWS vCPU, Azure vCore 모두 동일
- 하이퍼스레딩 환경에서도 논리 코어 기준
CFS Bandwidth Throttling
Linux CFS (Completely Fair Scheduler)는 CPU limits를 강제합니다:
# cgroups v2 기준
/sys/fs/cgroup/cpu.max
# 예시: "100000 100000" = 100ms 주기당 100ms 사용 가능 (100% = 1 CPU)
# 예시: "50000 100000" = 100ms 주기당 50ms 사용 가능 (50% = 0.5 CPU)
Throttling 메커니즘
시간 주기: 100ms
CPU Limit: 500m (0.5 CPU)
→ 100ms 중 50ms만 사용 가능
실제 동작:
[0-50ms] ████████████████████ (실행)
[50-100ms] ...................... (throttled)
[100-150ms] ████████████████████ (실행)
[150-200ms] ...................... (throttled)
CPU Limits를 설정하지 않는 전략
Google, Datadog 등 대규모 클러스터 운영 조직은 CPU limits를 설정하지 않습니다:
이유:
- CPU는 압축 가능한 리소스 (다른 Pod가 필요하면 자동 조정)
- Throttling으로 인한 불필요한 성능 저하 방지
- Requests만으로도 스케줄링과 QoS 제어 가능
대신 권장:
- CPU requests는 P95 사용량 기준으로 설정
- HPA로 부하에 따른 수평 확장
- Node-level 리소스 모니터링 강화
예외 (Limits 설정 필요):
- 배치 작업 (CPU 독점 방지)
- 신뢰할 수 없는 워크로드
- 멀티테넌트 환경
CPU 리소스 설정 예시
# 패턴 1: Requests만 설정 (권장)
apiVersion: v1
kind: Pod
metadata:
name: web-server
spec:
containers:
- name: nginx
image: nginx:1.25
resources:
requests:
cpu: "250m" # P95 사용량 기준
memory: "128Mi"
# limits 생략 - CPU 압축 가능 리소스 활용
---
# 패턴 2: 배치 작업 (Limits 설정)
apiVersion: batch/v1
kind: Job
metadata:
name: data-processing
spec:
template:
spec:
containers:
- name: processor
image: data-processor:v1
resources:
requests:
cpu: "1000m"
limits:
cpu: "2000m" # CPU 독점 방지
memory: "4Gi"
restartPolicy: OnFailure