ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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 timeout
    

    2. 포트 충돌 (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
    

     

     

    1. hostNetwork: true 추가: API 서버 통신 문제 해결
    2. --secure-port=4443 변경: Kubelet(10250)과의 충돌 방지
    3. --kubelet-insecure-tls 추가: 인증서 에러 방지
    4. 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 설정이 가능해졌습니다.

    반응형

    댓글

Designed by black7375.