- Published on
EKS에서 HPA가 안 늘어날 때 Metrics 오류 해결
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
서버 부하가 올라가는데도 EKS에서 HPA(Horizontal Pod Autoscaler)가 꿈쩍하지 않는 상황은 대부분 “스케일링 로직이 틀려서”가 아니라 “메트릭을 못 읽어서” 발생합니다. 특히 EKS에서는 Metrics Server, kubelet 인증/통신, API aggregation, (커스텀 메트릭이면) Prometheus Adapter까지 파이프라인이 길어서 한 군데만 삐끗해도 HPA가 Unknown 상태로 멈춥니다.
이 글은 HPA가 안 늘어날 때 흔히 보이는 Metrics 관련 오류 메시지를 기준으로, 원인-진단-해결을 빠르게 따라갈 수 있게 구성했습니다.
> 참고로 EKS에서 네트워크/IRSA 이슈가 함께 얽히는 경우도 많습니다. 예: DNS/통신 문제가 전반적으로 발생한다면 EKS TLS handshake timeout 해결 - IRSA·VPC·CoreDNS도 같이 점검하세요.
1) 증상부터 확인: HPA 이벤트/상태가 말해주는 것
먼저 “정말 메트릭 문제인지”를 HPA 상태에서 확인합니다.
kubectl -n <ns> describe hpa <hpa-name>
여기서 자주 보이는 신호:
Current CPU utilization: <unknown>failed to get cpu utilization: unable to get metrics for resource cputhe server could not find the requested resource (get pods.metrics.k8s.io)unable to fetch metrics from resource metrics APImissing request for cpu(리소스 request 미설정)
또한 Metrics API 자체가 살아있는지 확인합니다.
kubectl get apiservices | grep -E 'metrics.k8s.io|custom.metrics.k8s.io|external.metrics.k8s.io'
정상이라면 v1beta1.metrics.k8s.io가 Available=True로 보여야 합니다.
그리고 실제 메트릭 조회가 되는지:
kubectl top nodes
kubectl top pods -n <ns>
여기서 error: Metrics API not available가 뜨면 HPA는 사실상 멈춰 있다고 봐도 됩니다.
2) 가장 흔한 원인 1: Metrics Server 미설치/비정상
EKS는 기본적으로 Metrics Server가 “항상 자동 설치”되는 형태가 아닙니다(클러스터/애드온 구성에 따라 다름). kubectl top이 안 되면 Metrics Server부터 봅니다.
2-1) 설치 여부 확인
kubectl -n kube-system get deploy,po | grep -i metrics-server
- Deployment/Pod가 없다면 설치가 필요합니다.
2-2) (권장) EKS Add-on으로 설치/업데이트
운영에서는 매니페스트 직접 적용보다 EKS Add-on이 관리가 편합니다.
aws eks describe-addon-versions --addon-name metrics-server --kubernetes-version <k8s-version>
aws eks create-addon \
--cluster-name <cluster> \
--addon-name metrics-server \
--resolve-conflicts OVERWRITE
이미 설치돼 있다면 업데이트:
aws eks update-addon \
--cluster-name <cluster> \
--addon-name metrics-server \
--resolve-conflicts OVERWRITE
2-3) 로그로 “왜 수집이 안 되는지” 확인
kubectl -n kube-system logs deploy/metrics-server --tail=200
자주 보는 에러 패턴:
x509: certificate signed by unknown authoritycontext deadline exceededno metrics to serveunable to fully scrape metrics
이제부터는 케이스별로 해결합니다.
3) 가장 흔한 원인 2: kubelet TLS/인증 문제 (x509, unauthorized)
EKS에서 Metrics Server는 각 노드의 **kubelet(10250 포트)**에 붙어서 요약 메트릭을 가져옵니다. 여기서 인증서/인증 문제가 나면 kubectl top도, HPA도 모두 죽습니다.
3-1) 대표 증상
- Metrics Server 로그:
x509: certificate signed by unknown authority - 또는
Forbidden (user=system:serviceaccount:kube-system:metrics-server, verb=get, resource=nodes/stats)같은 RBAC 오류
3-2) 빠른 우회(권장 X): --kubelet-insecure-tls
보안적으로는 권장하지 않지만, 원인 분리가 급할 때 임시로 적용해 “TLS 문제인지” 확인할 수 있습니다.
kubectl -n kube-system patch deploy metrics-server \
--type='json' \
-p='[
{
"op": "add",
"path": "/spec/template/spec/containers/0/args/-",
"value": "--kubelet-insecure-tls"
}
]'
이후 kubectl top nodes가 살아나면, kubelet 인증서 체인/통신 경로 문제일 가능성이 큽니다.
3-3) 정석 접근: kubelet 접근/권한/통신 경로 점검
- Metrics Server가 노드로 라우팅 가능한지(보안그룹/네트워크 정책)
- API aggregation이 정상인지
- RBAC이 기본 제공 설정대로 적용됐는지
RBAC은 보통 Metrics Server 설치 시 함께 들어가지만, 커스텀으로 만지다 깨지는 경우가 있습니다.
kubectl get clusterrole system:aggregated-metrics-reader -o yaml
kubectl get clusterrolebinding | grep -i metrics
또한 EKS에서 전반적인 권한/인증 문제가 의심되면, 원인별로 정리된 Kubernetes 401 Unauthorized 원인별 해결 가이드 체크리스트대로 “누가/어디에” 인증 실패가 나는지 분리하는 게 빠릅니다.
4) 가장 흔한 원인 3: Metrics API Aggregation(apiserver) 문제
kubectl get --raw "/apis/metrics.k8s.io/v1beta1"가 실패하거나, apiservices에서 Available=False라면 aggregation 계층 문제입니다.
4-1) 상태 확인
kubectl get apiservice v1beta1.metrics.k8s.io -o yaml
여기서 status.conditions[].message에 원인이 드러납니다.
failing or missing response from ...x509관련timeout관련
4-2) 서비스/엔드포인트 확인
kubectl -n kube-system get svc,ep | grep -i metrics-server
- Endpoint가 비어 있으면 Pod readiness 문제이거나 selector가 안 맞는 것입니다.
5) HPA가 CPU 기준인데도 안 늘어나는 “설정” 문제: requests 미설정
메트릭 파이프라인이 정상인데도 HPA가 스케일링을 못 하는 가장 흔한 설정 실수는 컨테이너 리소스 requests 미설정입니다.
CPU utilization 기반 HPA는 usage / request로 계산합니다. request가 없으면 계산할 수 없어서 이벤트에 다음이 뜹니다.
missing request for cpu
5-1) Deployment에 requests 추가 예시
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 2
template:
spec:
containers:
- name: api
image: nginx:1.27
resources:
requests:
cpu: "200m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
5-2) HPA 예시 (CPU 60% 타겟)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
적용 후 확인:
kubectl apply -f deploy.yaml
kubectl apply -f hpa.yaml
kubectl describe hpa api-hpa
6) 커스텀/외부 메트릭(HPA v2)일 때: Prometheus Adapter 계열 오류
CPU/메모리 리소스 메트릭이 아니라 QPS, latency, queue length 같은 지표로 HPA를 돌리면 보통 다음 중 하나를 씁니다.
custom.metrics.k8s.io(파드/네임스페이스 등 Kubernetes 객체에 붙는 메트릭)external.metrics.k8s.io(클러스터 외부/논리적 지표)
이때는 Metrics Server가 아니라 **Prometheus Adapter(또는 KEDA 등)**가 핵심입니다.
6-1) APIService 확인
kubectl get apiservices | grep -E 'custom.metrics.k8s.io|external.metrics.k8s.io'
Available=False면 adapter가 죽었거나 aggregation이 깨진 것입니다.
6-2) HPA 이벤트에서 힌트 찾기
kubectl -n <ns> describe hpa <hpa-name>
자주 보이는 메시지:
unable to get external metric ... no metrics returned from external metrics APIthe server is currently unable to handle the request (get ...)
이 경우 adapter의 로그/서비스/엔드포인트를 확인하고, Prometheus 쿼리 자체가 데이터가 있는지부터 검증하세요.
7) 네트워크/DNS로 인해 Metrics Server가 노드에 못 붙는 경우
EKS에서는 보안그룹, NACL, CNI 설정, DNS(CoreDNS) 문제로 내부 통신이 간헐적으로 실패하며 Metrics 수집이 타임아웃 나는 경우가 있습니다.
7-1) 증상
- metrics-server 로그:
context deadline exceeded - apiservice message:
timeout/no response
7-2) 빠른 확인 포인트
- 노드 보안그룹에서 노드 간 통신(특히 10250) 경로가 막혀 있지 않은지
- CoreDNS 장애로 서비스 디스커버리가 흔들리지 않는지
EKS에서 DNS/네트워크가 엮인 증상은 겉으로는 “메트릭이 안 보임”으로만 나타나기도 합니다. 클러스터 전반의 TLS/DNS 증상이 함께 있다면 EKS TLS handshake timeout 해결 - IRSA·VPC·CoreDNS에서 제시한 CoreDNS/IRSA/VPC 점검 루틴을 같이 수행하는 게 좋습니다.
8) 실전 10분 진단 체크리스트
장애 상황에서 순서대로 실행하면 원인 범위를 빠르게 줄일 수 있습니다.
8-1) HPA 자체 상태
kubectl -n <ns> describe hpa <hpa>
Unknown/failed to get metrics면 메트릭 파이프라인 문제missing request for cpu면 리소스 설정 문제
8-2) Metrics API 확인
kubectl top nodes
kubectl get apiservice v1beta1.metrics.k8s.io
kubectl get --raw "/apis/metrics.k8s.io/v1beta1" | head
8-3) Metrics Server 상태/로그
kubectl -n kube-system get deploy metrics-server
kubectl -n kube-system logs deploy/metrics-server --tail=200
kubectl -n kube-system get svc,ep | grep -i metrics-server
8-4) 커스텀/외부 메트릭을 쓰는 HPA라면
kubectl get apiservices | grep -E 'custom.metrics|external.metrics'
9) 마무리: “HPA가 안 늘어남”은 대부분 관측 파이프라인 장애다
EKS에서 HPA 스케일아웃이 멈추는 이슈는 대개 다음 3가지로 귀결됩니다.
- Metrics Server/metrics.k8s.io가 죽었거나 aggregation이 실패
- kubelet TLS/권한/통신 문제로 스크래핑 불가
- CPU utilization 기반인데 requests 미설정
이 글의 커맨드들로 kubectl top이 정상화되면 HPA는 대부분 자동으로 회복됩니다. 만약 메트릭은 정상인데도 스케일이 안 된다면, 그때는 HPA의 behavior(stabilizationWindowSeconds), maxReplicas, 그리고 실제 부하가 request 대비 얼마나 올라가는지(타겟 계산)까지 들어가서 튜닝하면 됩니다.
추가로, EKS에서 특정 Pod만 외부 통신이 꼬이거나(예: NAT/WAF) 클러스터 내부 네트워크가 흔들리면 메트릭 수집도 연쇄로 깨질 수 있습니다. 그런 케이스는 EKS Pod만 외부 API 403 - NAT IP·WAF로 해결처럼 “네트워크 경계”부터 분리 진단하는 접근이 도움이 됩니다.