쿠버네티스 스케줄러 플러그인부터 HPA·VPA·Helm 릴리스 관리까지

Filter/Score 스케줄러 파이프라인, HPA·VPA·Cluster Autoscaler의 역할 분담, Helm 차트 템플릿·릴리스 관리를 실행 가능한 매니페스트로 정리한다.

2026-08-12 · 최초 발행 2025-12-11

Pod 하나가 배포되기까지는 세 가지 결정이 겹친다. 어느 노드에 앉힐지(스케줄링), 부하에 따라 몇 개로 늘릴지(오토스케일링), 어떤 버전으로 몇 번째 배포인지(Helm 릴리스). 이 세 가지를 따로 다루면 운영 중 서로 충돌하는 지점을 놓치기 쉽다. 여기서는 스케줄러 내부 동작, HPA/VPA/Cluster Autoscaler의 역할 분담, Helm 템플릿·릴리스 관리를 하나의 흐름으로 묶어 정리한다.

스케줄러는 단계별 파이프라인으로 움직인다

컨테이너 오케스트레이션의 핵심은 배치·확장·헬스체크·롤아웃/롤백·구성 관리를 자동화하는 데 있다. Kubernetes는 원하는 상태(Desired State)를 선언하면 컨트롤러가 현재 상태를 그 방향으로 수렴시키는 구조로 이를 구현한다.

스케줄링은 Pending 상태의 Pod를 적합한 노드에 배치하는 결정 과정이다. 내부적으로는 Filter(자원 적합성 확인), Score(점수화), Bind(바인딩)의 3단계가 기본 골격이지만, 실제 스케줄러 프레임워크는 Filter/Score/Reserve/Permit/PreBind/Bind/Unreserve 단계로 세분화되어 있고 NodeAffinity, Taints/Tolerations, TopologySpread 같은 정책이 각 단계에 반영된다. 스케줄링 큐와 백오프, 그리고 Preemption(선점)이 자원 경합을 처리하며, 우선순위 클래스로 서비스 품질을 보장한다.

HPA·VPA·Cluster Autoscaler, 층이 다르다

Pod Autoscaling은 세 가지 메커니즘의 조합이다. HPA(Horizontal Pod Autoscaler)는 메트릭 기반으로 Pod 수를 조정하고, VPA(Vertical Pod Autoscaler)는 Pod의 리소스 요청·제한을 조정하며, Cluster Autoscaler는 자원이 부족할 때 노드 수를 증감시킨다. 역할 분담도 명확하다 — HPA는 짧은 주기의 부하 변동 대응을, VPA는 평균 부하 패턴 최적화를, Cluster Autoscaler는 용량 한계 해소를 맡는다.

이 분담이 제대로 작동하려면 전제 조건이 있다. metrics-server나 Prometheus Adapter로 구성되는 메트릭 파이프라인의 신뢰도가 확보돼야 하고, 냉각 기간과 안정화 윈도우로 진동(oscillation)을 방지해야 한다.

HPA와 Cluster Autoscaler를 조합해 피크 시간대 자동 확장과 비피크 축소를 실행하면 인프라 비용을 2040% 절감할 수 있고, VPA와 리밋 정책 조정을 더하면 CPU·메모리 사용률을 3060%p 끌어올릴 수 있다.

Helm은 매니페스트를 템플릿화하고 릴리스를 버전으로 관리한다

Helm Charts는 Kubernetes 매니페스트를 템플릿화하고 릴리스를 버전 관리하는 도구다. values.yaml을 중심으로 파라미터화해 환경별 일관 배포를 지원한다. values.yaml로 환경·스테이지를 분리하고, templates 디렉터리에서 Deployment·Service·HPA 등을 선언한다. 차트 버전과 앱 버전을 구분해서 관리하며, 롤백·헬스체크·훅(Hooks)으로 점진적 배포 절차를 지원한다.

릴리스 자동화는 배포 리드타임을 30~70% 단축하고 재현성을 높인다.

선언적 상태와 정책 계층

원하는 상태를 선언하면 Controller가 현재 상태를 수렴시키는 구조 덕분에 장애·스파이크·노드 교체가 있어도 자동 복구와 자가 조정(Self-healing)이 이뤄진다. 이 위에 ResourceQuota·LimitRange·PodSecurity·NetworkPolicy로 격리와 남용 방지를 걸고, Admission 정책과 서명된 차트(Sigstore/COSIGN 등)로 공급망 보안을 강화한다.

이런 자동 복구·오토스케일링 조합 전반의 기대 효과로는 평균 응답시간 15~30% 개선, 장애 복구 시간(MTTR) 50% 이상 단축이 꼽힌다.

요청부터 Pod 실행까지의 흐름

템플릿 렌더링유효성 검사 권한확인(Admission)상태 저장스케줄링 대기열바인딩 결정Pod 생성 요청컨테이너 실행 프로브메트릭 수집타깃 비교Replica 조정자원 부족 경고노드 증설/축소스케줄 실패재시도/프리엠션'helm install' 또는 'kubectlapply' 요청매니페스트 생성(Deployment,HPA 등)API Serveretcd스케줄러(Filter/Score/Bind)노드 선택kubeletPod 러닝metrics-server/PrometheusAdapterHPA 컨트롤러Cluster Autoscaler이벤트/백오프

시나리오별 조합

트래픽이 급증하는 마이크로서비스는 CPU 70% 목표의 HPA로 순간 부하를 확장하고, Cluster Autoscaler로 노드를 자동 증설하며, TopologySpread로 가용영역을 분산해 단일 실패점을 최소화한다. 데이터 처리 배치·크론 워크로드는 스케줄 우선순위와 Taints/Tolerations로 전용 노드에 격리 실행하고, VPA로 작업군별 메모리 요청을 자동 교정해 OOM·스로틀링을 줄인다. 멀티테넌트 SaaS는 네임스페이스별 ResourceQuota·LimitRange와 네트워크 격리를 걸고, Helm values로 테넌트별 설정을 차등 적용하며 릴리스를 추적한다. 하이브리드·멀티리전 배포는 노드 어피니티와 지역 레이블 기반 배치를 쓰고, 차트 파라미터로 리전별 이미지 리포지토리·엔드포인트를 분기한다.

구현 절차와 코드

전제조건은 Kubernetes v1.27+, RBAC 활성화, metrics-server(HPA 필수), Prometheus Adapter(커스텀 메트릭 사용 시), Helm v3.13+·kubectl, 그리고 필요하면 Cluster Autoscaler(클라우드 공급자 통합)다.

스케줄링 제약 정의

NodeAffinity·PodAntiAffinity·Toleration·TopologySpreadConstraints를 함께 건 Deployment 예시다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      priorityClassName: high-priority
      nodeSelector:
        nodepool: general
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: disktype
                    operator: In
                    values: ["ssd"]
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                topologyKey: kubernetes.io/hostname
                labelSelector:
                  matchLabels:
                    app: web
      tolerations:
        - key: "workload"
          operator: "Equal"
          value: "batch"
          effect: "NoSchedule"
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: topology.kubernetes.io/zone
          whenUnsatisfiable: ScheduleAnyway
          labelSelector:
            matchLabels:
              app: web
      containers:
        - name: web
          image: ghcr.io/example/web:1.2.3
          resources:
            requests:
              cpu: "200m"
              memory: "256Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080

HPA(v2) 설정

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
  minReplicas: 3
  maxReplicas: 20
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 60
      policies:
        - type: Percent
          value: 100
          periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 50
          periodSeconds: 60
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

VPA는 HPA와 동시 적용할 경우 Requests만 조정하는 추천 모드를 권장한다.

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: web-vpa
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: web
  updatePolicy:
    updateMode: "Off"   # "Initial" 또는 "Auto"로 점진 전환
  resourcePolicy:
    containerPolicies:
      - containerName: "*"
        controlledResources: ["cpu","memory"]
        minAllowed:
          cpu: "200m"
          memory: "256Mi"
        maxAllowed:
          cpu: "2"
          memory: "2Gi"

Helm 차트 스캐폴딩과 values

helm create web을 실행하면 charts/templates/values 구조가 생성된다. Chart.yaml에서 차트 버전과 앱 버전을 분리한다.

apiVersion: v2
name: web
description: Web service chart
type: application
version: 0.2.0      # 차트 버전
appVersion: "1.2.3" # 애플리케이션 버전

values.yaml은 replicaCount, 이미지, 리소스, HPA 파라미터를 담는다.

replicaCount: 3
image:
  repository: ghcr.io/example/web
  tag: "1.2.3"
  pullPolicy: IfNotPresent
resources:
  requests:
    cpu: 200m
    memory: 256Mi
  limits:
    cpu: 500m
    memory: 512Mi
hpa:
  enabled: true
  minReplicas: 3
  maxReplicas: 20
  targetCPUUtilizationPercentage: 70

templates/deployment.yaml은 이 값을 템플릿 함수로 주입한다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "web.fullname" . }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ include "web.name" . }}
  template:
    metadata:
      labels:
        app: {{ include "web.name" . }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}

배포와 점검은 helm install web ./web -n prod로 설치하고 kubectl get hpa,pod -n prod로 확인한다.

운영 점검 체크리스트

메트릭 신뢰도는 샘플링 간격·레이블 카디널리티·지연 측정으로 확인한다. 리소스 모델은 Requests/Limit 비율, Burst 대비 버퍼, QoS 클래스를 점검한다. 스케일 정책은 최소·최대, 윈도우·쿨다운, 예외 시간대(예약 스케일)를 설정해야 하고, 차트 거버넌스는 values 스키마 검증·릴리스 네이밍 규칙·서명/무결성 검증을 챙긴다. 카나리·블루그린 배포에는 Helm hooks나 Argo Rollouts, 그리고 PDB·백오프 구성이 함께 필요하다.

스케줄링과 오토스케일링, Helm 배포는 따로 튜닝하면 서로의 효과를 깎아먹기 쉽다. TopologySpread로 분산 배치를 강제해놓고 HPA 안정화 윈도우를 짧게 잡으면 스케줄 실패가 늘고, 차트 템플릿이 복잡해지면 배포 자동화의 이점이 가독성 저하로 상쇄된다. 세 축을 하나의 정책 세트로 보고 점진적으로 도입하며 관찰성을 함께 강화하는 편이 안전하다.

Kubernetes스케줄링오토스케일링Helm컨테이너 오케스트레이션