-
Kubernetes Metrics Server 설치 시 발생하는 i/o timeout 및 포트 충돌 해결BACKEND/K8s 2025. 12. 16. 20:50반응형
1. 배경 및 문제 상황
쿠버네티스 클러스터 모니터링과 HPA(Horizontal Pod Autoscaler) 구성을 위해 Metrics Server를 설치하던 중, Pod가 정상적으로 뜨지 않고 CrashLoopBackOff 상태를 반복하는 문제가 발생했습니다.
로그를 확인해보니 두 가지 주요 에러가 연달아 나타났습니다.
1. API 서버 통신 타임아웃
처음에는 Metrics Server가 API 서버에 접근하지 못하는 네트워크 에러가 발생했습니다.
Error: unable to load configmap based request-header-client-ca-file: Get "https://10.96.0.1:443/...": dial tcp 10.96.0.1:443: i/o timeout2. 포트 충돌 (Address already in use)
네트워크 문제를 해결하려고 hostNetwork: true를 적용했더니, 이번엔 포트 충돌 에러가 발생했습니다.
panic: failed to create listener: failed to listen on 0.0.0.0:10250: listen tcp 0.0.0.0:10250: bind: address already in use
2. 원인 분석
1) i/o timeout의 원인
- CNI(Overlay Network) 설정 문제 등으로 인해 Metrics Server Pod가 내부 DNS나 Cluster IP를 통해 API 서버(Control Plane)와 통신하지 못하는 상태였습니다.
- 파드가 노드(Host)의 네트워크 인터페이스를 직접 사용하도록 hostNetwork: true 설정이 필요했습니다.
2) address already in use의 원인
- hostNetwork: true를 적용하면 파드가 노드의 IP와 포트를 공유하게 됩니다.
- 기본적으로 Metrics Server는 10250 포트를 사용하도록 설정되어 있는데, 이 포트는 이미 노드의 Kubelet이 점유하고 있는 포트입니다.
- Metrics Server가 사용하는 포트를 비어있는 포트(예: 4443)로 변경해야 합니다.
3) 인증서 검증
- 사설/테스트 클러스터 환경에서는 Kubelet 인증서가 공인되지 않은 경우가 많아 연결이 거부될 수 있습니다.
- --kubelet-insecure-tls 옵션을 추가하여 검증을 우회해야 합니다.
3. 해결 과정 (YAML 수정)
Deployment 설정을 수정하여 위 세 가지 문제를 해결했습니다.
kubectl edit deployment metrics-server -n kube-system- hostNetwork: true 추가: API 서버 통신 문제 해결
- --secure-port=4443 변경: Kubelet(10250)과의 충돌 방지
- --kubelet-insecure-tls 추가: 인증서 에러 방지
- ports 및 probes 포트 동기화: 컨테이너 포트와 상태 체크(Liveness/Readiness) 포트를 모두 4443으로 변경
최종 적용된 YAML (spec 부분):
spec: template: spec: hostNetwork: true # [1] 호스트 네트워크 사용 containers: - args: - --cert-dir=/tmp - --secure-port=4443 # [2] 포트 충돌 회피 (10250 -> 4443) - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --kubelet-use-node-status-port - --metric-resolution=15s - --kubelet-insecure-tls # [3] TLS 검증 무시 image: registry.k8s.io/metrics-server/metrics-server:v0.8.0 # ... (중략) ... livenessProbe: httpGet: path: /livez port: 4443 # Probe 포트도 4443으로 맞춰줘야 함 scheme: HTTPS # ... (중략) ... ports: - containerPort: 4443 # 컨테이너 오픈 포트 변경 name: https protocol: TCP readinessProbe: httpGet: path: /readyz port: 4443 # Probe 포트 변경 scheme: HTTPS
4. 결과 확인
설정 적용 후 Pod가 정상적으로 Running 상태가 되었으며, Node와 Pod의 리소스 사용량이 정상적으로 조회되는 것을 확인했습니다.
Pod 상태 확인
$ kubectl get pods -n kube-system -l k8s-app=metrics-server NAME READY STATUS RESTARTS AGE metrics-server-7546d479dd-74p5q 1/1 Running 0 5m리소스 조회
$ kubectl top nodes NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% k8s-master 120m 6% 1500Mi 18%이제 kubectl top 명령어 사용과 HPA 설정이 가능해졌습니다.
반응형