🎯 k8s실습 9-3: 메트릭서버와 HPA 완전 정복 가이드
📑 목차
1. 메트릭서버 개념과 아키텍처
메트릭서버란?
쿠버네티스 클러스터의 리소스 사용량(CPU, 메모리)을 수집하고 API 서버를 통해 제공하는 핵심 컴포넌트
💡 메트릭서버의 역할
🤔 질문: “왜 메트릭서버가 필요한가?”
📋 메트릭서버가 해결하는 문제들
실제 상황
- 문제:
kubectl top pods명령어 사용 불가- 감지: “error: Metrics API not available” 에러
- 조치: 메트릭서버 설치
- 결과: 리소스 모니터링 및 HPA 동작 가능
🏗️ 메트릭서버 아키텍처
# 📊 메트릭서버 아키텍처 구조
Components:
kubelet: 노드 리소스 수집
metrics-server: 메트릭 집계 및 API 제공
api-server: Metrics API 엔드포인트
HPA Controller: 메트릭 기반 스케일링 결정📊 메트릭 데이터 흐름
| 단계 | 컴포넌트 | 역할 | 데이터 |
|---|---|---|---|
| 1 | kubelet | 노드/파드 메트릭 수집 | CPU, 메모리 사용량 |
| 2 | metrics-server | 메트릭 집계 | 표준화된 메트릭 |
| 3 | API Server | Metrics API 제공 | /apis/metrics.k8s.io/ |
| 4 | kubectl/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 스케일링 시나리오
- 메트릭 수집: metrics-server에서 현재 리소스 사용량 조회
- 타겟 계산: 설정된 목표값과 현재값 비교
- 스케일링 결정: 필요한 파드 수 계산
- 파드 조정: Deployment/ReplicaSet 업데이트
- 대기: cooldown 기간 후 다시 평가
💻 HPA 계산 공식
# 📊 HPA 스케일링 계산
desiredReplicas = ceil[currentReplicas * (currentMetricValue / desiredMetricValue)]
# 예시: 현재 CPU 사용률이 80%, 목표가 50%인 경우
# desiredReplicas = ceil[3 * (80% / 50%)] = ceil[3 * 1.6] = 5개📊 HPA vs VPA 비교
| 항목 | HPA | VPA |
|---|---|---|
| 스케일링 방향 | 수평 (파드 수 증가) | 수직 (리소스 할당 증가) |
| 적용 대상 | 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: ClusterIP2단계: 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: 603단계: 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/
doneHPA 모니터링 명령어
# 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가 스케일링하지 않음
일반적인 원인
- 메트릭서버 미설치:
kubectl get apiservice v1beta1.metrics.k8s.io- 리소스 요청 미설정: requests 설정 필수
- 메트릭 수집 실패: 파드 상태 확인
# 🔍 진단 명령어
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 설계 권장사항
-
리소스 요청 설정 필수
resources: requests: cpu: 100m # HPA 동작을 위해 반드시 설정 memory: 128Mi -
적절한 스케일링 범위 설정
minReplicas: 2 # 가용성 보장 maxReplicas: 50 # 비용 통제 -
안정화 기간 조정
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 대상 앱에 리소스 요청 설정
- ✅ 적절한 스케일링 정책 구성
- ✅ 모니터링 및 알람 설정
- ✅ 부하 테스트로 동작 검증
📚 관련 문서
🔗 참고 링크