🎯 k8s실습 9-3: 메트릭서버와 HPA 완전 정복 가이드

📑 목차


1. 메트릭서버 개념과 아키텍처

메트릭서버란?

쿠버네티스 클러스터의 리소스 사용량(CPU, 메모리)을 수집하고 API 서버를 통해 제공하는 핵심 컴포넌트

💡 메트릭서버의 역할

🤔 질문: “왜 메트릭서버가 필요한가?”

📋 메트릭서버가 해결하는 문제들

실제 상황

  1. 문제: kubectl top pods 명령어 사용 불가
  2. 감지: “error: Metrics API not available” 에러
  3. 조치: 메트릭서버 설치
  4. 결과: 리소스 모니터링 및 HPA 동작 가능

🏗️ 메트릭서버 아키텍처

# 📊 메트릭서버 아키텍처 구조
Components:
  kubelet: 노드 리소스 수집
  metrics-server: 메트릭 집계 및 API 제공
  api-server: Metrics API 엔드포인트
  HPA Controller: 메트릭 기반 스케일링 결정

📊 메트릭 데이터 흐름

단계컴포넌트역할데이터
1kubelet노드/파드 메트릭 수집CPU, 메모리 사용량
2metrics-server메트릭 집계표준화된 메트릭
3API ServerMetrics API 제공/apis/metrics.k8s.io/
4kubectl/HPA메트릭 조회리소스 현황

2. 메트릭서버 설치 및 설정

💻 설치 방법

방법 1: 공식 YAML 매니페스트 사용

# 📦 최신 metrics-server 설치
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

방법 2: 로컬 개발환경용 설정

# 📊 metrics-server-insecure.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: metrics-server
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: metrics-server
  template:
    metadata:
      labels:
        k8s-app: metrics-server
    spec:
      containers:
      - name: metrics-server
        image: registry.k8s.io/metrics-server/metrics-server:v0.6.4
        args:
        - --cert-dir=/tmp
        - --secure-port=4443
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        - --kubelet-use-node-status-port
        - --metric-resolution=15s
        # 🚨 개발환경용 설정 (프로덕션에서는 제거)
        - --kubelet-insecure-tls
        ports:
        - containerPort: 4443
          name: https
          protocol: TCP
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - ALL
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 1000
          seccompProfile:
            type: RuntimeDefault
        volumeMounts:
        - mountPath: /tmp
          name: tmp-dir
      volumes:
      - emptyDir: {}
        name: tmp-dir
---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  ports:
  - name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    k8s-app: metrics-server

⚙️ 설치 확인 및 검증

# 📋 메트릭서버 파드 상태 확인
kubectl get pods -n kube-system | grep metrics-server
 
# 📊 메트릭 API 동작 확인
kubectl top nodes
kubectl top pods
 
# 🔍 메트릭서버 로그 확인
kubectl logs -n kube-system deployment/metrics-server

흔한 설치 오류

  • TLS 인증서 오류: --kubelet-insecure-tls 옵션 추가
  • 노드 주소 해결 오류: --kubelet-preferred-address-types 설정
  • 리소스 부족: 메모리 100Mi, CPU 100m 최소 필요

3. HPA 개념과 작동원리

HPA (Horizontal Pod Autoscaler)란?

메트릭 기반으로 파드 개수를 자동으로 조정하는 쿠버네티스 오토스케일링 메커니즘

🎯 HPA 작동 원리

📋 HPA 동작 프로세스

HPA 스케일링 시나리오

  1. 메트릭 수집: metrics-server에서 현재 리소스 사용량 조회
  2. 타겟 계산: 설정된 목표값과 현재값 비교
  3. 스케일링 결정: 필요한 파드 수 계산
  4. 파드 조정: Deployment/ReplicaSet 업데이트
  5. 대기: cooldown 기간 후 다시 평가

💻 HPA 계산 공식

# 📊 HPA 스케일링 계산
desiredReplicas = ceil[currentReplicas * (currentMetricValue / desiredMetricValue)]
 
# 예시: 현재 CPU 사용률이 80%, 목표가 50%인 경우
# desiredReplicas = ceil[3 * (80% / 50%)] = ceil[3 * 1.6] = 5개

📊 HPA vs VPA 비교

항목HPAVPA
스케일링 방향수평 (파드 수 증가)수직 (리소스 할당 증가)
적용 대상Stateless 앱Stateful 앱
메트릭 유형CPU, 메모리, 커스텀CPU, 메모리
응답 속도빠름 (파드 추가)느림 (재시작 필요)
사용 사례웹서버, API데이터베이스, 캐시

4. HPA 실전 구현

💻 기본 HPA 설정

1단계: 테스트 앱 배포

# 📦 hpa-test-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hpa-test-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hpa-test-app
  template:
    metadata:
      labels:
        app: hpa-test-app
    spec:
      containers:
      - name: app
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: hpa-test-service
spec:
  selector:
    app: hpa-test-app
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP

2단계: HPA 생성

# 📊 hpa-config.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: hpa-test-app
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: hpa-test-app
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 70
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 60
      policies:
      - type: Percent
        value: 100
        periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 50
        periodSeconds: 60

3단계: HPA 배포 및 확인

# 📦 앱과 HPA 배포
kubectl apply -f hpa-test-app.yaml
kubectl apply -f hpa-config.yaml
 
# 📊 HPA 상태 확인
kubectl get hpa
kubectl describe hpa hpa-test-app
 
# 🔍 실시간 모니터링
watch kubectl get hpa,pods

🔥 부하 테스트로 HPA 동작 확인

# 📊 부하 생성 파드 실행
kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh
 
# 부하 테스트 스크립트
while true; do
  wget -q -O- http://hpa-test-service/
done

HPA 모니터링 명령어

# HPA 이벤트 확인
kubectl describe hpa hpa-test-app
 
# 메트릭 직접 조회
kubectl top pods -l app=hpa-test-app
 
# HPA 동작 로그
kubectl get events --sort-by=.metadata.creationTimestamp

5. 고급 HPA 설정

🚀 커스텀 메트릭 기반 HPA

Prometheus 메트릭 사용

# 📊 custom-metrics-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: custom-metrics-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app
  minReplicas: 2
  maxReplicas: 20
  metrics:
  # 📈 HTTP 요청 수 기반 스케일링
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: "10"
  # 📊 큐 길이 기반 스케일링
  - type: Object
    object:
      metric:
        name: queue_length
      describedObject:
        apiVersion: v1
        kind: Service
        name: redis-queue
      target:
        type: Value
        value: "30"

⚙️ 고급 스케일링 정책

# 📊 advanced-scaling-behavior.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: advanced-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app
  minReplicas: 3
  maxReplicas: 100
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 60
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 120  # 2분 안정화
      policies:
      - type: Percent
        value: 50    # 50% 증가
        periodSeconds: 60
      - type: Pods
        value: 5     # 최대 5개씩 증가
        periodSeconds: 60
      selectPolicy: Min  # 더 보수적인 정책 선택
    scaleDown:
      stabilizationWindowSeconds: 600  # 10분 안정화
      policies:
      - type: Percent
        value: 25    # 25% 감소
        periodSeconds: 120
      - type: Pods
        value: 2     # 최대 2개씩 감소
        periodSeconds: 120
      selectPolicy: Max  # 더 보수적인 정책 선택

6. 트러블슈팅 및 모니터링

🚨 주요 문제와 해결방법

문제 1: HPA가 스케일링하지 않음

일반적인 원인

  1. 메트릭서버 미설치: kubectl get apiservice v1beta1.metrics.k8s.io
  2. 리소스 요청 미설정: requests 설정 필수
  3. 메트릭 수집 실패: 파드 상태 확인
# 🔍 진단 명령어
kubectl get hpa -o yaml
kubectl describe hpa [HPA_NAME]
kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes
kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods

문제 2: 메트릭서버 인증 오류

# 🔧 해결 방법: TLS 무시 설정
args:
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP

문제 3: 과도한 스케일링 (Thrashing)

해결 방안

  • 안정화 윈도우 증가: stabilizationWindowSeconds 조정
  • 스케일링 정책 조정: behavior 섹션 세밀 설정
  • 메트릭 평균화: 더 긴 기간 평균값 사용

📊 모니터링 대시보드 설정

Grafana 대시보드 쿼리

# HPA 현재 레플리카 수
kube_horizontalpodautoscaler_status_current_replicas
 
# HPA 목표 레플리카 수  
kube_horizontalpodautoscaler_status_desired_replicas
 
# CPU 사용률
rate(container_cpu_usage_seconds_total[5m]) * 100
 
# 메모리 사용률
container_memory_working_set_bytes / container_spec_memory_limit_bytes * 100

🔧 유용한 모니터링 스크립트

#!/bin/bash
# 📊 hpa-monitor.sh - HPA 상태 모니터링 스크립트
 
echo "=== HPA 전체 상태 ==="
kubectl get hpa
 
echo "=== 메트릭서버 상태 ==="
kubectl get pods -n kube-system -l k8s-app=metrics-server
 
echo "=== 노드 리소스 사용률 ==="
kubectl top nodes
 
echo "=== HPA 이벤트 (최근 10개) ==="
kubectl get events --field-selector involvedObject.kind=HorizontalPodAutoscaler --sort-by=.metadata.creationTimestamp | tail -10
 
# 특정 HPA 상세 모니터링
if [ ! -z "$1" ]; then
    echo "=== $1 HPA 상세 정보 ==="
    kubectl describe hpa $1
    
    echo "=== $1 타겟 파드 리소스 사용률 ==="
    APP_LABEL=$(kubectl get hpa $1 -o jsonpath='{.spec.scaleTargetRef.name}')
    kubectl top pods -l app=$APP_LABEL
fi

🎯 실전 베스트 프랙티스

✅ HPA 설계 권장사항

  1. 리소스 요청 설정 필수

    resources:
      requests:
        cpu: 100m      # HPA 동작을 위해 반드시 설정
        memory: 128Mi
  2. 적절한 스케일링 범위 설정

    minReplicas: 2    # 가용성 보장
    maxReplicas: 50   # 비용 통제
  3. 안정화 기간 조정

    behavior:
      scaleUp:
        stabilizationWindowSeconds: 60    # 빠른 확장
      scaleDown:
        stabilizationWindowSeconds: 300   # 보수적 축소

🚀 프로덕션 환경 권장 설정

# 📊 production-hpa-template.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: production-app-hpa
  labels:
    environment: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: production-app
  minReplicas: 3      # 고가용성
  maxReplicas: 100    # 충분한 확장성
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70  # 보수적 임계값
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 120
      policies:
      - type: Percent
        value: 100    # 최대 100% 증가
        periodSeconds: 60
      - type: Pods
        value: 10     # 최대 10개까지
        periodSeconds: 60
      selectPolicy: Min
    scaleDown:
      stabilizationWindowSeconds: 600   # 10분 대기
      policies:
      - type: Percent
        value: 10     # 천천히 감소
        periodSeconds: 120
      selectPolicy: Min

마무리 체크리스트

  • ✅ 메트릭서버 정상 설치 확인
  • ✅ HPA 대상 앱에 리소스 요청 설정
  • ✅ 적절한 스케일링 정책 구성
  • ✅ 모니터링 및 알람 설정
  • ✅ 부하 테스트로 동작 검증

📚 관련 문서

🔗 참고 링크