본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 11. 29. · 16 Views
쿠버네티스 오토스케일링 전략 완벽 가이드
쿠버네티스 환경에서 애플리케이션을 자동으로 확장하고 축소하는 방법을 알아봅니다. HPA, VPA, Cluster Autoscaler를 활용한 실전 오토스케일링 전략을 초급자도 이해할 수 있도록 쉽게 설명합니다.
목차
1. HPA 개념과 설정
금요일 저녁, 김개발 씨는 퇴근을 앞두고 모니터링 대시보드를 확인하다가 깜짝 놀랐습니다. 트래픽이 평소의 세 배로 치솟아 있었고, 서버는 비명을 지르고 있었습니다.
"이럴 때마다 수동으로 Pod를 늘려야 하나요?" 선배 박시니어 씨가 웃으며 대답했습니다. "HPA를 설정해두면 자동으로 처리되는데, 아직 안 해뒀구나?"
**HPA(Horizontal Pod Autoscaler)**는 워크로드의 부하에 따라 Pod 개수를 자동으로 조절하는 쿠버네티스의 핵심 기능입니다. 마치 백화점에서 손님이 많아지면 계산대를 추가로 열고, 한산해지면 닫는 것과 같습니다.
CPU 사용률이나 메모리 사용량 같은 메트릭을 기준으로 필요한 만큼 Pod를 늘리거나 줄여서 최적의 성능과 비용 효율을 달성할 수 있습니다.
다음 코드를 살펴봅시다.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2 # 최소 2개 Pod 유지
maxReplicas: 10 # 최대 10개까지 확장
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # CPU 70% 넘으면 확장
김개발 씨는 입사 6개월 차 백엔드 개발자입니다. 쿠버네티스에 애플리케이션을 배포하는 것까지는 어렵지 않게 해냈지만, 트래픽 급증 상황에서는 항상 진땀을 흘렸습니다.
서버가 느려지면 kubectl scale 명령어로 수동으로 Pod를 늘리고, 트래픽이 줄어들면 다시 줄이는 작업을 반복했습니다. 박시니어 씨가 김개발 씨 자리로 다가왔습니다.
"매번 수동으로 스케일링하는 거 힘들지 않아요? HPA 설정해두면 알아서 다 해주는데." 그렇다면 HPA란 정확히 무엇일까요?
쉽게 비유하자면, HPA는 마치 놀이공원의 회전목마 운영과 같습니다. 손님이 적을 때는 한 대만 운영하다가, 줄이 길어지면 추가로 가동합니다.
그리고 손님이 빠지면 다시 운영 대수를 줄입니다. 쿠버네티스의 HPA도 마찬가지로 트래픽이 많아지면 Pod를 늘리고, 적어지면 줄이는 역할을 자동으로 수행합니다.
HPA가 없던 시절에는 어땠을까요? 개발자들은 24시간 모니터링 대시보드를 주시해야 했습니다.
새벽에 트래픽이 급증하면 알람을 받고 일어나서 수동으로 스케일링해야 했습니다. 더 큰 문제는 예측이 어렵다는 점이었습니다.
언제 트래픽이 폭증할지 모르니, 항상 넉넉하게 리소스를 할당해두었고, 이는 곧 비용 낭비로 이어졌습니다. 바로 이런 문제를 해결하기 위해 HPA가 등장했습니다.
HPA를 사용하면 자동화된 스케일링이 가능해집니다. 더 이상 새벽에 일어나서 kubectl 명령어를 입력할 필요가 없습니다.
또한 비용 최적화도 가능합니다. 트래픽이 적을 때는 최소한의 Pod만 유지하므로 불필요한 리소스 비용을 절약할 수 있습니다.
무엇보다 안정적인 서비스 운영이라는 큰 이점이 있습니다. 위의 YAML 코드를 한 줄씩 살펴보겠습니다.
먼저 scaleTargetRef 부분을 보면 어떤 Deployment를 대상으로 스케일링할지 지정합니다. 여기서는 web-app이라는 Deployment를 대상으로 합니다.
다음으로 minReplicas와 maxReplicas에서 Pod 개수의 범위를 설정합니다. 아무리 트래픽이 적어도 2개는 유지하고, 아무리 많아도 10개를 넘지 않습니다.
마지막으로 metrics 부분에서 CPU 사용률 70%를 기준으로 설정했습니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 이커머스 서비스를 운영한다고 가정해봅시다. 평소에는 트래픽이 일정하지만, 블랙프라이데이 같은 대규모 세일 기간에는 트래픽이 10배 이상 증가합니다.
HPA를 활용하면 이런 급격한 트래픽 변화에도 자동으로 대응할 수 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 리소스 요청(requests)을 설정하지 않는 것입니다. HPA가 CPU 사용률을 계산하려면 기준이 되는 requests 값이 반드시 필요합니다.
설정하지 않으면 HPA가 제대로 동작하지 않습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다. "아, 그래서 항상 선배님은 여유로우셨군요!" HPA를 제대로 설정하면 더 이상 트래픽 때문에 밤잠을 설치지 않아도 됩니다.
여러분도 오늘 배운 내용을 실제 클러스터에 적용해 보세요.
실전 팁
💡 - Deployment에 반드시 resources.requests를 설정해야 HPA가 정상 동작합니다
- minReplicas는 최소 2개 이상으로 설정하여 가용성을 확보하세요
- stabilizationWindowSeconds를 설정하면 급격한 스케일링 변동을 방지할 수 있습니다
2. 메트릭 서버 설치
김개발 씨는 박시니어 씨의 조언대로 HPA를 설정했습니다. 그런데 kubectl get hpa 명령어를 실행하니 이상한 결과가 나왔습니다.
TARGETS 열에 unknown/70%라고 표시되어 있었습니다. "왜 메트릭이 수집이 안 되는 거죠?" 박시니어 씨가 물었습니다.
"혹시 메트릭 서버 설치했어요?"
Metrics Server는 쿠버네티스 클러스터의 노드와 Pod에서 CPU, 메모리 사용량 같은 리소스 메트릭을 수집하는 핵심 컴포넌트입니다. 마치 건강검진에서 혈압과 맥박을 측정하는 기기처럼, 클러스터의 건강 상태를 실시간으로 모니터링합니다.
HPA가 제대로 동작하려면 반드시 Metrics Server가 설치되어 있어야 합니다.
다음 코드를 살펴봅시다.
# Metrics Server 설치 (Helm 사용)
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
helm repo update
helm install metrics-server metrics-server/metrics-server \
--namespace kube-system \
--set args[0]="--kubelet-insecure-tls"
# 설치 확인
kubectl get deployment metrics-server -n kube-system
# 메트릭 확인
kubectl top nodes
kubectl top pods -n production
김개발 씨는 당황했습니다. 분명히 HPA 설정은 제대로 한 것 같은데, 왜 메트릭이 unknown으로 표시되는 걸까요?
박시니어 씨가 차근차근 설명을 시작했습니다. "HPA가 스케일링 결정을 내리려면 현재 Pod들의 리소스 사용량을 알아야 해요.
그 정보를 제공하는 게 바로 Metrics Server예요." 그렇다면 Metrics Server란 정확히 무엇일까요? 쉽게 비유하자면, Metrics Server는 마치 회사의 인사팀과 같습니다.
각 부서에서 몇 명이 일하고 있는지, 업무 부하가 어느 정도인지 파악해서 경영진에게 보고합니다. 경영진은 이 정보를 바탕으로 인력 충원이나 재배치 결정을 내립니다.
Metrics Server도 마찬가지로 각 Pod의 CPU, 메모리 사용량을 수집해서 HPA에게 전달합니다. Metrics Server가 없으면 어떤 일이 벌어질까요?
HPA는 눈을 가린 채 운전하는 것과 같습니다. 현재 트래픽이 많은지 적은지 알 수 없으니, 스케일링 결정을 내릴 수가 없습니다.
kubectl top pods 명령어도 동작하지 않아서 Pod별 리소스 사용량을 확인할 수도 없습니다. Metrics Server의 동작 원리를 살펴봅시다.
Metrics Server는 각 노드에 있는 kubelet에서 메트릭을 수집합니다. kubelet은 컨테이너 런타임과 통신하여 실제 컨테이너의 리소스 사용량을 파악합니다.
이렇게 수집된 정보는 Kubernetes API를 통해 조회할 수 있게 됩니다. 위의 설치 명령어를 살펴보겠습니다.
먼저 Helm 저장소를 추가하고 업데이트합니다. Helm은 쿠버네티스의 패키지 매니저로, 복잡한 애플리케이션을 쉽게 설치할 수 있게 해줍니다.
--kubelet-insecure-tls 옵션은 로컬 개발 환경에서 인증서 검증을 건너뛰기 위한 것입니다. 프로덕션 환경에서는 적절한 인증서 설정이 필요합니다.
설치 후에는 반드시 확인 과정을 거쳐야 합니다. kubectl top nodes 명령어를 실행하면 각 노드의 CPU와 메모리 사용량이 표시됩니다.
만약 error: Metrics API not available이라는 메시지가 나온다면 아직 Metrics Server가 준비되지 않은 것입니다. 보통 설치 후 1-2분 정도 기다리면 정상적으로 동작합니다.
클라우드 환경에서는 조금 다를 수 있습니다. AWS EKS, GCP GKE, Azure AKS 같은 관리형 쿠버네티스 서비스에서는 Metrics Server가 기본으로 설치되어 있는 경우가 많습니다.
하지만 버전이 오래되었거나 설정이 필요한 경우도 있으니, 반드시 확인해보세요. 하지만 주의할 점도 있습니다.
Metrics Server는 실시간 메트릭만 제공합니다. 과거 데이터나 장기 트렌드 분석이 필요하다면 Prometheus와 같은 별도의 모니터링 시스템을 구축해야 합니다.
Metrics Server는 어디까지나 HPA 같은 오토스케일링을 위한 최소한의 메트릭만 제공한다고 생각하면 됩니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
Metrics Server를 설치한 후 다시 kubectl get hpa를 실행하니 TARGETS 열에 드디어 35%/70%라는 숫자가 표시되었습니다. "이제 HPA가 제대로 동작하겠네요!" Metrics Server는 쿠버네티스 오토스케일링의 눈과 귀입니다.
반드시 설치하고 정상 동작을 확인한 후 HPA를 설정하세요.
실전 팁
💡 - 클라우드 관리형 쿠버네티스에서는 Metrics Server가 이미 설치되어 있을 수 있으니 먼저 확인하세요
- kubectl top pods 명령어로 메트릭 수집이 정상인지 테스트하세요
- Metrics Server는 경량화를 위해 메트릭을 메모리에만 저장하므로 재시작하면 데이터가 사라집니다
3. CPU 메모리 기반 스케일링
김개발 씨는 HPA와 Metrics Server 설정을 마쳤습니다. 그런데 새로운 고민이 생겼습니다.
"CPU 기준으로만 스케일링하면 될까요? 우리 서비스는 메모리도 많이 쓰는데..." 박시니어 씨가 고개를 끄덕였습니다.
"좋은 질문이에요. 사실 CPU와 메모리를 함께 모니터링하는 게 더 정확해요."
CPU와 메모리 기반 스케일링은 HPA의 가장 기본적이면서도 효과적인 스케일링 전략입니다. 마치 자동차의 RPM과 엔진 온도를 함께 모니터링하는 것처럼, 두 가지 지표를 동시에 확인하면 더 정확한 스케일링 결정을 내릴 수 있습니다.
애플리케이션 특성에 따라 적절한 임계값을 설정하는 것이 핵심입니다.
다음 코드를 살펴봅시다.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60 # CPU 60% 기준
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70 # 메모리 70% 기준
김개발 씨의 팀에서 운영하는 API 서버는 조금 특별했습니다. 대부분의 요청은 가볍지만, 특정 API는 복잡한 데이터 처리 때문에 메모리를 많이 사용했습니다.
처음에 CPU 기준으로만 HPA를 설정했을 때 문제가 발생했습니다. CPU 사용률은 50% 정도로 여유로웠지만, 메모리가 90%를 넘어 OOM(Out of Memory)으로 Pod가 죽어버린 것입니다.
그렇다면 CPU와 메모리를 함께 모니터링하면 어떨까요? 쉽게 비유하자면, 이것은 마치 마라톤 선수의 컨디션 관리와 같습니다.
심박수(CPU)만 체크하는 것보다 체온(메모리)도 함께 확인하면 더 정확하게 페이스를 조절할 수 있습니다. 둘 중 하나라도 위험 신호가 오면 속도를 조절해야 합니다.
HPA에서 여러 메트릭을 설정하면 어떻게 동작할까요? 핵심 원리는 간단합니다.
둘 중 하나라도 임계값을 넘으면 스케일 아웃이 시작됩니다. 위 예시에서는 CPU가 60%를 넘거나 메모리가 70%를 넘으면 Pod가 추가됩니다.
반대로 스케일 인은 모든 메트릭이 안정화되어야 진행됩니다. 위의 YAML 코드를 자세히 살펴보겠습니다.
metrics 배열에 두 개의 항목이 있습니다. 첫 번째는 CPU 사용률 60%를 기준으로, 두 번째는 메모리 사용률 70%를 기준으로 합니다.
CPU 임계값을 더 낮게 설정한 이유는 CPU는 순간적으로 급증할 수 있어서 여유를 더 두는 것이 좋기 때문입니다. 임계값 설정은 어떻게 해야 할까요?
정답은 없지만, 일반적인 가이드라인이 있습니다. CPU는 50-70%, 메모리는 60-80% 사이에서 설정하는 것이 좋습니다.
너무 낮게 설정하면 불필요한 스케일링이 자주 발생하고, 너무 높게 설정하면 급증하는 트래픽에 대응하지 못할 수 있습니다. 애플리케이션 특성에 따라 전략이 달라집니다.
웹 서버처럼 연산 위주의 애플리케이션은 CPU 기반 스케일링이 효과적입니다. 반면 캐시 서버나 데이터 처리 서비스처럼 데이터를 많이 다루는 경우는 메모리 기반이 더 적합합니다.
여러분의 서비스가 어떤 특성을 가지는지 파악하는 것이 중요합니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수는 Deployment의 resources.requests 값을 제대로 설정하지 않는 것입니다. HPA가 계산하는 사용률은 requests 대비 실제 사용량입니다.
requests를 너무 높게 설정하면 사용률이 낮게 나와서 스케일 아웃이 늦어지고, 너무 낮게 설정하면 너무 자주 스케일링됩니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
CPU와 메모리 두 가지 메트릭으로 HPA를 설정한 후, 더 이상 OOM 문제가 발생하지 않았습니다. "이제야 안심하고 퇴근할 수 있겠네요." CPU와 메모리를 함께 모니터링하면 더 안정적인 서비스 운영이 가능합니다.
여러분의 애플리케이션 특성에 맞는 적절한 임계값을 찾아보세요.
실전 팁
💡 - Deployment에 resources.requests와 limits를 반드시 설정하세요
- 처음에는 보수적으로 낮은 임계값(CPU 50%, 메모리 60%)으로 시작한 뒤 모니터링하면서 조정하세요
- kubectl describe hpa 명령어로 현재 메트릭 상태와 스케일링 이벤트를 확인할 수 있습니다
4. 커스텀 메트릭 활용
어느 날 김개발 씨는 이상한 현상을 발견했습니다. CPU와 메모리 사용률은 낮은데, 응답 시간이 점점 느려지고 있었습니다.
"왜 HPA가 동작 안 하는 거죠?" 박시니어 씨가 대시보드를 보며 말했습니다. "지금 문제는 메시지 큐에 쌓인 처리 대기 건수예요.
CPU/메모리만으로는 이런 상황을 감지할 수 없어요."
커스텀 메트릭은 CPU, 메모리 외에 애플리케이션 특화된 지표를 기반으로 스케일링하는 고급 기법입니다. 마치 레스토랑에서 주방 인력을 늘릴 때 단순히 가스 사용량이 아니라 대기 주문 수를 보고 결정하는 것과 같습니다.
메시지 큐 길이, HTTP 요청 수, 응답 지연 시간 등 비즈니스에 더 의미 있는 지표로 스케일링할 수 있습니다.
다음 코드를 살펴봅시다.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: order-processor-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: order-processor
minReplicas: 2
maxReplicas: 15
metrics:
- type: External
external:
metric:
name: rabbitmq_queue_messages # RabbitMQ 대기 메시지 수
selector:
matchLabels:
queue: orders
target:
type: AverageValue
averageValue: "30" # Pod당 30개 메시지 처리
김개발 씨 팀의 주문 처리 시스템은 RabbitMQ를 사용했습니다. 사용자가 주문을 하면 메시지 큐에 쌓이고, order-processor Pod들이 이를 처리하는 구조였습니다.
문제는 명절 같은 특수 기간에 발생했습니다. 주문이 폭주하면 큐에 메시지가 수만 건씩 쌓이는데, CPU/메모리 기반 HPA는 이를 감지하지 못했습니다.
각 Pod는 여유롭게 메시지를 처리하고 있었으니까요. 하지만 처리 속도보다 유입 속도가 빨라서 지연이 점점 심해졌습니다.
이런 상황에서 필요한 것이 바로 커스텀 메트릭입니다. 쉽게 비유하자면, 커스텀 메트릭은 마치 콜센터 운영과 같습니다.
상담원(Pod)의 통화 시간(CPU)만 보는 것이 아니라, 대기 고객 수(큐 길이)를 보고 상담원을 더 투입할지 결정합니다. 대기 고객이 50명 이상이면 상담원을 추가 배치하는 것처럼요.
커스텀 메트릭을 사용하려면 어떤 준비가 필요할까요? 먼저 Prometheus가 설치되어 있어야 합니다.
Prometheus는 다양한 시스템에서 메트릭을 수집하는 모니터링 도구입니다. 그 다음 Prometheus Adapter를 설치해야 합니다.
이 어댑터가 Prometheus의 메트릭을 쿠버네티스 API로 변환해서 HPA가 사용할 수 있게 해줍니다. 위의 YAML 코드를 살펴보겠습니다.
metrics 타입이 External로 설정되어 있습니다. 이는 클러스터 외부 시스템(여기서는 RabbitMQ)의 메트릭을 사용한다는 의미입니다.
rabbitmq_queue_messages는 Prometheus가 수집하는 메트릭 이름입니다. averageValue가 30이므로, Pod당 평균 30개의 대기 메시지를 처리하도록 스케일링됩니다.
실제 시나리오를 통해 이해해봅시다. 현재 큐에 150개의 메시지가 쌓여 있고 Pod가 2개라면, Pod당 평균 75개입니다.
목표값 30을 크게 초과하므로 HPA는 Pod를 늘립니다. 계산상 150 / 30 = 5개의 Pod가 필요합니다.
HPA는 Pod를 5개로 스케일 아웃합니다. 커스텀 메트릭의 또 다른 활용 사례도 있습니다.
HTTP 요청 수를 기준으로 할 수 있습니다. 초당 요청이 1000개를 넘으면 Pod를 늘리는 식입니다.
응답 지연 시간을 기준으로 할 수도 있습니다. P95 응답 시간이 500ms를 넘으면 확장하는 것이죠.
비즈니스에 더 의미 있는 지표를 선택할 수 있다는 것이 커스텀 메트릭의 장점입니다. 하지만 주의할 점도 있습니다.
커스텀 메트릭 설정은 복잡합니다. Prometheus, Prometheus Adapter, 그리고 애플리케이션에서 메트릭을 노출하는 설정까지 필요합니다.
또한 메트릭 수집 지연으로 인해 스케일링이 늦어질 수 있습니다. CPU/메모리 기반 스케일링이 충분하다면 굳이 복잡하게 만들 필요는 없습니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 큐 길이 기반 HPA를 설정한 후, 명절 트래픽에도 주문 처리가 밀리지 않게 되었습니다.
"이제 큐가 쌓이면 자동으로 Pod가 늘어나니까 안심이에요!" 커스텀 메트릭은 강력하지만 복잡합니다. 먼저 CPU/메모리 기반 스케일링을 충분히 활용하고, 그래도 부족할 때 도입을 검토하세요.
실전 팁
💡 - Prometheus와 Prometheus Adapter 설치가 선행되어야 합니다
- 메트릭 이름과 라벨은 Prometheus에서 PromQL로 먼저 확인해보세요
- External 메트릭 외에도 Pod 메트릭, Object 메트릭 등 다양한 타입이 있습니다
5. VPA로 리소스 자동 조절
김개발 씨는 새로운 고민에 빠졌습니다. "Deployment의 resources.requests 값을 얼마로 설정해야 할지 모르겠어요.
너무 작게 설정하면 Pod가 불안정하고, 너무 크게 설정하면 리소스 낭비인데..." 박시니어 씨가 미소를 지었습니다. "VPA를 써보는 건 어때요?
적정 리소스를 자동으로 추천해줘요."
**VPA(Vertical Pod Autoscaler)**는 Pod의 리소스 요청량(requests)과 제한량(limits)을 자동으로 조절하는 기능입니다. HPA가 Pod의 개수를 늘리는 수평적 확장이라면, VPA는 각 Pod의 크기를 조절하는 수직적 확장입니다.
마치 옷을 살 때 몸에 맞는 사이즈를 찾아주는 AI 피팅 서비스처럼, 애플리케이션에 적합한 리소스 크기를 자동으로 찾아줍니다.
다음 코드를 살펴봅시다.
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: backend-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: backend-api
updatePolicy:
updateMode: "Auto" # Off, Initial, Recreate, Auto 중 선택
resourcePolicy:
containerPolicies:
- containerName: "*"
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: 2
memory: 4Gi
김개발 씨는 새로운 마이크로서비스를 배포해야 했습니다. 하지만 이 서비스가 얼마나 리소스를 사용할지 전혀 감이 오지 않았습니다.
일단 CPU 500m, 메모리 512Mi로 설정했지만, 확신이 없었습니다. 일주일 후 모니터링을 해보니 실제 사용량은 CPU 100m, 메모리 200Mi 정도였습니다.
리소스의 60% 이상이 낭비되고 있었던 것입니다. 반대로 다른 서비스는 설정한 리소스가 부족해서 OOM으로 자주 재시작되고 있었습니다.
바로 이런 문제를 해결하기 위해 VPA가 등장했습니다. 쉽게 비유하자면, VPA는 마치 스마트 에어컨과 같습니다.
사용자가 직접 온도를 설정하는 대신, 실내 온도와 외부 날씨를 분석해서 자동으로 최적의 온도를 유지합니다. VPA도 Pod의 실제 리소스 사용 패턴을 분석해서 적정 값을 찾아줍니다.
VPA의 동작 모드를 살펴봅시다. Off 모드는 추천만 제공하고 실제로 변경하지 않습니다.
kubectl describe vpa 명령어로 추천값을 확인할 수 있습니다. Initial 모드는 Pod가 새로 생성될 때만 추천값을 적용합니다.
Recreate 모드는 추천값이 변경되면 Pod를 재생성합니다. Auto 모드는 가장 적극적으로 Pod를 업데이트합니다.
위의 YAML 코드를 자세히 살펴보겠습니다. updateMode가 Auto로 설정되어 있어서 VPA가 자동으로 리소스를 조절합니다.
resourcePolicy에서 minAllowed와 maxAllowed를 설정하여 조절 범위를 제한했습니다. 아무리 사용량이 적어도 CPU 100m 이하로는 내리지 않고, 아무리 많이 사용해도 CPU 2코어, 메모리 4Gi를 넘지 않습니다.
VPA의 추천 값은 어떻게 확인할까요? 다음 명령어를 실행하면 됩니다.
kubectl describe vpa backend-vpa를 실행하면 Recommendation 섹션에서 Lower Bound, Target, Upper Bound 세 가지 값을 확인할 수 있습니다. Target이 VPA가 권장하는 최적 값입니다.
VPA 사용 시 중요한 주의사항이 있습니다. VPA와 HPA를 동일한 메트릭(CPU/메모리)으로 함께 사용하면 충돌이 발생합니다. 예를 들어 HPA는 Pod를 늘리려 하는데 VPA는 각 Pod의 리소스를 줄이려 하면 서로 상쇄될 수 있습니다.
함께 사용하려면 HPA는 커스텀 메트릭으로, VPA는 CPU/메모리로 분리해서 사용해야 합니다. 실무에서의 추천 사용 방법입니다.
처음에는 Off 모드로 설정해서 1-2주간 추천값만 관찰합니다. 추천값이 안정적으로 나오면 그 값을 Deployment에 수동으로 반영합니다.
충분히 신뢰가 쌓이면 그때 Auto 모드로 전환하는 것이 안전합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
VPA를 Off 모드로 설정하고 일주일을 관찰했더니, 훨씬 정확한 리소스 추천값을 얻을 수 있었습니다. "이제 감으로 설정하지 않아도 되겠네요!" VPA는 리소스 설정의 불확실성을 줄여줍니다.
처음에는 Off 모드로 시작해서 점진적으로 도입하세요.
실전 팁
💡 - VPA는 별도 설치가 필요합니다 (쿠버네티스 기본 컴포넌트가 아님)
- Off 모드로 먼저 추천값을 확인하고, 신뢰가 쌓이면 Auto로 전환하세요
- HPA와 함께 사용할 때는 메트릭 충돌에 주의하세요
6. Cluster Autoscaler 설정
김개발 씨의 서비스는 성장을 거듭해 트래픽이 크게 늘었습니다. HPA 덕분에 Pod는 자동으로 늘어났지만, 어느 순간 Pod가 Pending 상태에서 멈춰버렸습니다.
"노드 리소스가 부족해요. 더 이상 Pod를 스케줄링할 수 없어요." 박시니어 씨가 설명했습니다.
"Pod 스케일링은 HPA가 하지만, 노드 스케일링은 Cluster Autoscaler가 담당해요."
Cluster Autoscaler는 클러스터의 노드(서버) 개수를 자동으로 조절하는 컴포넌트입니다. HPA가 Pod 레벨의 스케일링이라면, Cluster Autoscaler는 인프라 레벨의 스케일링입니다.
마치 회사에서 직원 수(Pod)가 늘어나면 사무실(노드)을 추가로 임대하고, 직원이 줄면 사무실을 반납하는 것과 같습니다. 클라우드 환경에서 비용 최적화의 핵심입니다.
다음 코드를 살펴봅시다.
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-autoscaler-config
namespace: kube-system
data:
# AWS EKS Cluster Autoscaler 설정 예시
parameters: |
scale-down-delay-after-add: 10m
scale-down-unneeded-time: 10m
scale-down-utilization-threshold: 0.5
max-node-provision-time: 15m
balance-similar-node-groups: true
---
# Node Group 설정 (AWS ASG 예시)
# min: 2, max: 10, desired: 3
김개발 씨는 kubectl get pods 명령어를 실행했을 때 여러 Pod가 Pending 상태인 것을 발견했습니다. describe 명령어로 확인해보니 0/3 nodes are available, insufficient cpu라는 메시지가 있었습니다.
HPA는 열심히 Pod를 늘렸지만, 정작 그 Pod를 실행할 노드가 부족했던 것입니다. 마치 손님(Pod)은 많이 왔는데 테이블(노드)이 부족한 레스토랑과 같은 상황이었습니다.
바로 이런 문제를 해결하기 위해 Cluster Autoscaler가 필요합니다. 쉽게 비유하자면, Cluster Autoscaler는 마치 스마트 주차장 관리 시스템과 같습니다.
주차장(클러스터)에 차(Pod)가 많이 들어오면 새로운 주차 구역(노드)을 개방합니다. 차가 빠지면 비어있는 구역을 닫아서 관리 비용을 줄입니다.
Cluster Autoscaler의 동작 원리를 살펴봅시다. 스케일 아웃: Pod가 리소스 부족으로 스케줄링되지 못하면(Pending 상태), Cluster Autoscaler는 새 노드를 추가합니다.
클라우드 환경에서는 AWS ASG, GCP MIG 같은 노드 그룹에 새 인스턴스를 요청합니다. 스케일 인: 노드의 리소스 사용률이 기준값(기본 50%) 이하로 떨어지면 해당 노드의 Pod를 다른 노드로 이동시키고, 빈 노드를 제거합니다.
이를 통해 불필요한 클라우드 비용을 절약합니다. 위의 설정에서 중요한 파라미터를 살펴보겠습니다.
scale-down-delay-after-add는 노드 추가 후 10분간 스케일 다운을 하지 않습니다. 새 노드가 추가되자마자 바로 제거되는 것을 방지합니다.
scale-down-utilization-threshold가 0.5이므로 노드 사용률이 50% 이하일 때 제거 대상이 됩니다. max-node-provision-time은 노드 프로비저닝에 최대 15분을 허용합니다.
클라우드 제공자별로 설정 방법이 다릅니다. AWS EKS에서는 Auto Scaling Group(ASG)과 연동됩니다.
노드 그룹의 min, max, desired 설정이 Cluster Autoscaler의 스케일링 범위가 됩니다. GCP GKE는 기본으로 Cluster Autoscaler가 내장되어 있어서 설정만 활성화하면 됩니다.
Azure AKS도 마찬가지로 기능을 활성화하는 것만으로 사용 가능합니다. 실제 동작 시나리오를 살펴봅시다.
현재 3개의 노드가 있고, HPA가 Pod를 10개에서 25개로 늘리려 합니다. 기존 노드로는 20개만 수용 가능해서 5개 Pod가 Pending됩니다.
Cluster Autoscaler가 이를 감지하고 새 노드를 추가합니다. 새 노드가 Ready 상태가 되면 Pending이었던 Pod들이 스케줄링됩니다.
하지만 주의할 점도 있습니다. 노드 프로비저닝에는 시간이 걸립니다.
AWS에서 새 EC2 인스턴스가 준비되기까지 보통 2-5분 정도 소요됩니다. 따라서 급격한 트래픽 급증에 즉시 대응하기 어렵습니다.
이런 경우를 대비해 여유 노드를 미리 확보해두거나, Priority Preemption을 활용하는 전략이 필요합니다. 또한 PodDisruptionBudget(PDB)을 설정하지 않으면 스케일 다운 시 서비스 장애가 발생할 수 있습니다.
PDB는 동시에 중단될 수 있는 Pod 수를 제한하여 서비스 가용성을 보장합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
Cluster Autoscaler를 설정한 후, 대규모 프로모션 기간에도 노드가 자동으로 늘어나서 모든 트래픽을 처리할 수 있었습니다. 프로모션이 끝나자 불필요한 노드는 자동으로 제거되어 비용도 절약되었습니다.
Cluster Autoscaler는 HPA와 함께 사용할 때 진정한 완전 자동화 스케일링을 달성할 수 있습니다. 클라우드 환경에서 비용 효율적인 인프라 운영의 핵심입니다.
실전 팁
💡 - 노드 프로비저닝 시간(2-5분)을 고려해서 HPA의 스케일링 속도와 조화를 이루도록 설정하세요
- PodDisruptionBudget을 반드시 설정하여 스케일 다운 시 서비스 장애를 방지하세요
- 클라우드 비용 절약을 위해 Spot/Preemptible 인스턴스와 함께 활용하는 것도 좋은 전략입니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Istio 보안 완벽 가이드
마이크로서비스 환경에서 필수적인 Istio 보안 기능을 실무 중심으로 설명합니다. mTLS부터 인증, 인가까지 단계별로 학습하여 안전한 서비스 메시를 구축할 수 있습니다.
Istio 트래픽 관리 완벽 가이드
Istio의 트래픽 관리 기능을 마스터하는 완벽 가이드입니다. VirtualService와 DestinationRule을 활용한 라우팅부터 트래픽 분할, 헤더 기반 라우팅까지 실무에 필요한 모든 내용을 다룹니다.
Istio 설치와 구성 완벽 가이드
Kubernetes 환경에서 Istio 서비스 메시를 설치하고 구성하는 방법을 초급 개발자도 쉽게 이해할 수 있도록 실무 스토리와 비유로 풀어낸 가이드입니다. istioctl 설치부터 사이드카 주입까지 단계별로 학습합니다.
서비스 메시 완벽 가이드
마이크로서비스 간 통신을 안전하고 효율적으로 관리하는 서비스 메시의 핵심 개념부터 실전 도입까지, 초급 개발자를 위한 완벽한 입문서입니다. Istio와 Linkerd 비교, 사이드카 패턴, 실무 적용 노하우를 담았습니다.
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.