95. HPA (Horizontal Pod Autoscaler) - 파드 수평 자동 스케일러

⚠️ 이 문서는 마이크로서비스(MSA)를 굴리는 쿠버네티스 클러스터에서 블랙프라이데이나 수강 신청 날 트래픽이 폭주하여 서버 CPU가 100%를 찍고 터져버리는 것을 막기 위해, **미리 설정해 둔 CPU나 메모리 임계치(예: 70%)를 넘어서는 순간 관리자가 자는 새벽이라도 쿠버네티스 스스로 파드(Pod)의 개수를 3개에서 50개로 무한정 늘리고(Scale-out), 트래픽이 빠지면 다시 3개로 쪼그라뜨려(Scale-in) 시스템 생존과 클라우드 요금 절약을 동시에 달성하는 'HPA (Horizontal Pod Autoscaler)'**를 다룹니다.

핵심 인사이트 (3줄 요약)

  1. 본질: 파드 덩치(CPU/RAM 크기) 자체를 키우는 수직 스케일링(VPA, Scale-up)이 아니라, 작은 파드의 '복제본 개수(Replica)'를 무한히 늘려 부하를 분산시키는 수평 스케일링(Scale-out)을 15초 단위로 자동 수행하는 K8s의 핵심 봇(Bot)이다.
  2. 가치: 운영자가 밤새워 모니터를 보며 수동으로 파드 개수를 늘리는(kubectl scale) 인프라 팀의 고통을 멸망시키고, 평소에는 파드 2개 분량의 클라우드 요금만 내다가 트래픽 폭주 시에만 요금을 더 내는 극강의 탄력성(Elasticity)을 완성한다.
  3. 기술 체계: HPA가 작동하려면 각 파드의 현재 심장박동(CPU 사용률)을 실시간으로 캐내는 청진기인 **Metrics Server(메트릭 서버)**가 클러스터에 무조건 깔려있어야 하며, 파드 yaml 파일에 자신의 체력 한계치인 **resources.requests**가 반드시 적혀 있어야만 수학적 계산이 돌아간다.

Ⅰ. 트래픽 폭주와 수평 스케일링(Scale-out)의 미학

서버 덩치를 키우는 것은 비싸고 한계가 있다. 쪼개서 늘려라.

  1. 수직(Scale-up) vs 수평(Scale-out):
    • 트래픽이 몰려 웹 서버(Pod)의 CPU가 100%를 쳤다.
    • 램 16GB짜리 파드 1개를 끄고 램 64GB짜리 거대한 파드로 재부팅시키는 것(VPA, 수직 스케일링)은 서비스 중단이 발생하고 물리적 한계에 부딪힌다.
    • 반면 램 16GB짜리 파드를 끄지 않고, **그 옆에 똑같은 램 16GB 파드를 10개 더 복제해서 띄워버리는 것(HPA, 수평 스케일링)**은 무중단(Zero Downtime)으로 이론상 무한대의 트래픽을 처리할 수 있는 클라우드의 근본 철학이다.
  2. HPA의 자동 개입 (Auto-scaling):
    • HPA 객체에 룰을 적는다. [목표: 평균 CPU 70% 유지 / 최소 파드 2개 / 최대 파드 50개]
    • 갑자기 트래픽이 터져 2개 파드의 평균 CPU가 90%로 치솟았다.
    • HPA는 15초마다 돌면서 이를 감지하고, "CPU를 70%로 낮추려면 파드가 몇 개 더 필요하지?" 수학 공식을 돌려, 순식간에 레플리카셋(ReplicaSet)에게 "파드 3개 더 띄워!"라고 명령을 내린다. 총 5개가 된 파드들이 부하를 나눠 먹으며 CPU는 다시 쾌적한 60%로 안정화된다.

📢 섹션 요약 비유: 식당에 갑자기 단체 손님이 몰려옵니다. 주방장 1명(파드)이 땀을 뻘뻘 흘리며(CPU 100%) 쓰러지려 합니다. 주방장의 체력을 헐크처럼 10배로 키우는 주사(Scale-up)를 놓는 건 불가능합니다. HPA 점장은 주방장의 심박수(Metrics)가 70%를 넘는 순간, 대기실에서 알바생 요리사 4명을 즉시 주방으로 더 투입(Scale-out)하여 요리(트래픽)를 분담시킴으로써 주방의 평화를 되찾는 지능형 인력 관리 시스템입니다.


Ⅱ. HPA 구동의 필수 전제 조건 (Metrics Server & Requests)

심박수를 잴 청진기가 없고, 기초 체력을 모르면 HPA는 바보가 된다.

  1. Metrics Server (메트릭 서버) 설치 강제:
    • 쿠버네티스를 갓 설치한 깡통 상태에서는 HPA가 절대 작동하지 않는다(에러 뿜음).
    • 왜냐하면 쿠버네티스 본체는 현재 1번 파드가 CPU를 얼마나 쓰고 있는지 알지 못하기 때문이다.
    • 따라서 각 서버(노드)의 밑바닥에서 실시간으로 CPU와 RAM 사용량을 긁어모아 중앙으로 쏴주는 플러그인인 **Metrics Server**를 반드시 별도로 설치해 주어야 HPA가 눈을 뜬다.
  2. resources.requests 할당의 절대 원칙:
    • HPA에 "CPU 50% 넘으면 스케일 아웃해라"라고 설정했다 치자. 도대체 "무엇의 50%"란 말인가?
    • 파드를 띄울 때 매니페스트(yaml)에 resources.requests: cpu: 500m (내 기본 체력은 0.5코어입니다) 라고 밑바탕 기준을 명시해 줘야 한다.
    • 이 기준(requests)이 없으면 HPA는 "분모(기준치)"를 모르기 때문에 $Target% = \frac{현재 사용량}{?}$ 공식을 계산하지 못하고 파드 개수를 0개도 못 늘린 채 멈춰버린다.

📢 섹션 요약 비유: HPA 점장이 알바생을 더 투입하려면 두 가지가 완벽히 준비되어 있어야 합니다. 첫째, 주방장 손목에 실시간으로 심박수를 재어 점장 스마트폰으로 쏴주는 '스마트 워치(Metrics Server)'를 채워야 합니다. 둘째, 이 주방장의 평소 정상 체력이 1분에 요리 10그릇(resources.requests)이라는 기초 체력 프로필이 사전에 등록되어 있어야만, 점장이 "어? 지금 15그릇을 빼고 있으니 한계치(50%)를 넘었네, 알바 추가해!"라고 수학적 계산을 내릴 수 있습니다.


Ⅲ. HPA의 진화: 커스텀 메트릭 (Custom Metrics)과 축소 쿨다운

단순한 CPU를 넘어, 큐(Queue)에 쌓인 메시지 수로 스케일링한다.

  1. CPU/RAM을 넘어선 스케일링 (Custom/External Metrics):
    • 비동기 처리 서버(Worker)는 CPU를 별로 안 먹는다. 대신 처리해야 할 카프카(Kafka) 메시지가 큐에 수십만 건 쌓이면 터진다.
    • 현대의 HPA는 프로메테우스(Prometheus)와 연동하여, "Kafka 큐에 쌓인 메시지 길이가 1,000건을 돌파하면 파드를 20개로 늘려라!" 같은 초정밀 '비즈니스 지표(Custom Metrics)' 기반 스케일링을 완벽하게 지원한다 (KEDA 플러그인 등 활용).
  2. 스케일 인 플래핑 (Scale-in Flapping) 방지:
    • 파드를 10개로 늘렸더니 10초 만에 손님이 다 빠져서 CPU가 10%로 떨어졌다. HPA가 신나서 파드 8개를 확 죽여버렸다(Scale-in).
    • 그런데 5초 뒤에 다시 트래픽이 폭주한다. 또 파드를 띄우려니 컨테이너 뜨는 시간(지연) 때문에 서버가 뻗는다. 이렇게 늘렸다 줄였다 미친 듯이 반복하며 시스템 자원만 낭비하는 현상을 '플래핑(Flapping)'이라 한다.
  3. 쿨다운 (Cooldown / Stabilization Window) 설정:
    • 이를 막기 위해 HPA는 파드를 늘릴 때(Scale-out)는 번개처럼 즉시 늘리지만, 파드를 줄일 때(Scale-in)는 무조건 5분(300초 기본값) 동안 꾹 참고 기다려본다.
    • 5분 내내 트래픽이 잔잔한 게 100% 확실해졌을 때만 천천히 파드를 끄는 '현자 타임(Cooldown)' 로직이 내장되어 있어 안정적인 스케일링을 보장한다.

📢 섹션 요약 비유: 점장(HPA)은 주방 심박수(CPU)만 보는 게 아니라, 바깥의 웨이팅 번호표 기계(Custom Metric, Kafka Queue)에 대기표가 100장을 넘기면 묻지도 따지지도 않고 알바를 10명 부르는 고단수 매니저입니다. 또한 손님이 다 빠졌다고 알바생을 즉시 퇴근시키지 않습니다(플래핑 방지). "혹시 2차 단체 손님이 또 올지 모르니 최소 5분(쿨다운)은 주방에서 대기하고 있어라"라고 관망한 뒤에야 천천히 알바를 집으로 돌려보내는 노련한 인건비 컨트롤러입니다.