쿠버네티스 노드, 크게 띄울까 잘게 쪼갤까? CPU·메모리 사이징 판단 기준 총정리

Kubernetes 운영 비용

클러스터를 처음 구성할 때 가장 먼저 부딪히는 질문이 있다. 노드를 몇 개로, 얼마나 크게 잡아야 하는가. vCPU 4개짜리 노드 열 대가 나을까, 16개짜리 세 대가 나을까. 이 판단을 감으로 내리면 리소스 낭비와 안정성 문제가 동시에 찾아온다. 이 글을 끝까지 읽으면 워크로드 특성에 따라 노드 크기를 결정하는 구체적 기준과, 클라우드 인스턴스 타입 선택 시 반드시 확인해야 할 체크포인트를 갖추게 된다.

노드 사이징을 잘못 잡으면 어떤 문제가 생기는가

과대 프로비저닝의 실체

실제 적용 사례를 살펴보면, 초기 클러스터 설계 시 “넉넉하게 잡자”는 판단이 가장 흔하다. m5.2xlarge(8 vCPU, 32GB) 노드 다섯 대로 시작한 팀이 실제 CPU 사용률을 측정해보니 평균 18%에 머무는 경우가 적지 않다. 월 청구서의 절반 이상이 유휴 리소스에 쓰이는 셈이다.

과소 프로비저닝이 부르는 장애

반대로 비용을 아끼겠다고 노드를 너무 작게 잡으면 Pod 스케줄링 실패가 빈번해진다. Pending 상태로 대기하는 Pod가 쌓이면 서비스 응답 지연으로 이어진다. 결국 긴급 스케일아웃을 하게 되고, 스팟 인스턴스 확보 경쟁까지 겹치면 오히려 온디맨드보다 비싼 비용을 치르기도 한다.

쿠버네티스 노드 사이징의 근본 원인, 왜 정답이 없다고 느끼는가

시스템 오버헤드라는 보이지 않는 변수

노드 하나에 할당 가능한 리소스는 인스턴스 스펙 그대로가 아니다. kubelet, kube-proxy, OS 커널, containerd 런타임이 일정량을 선점한다. 쿠버네티스 공식 문서에 따르면 kubelet의 기본 예약량은 CPU 코어 수에 비례해 증가하며, 4 vCPU 노드에서 약 6~8%의 CPU가 시스템 예약으로 빠진다. 메모리 역시 커널과 eviction threshold로 약 500MB~1GB가 차감된다.

노드가 작을수록 이 오버헤드 비율이 커진다. t3.medium(2 vCPU, 4GB)에서는 할당 가능 메모리가 전체의 75% 수준까지 떨어질 수 있다. 노드를 크게 잡을수록 오버헤드 비율은 줄어들지만, 장애 시 blast radius가 커지는 트레이드오프가 존재한다.

워크로드 프로파일의 차이

CPU 집약 워크로드와 메모리 집약 워크로드는 최적 인스턴스 패밀리가 완전히 다르다. 배치 처리나 CI/CD 파이프라인은 c 계열(컴퓨팅 최적화)이 유리하고, Redis 캐시나 JVM 기반 서비스는 r 계열(메모리 최적화)이 맞다. 범용 m 계열로 모든 워크로드를 수용하려는 접근이 비효율의 가장 큰 원인이다.

Kubernetes 운영 비용

CPU 메모리 최적 인스턴스 타입 선택 기준, 실전 비교 프레임워크

빈패킹 효율로 판단하기

핵심 지표는 빈패킹 효율(bin-packing efficiency)이다. Pod의 request 합계를 노드의 allocatable 리소스로 나눈 값이 80% 이상이면 양호하다. 이 수치가 60% 미만이면 노드 크기를 줄이거나 Pod request를 재조정해야 한다.

구체적으로 비교해 보자. 1 vCPU / 2GB request를 가진 Pod 20개를 배치한다고 가정하면:

  • 4 vCPU / 16GB 노드 6대: allocatable 약 3.7 vCPU, 14GB → Pod 3개씩 → 18개만 수용, 2대 추가 필요
  • 8 vCPU / 32GB 노드 3대: allocatable 약 7.4 vCPU, 30GB → Pod 7개씩 → 21개 수용 가능, 여유분 확보
  • 16 vCPU / 64GB 노드 2대: allocatable 약 15.2 vCPU, 61GB → Pod 15개씩 → 30개 수용, 과잉 가능성

이 사례에서 8 vCPU 노드가 빈패킹과 가용성의 균형점이 된다. 단, Pod 크기가 4 vCPU 이상이면 8 vCPU 노드에 하나만 들어가므로 낭비가 심해진다. 가장 큰 Pod의 request 기준으로 노드 최소 크기를 결정하는 것이 원칙이다.

클라우드별 인스턴스 패밀리 선택

AWS 기준으로 정리하면 범용(m6i), 컴퓨팅 최적화(c6i), 메모리 최적화(r6i)가 주요 후보다. AWS EC2 인스턴스 타입 페이지에서 vCPU 대비 메모리 비율을 확인할 수 있다. m 계열은 1:4, c 계열은 1:2, r 계열은 1:8 비율이다. 클러스터 전체 Pod의 CPU:메모리 request 비율 평균을 구한 뒤, 가장 가까운 패밀리를 고르면 된다.

GCP의 경우 e2-standard(범용), c2(컴퓨팅), n2-highmem(메모리)으로 대응된다. Azure는 Dsv5, Fsv2, Esv5 시리즈가 각각 해당한다.

노드 크기를 키우면 안 되는 경우, 리스크와 주의사항

blast radius 문제

노드 한 대에 Pod 30개가 올라가 있다면, 그 노드가 죽는 순간 30개 서비스가 동시에 영향받는다. Topology Spread Constraints로 분산을 강제할 수 있지만, 노드 수가 적으면 분산 자체가 제한된다. 고가용성이 필수인 프로덕션 환경에서는 노드당 최대 Pod 수를 의도적으로 제한하는 편이 안전하다.

스팟 인스턴스와의 궁합

큰 인스턴스일수록 스팟 중단 빈도가 높아지는 경향이 있다. 16xlarge 스팟이 회수되면 한 번에 대량의 Pod가 축출된다. 노드 사이징과 스팟 전략의 TCO 관계에서 다룬 것처럼, 스팟을 적극 활용하려면 중간 크기 노드를 여러 대 운영하는 전략이 비용과 안정성 양쪽에서 유리하다.

주의: 모든 워크로드를 단일 노드 그룹으로 운영하지 마세요. CPU 집약과 메모리 집약 워크로드를 분리된 노드 그룹에 배치하고, 각 그룹에 맞는 인스턴스 타입을 지정하는 것이 리소스 효율의 핵심입니다.

Kubernetes 운영 비용

결국 어떤 크기를 선택해야 하는가

워크로드 분류부터 시작하기

권장 프로세스는 세 단계다. 먼저, 모든 Pod의 resource request를 수집한다. kubectl top과 메트릭 서버, 또는 Kubecost 같은 도구로 실사용량을 최소 2주간 측정하는 것이 이상적이다. 두 번째로 CPU:메모리 비율 기준으로 워크로드를 그룹핑한다. 세 번째로 각 그룹에 맞는 인스턴스 패밀리와 크기를 매칭하되, 가장 큰 Pod의 request에 시스템 오버헤드를 더한 값보다 노드 allocatable이 최소 2배 이상이 되도록 설정한다.

실용적 기본값

확신이 없다면 8 vCPU / 32GB (m6i.2xlarge 또는 동급)가 범용 출발점으로 무난하다. 오버헤드 비율이 합리적이고, 스팟 회수 시 영향 범위도 관리 가능한 수준이다. 여기서 시작해 실측 데이터를 바탕으로 c 계열이나 r 계열로 분화시키는 접근이 가장 현실적이다.

핵심 요약과 다음 단계

정리하면 이렇다.

  • 노드 크기는 “가장 큰 Pod request × 2 + 시스템 오버헤드” 이상으로 설정
  • CPU:메모리 비율로 인스턴스 패밀리를 선택하고, 빈패킹 효율 80%를 목표로 조정
  • blast radius와 스팟 회수 리스크를 고려해 극단적으로 크거나 작은 노드는 피할 것

오늘 당장 할 수 있는 첫 단계는 kubectl describe nodes로 현재 allocatable과 실제 request 합계를 비교하는 것이다. 빈패킹 효율이 60% 미만인 노드가 있다면 사이징 재조정의 신호다. 비용 모니터링 자동화와 오토스케일링 전략까지 확장하고 싶다면, FinOps 전략으로 클라우드 비용을 줄인 기업 사례도 참고해 보길 권한다.

댓글 남기기