[Kubernetes] Kubernetes Pod 간 Connection reset 오류, 원인과 해결 방법

2025. 7. 13. 00:39·개발 (Development)/Kubernetes

문제 상황

내부에서 운영 중인 두 개의 API Pod A와 B가 있습니다. Pod A는 Pod B의 특정 API를 호출하여 인증 등의 기능을 위임하고 있으며, 이들은 Kubernetes 클러스터 내에서 서비스 이름을 기반으로 통신하고 있습니다.

문제는 간헐적으로 다음과 같은 예외가 발생한다는 점이었습니다.

java.net.SocketException: Connection reset

특정 시점에서 API 호출이 실패하고, 호출하는 쪽에서 위와 같은 오류가 발생했습니다. Pod B를 재시작하면 문제가 일시적으로 해결되었지만, 원인을 명확히 파악하지 못해 대응이 어려운 상황이었습니다.

원인 분석

에러 메시지와 인프라 구조를 바탕으로 다음과 같은 가능성을 검토하였습니다.

1. 애플리케이션이 응답하지 않는 상태

Pod 내부에서 실행 중인 애플리케이션이 GC 지연, 스레드 풀 고갈, 내부 오류 등으로 인해 외부 요청에 응답하지 못할 수 있습니다. 이 경우 포트는 열려 있어도 연결이 끊기는 현상이 발생할 수 있습니다.

2. Pod 간 네트워크 불안정

Kubernetes 환경에서는 서비스 이름(A.namespace.svc.cluster.local)을 통해 다른 Pod에 접근하게 됩니다. 이때 내부 DNS 서버(CoreDNS 등)가 해당 이름을 IP로 해석해주며, 이 DNS 해석 과정이 실패하거나 캐시가 꼬이면 연결이 실패할 수 있습니다.

3. 대상 Pod가 비정상 상태인데도 트래픽을 계속 받는 경우

Pod 내부 애플리케이션이 비정상 상태에 빠졌지만 Kubernetes가 이를 인지하지 못하고, 서비스 엔드포인트에서 제거되지 않으면 여전히 트래픽을 받게 됩니다. 이 경우 연결 시도가 계속 실패할 수 있습니다. 특히 readiness 또는 liveness probe가 설정되어 있지 않다면 이러한 상태를 Kubernetes가 감지하지 못합니다.

해결 방안

문제를 해결하기 위해 다음과 같은 접근을 진행하였습니다.

1. Liveness 및 Readiness Probe 설정

애플리케이션 이미지를 수정할 수 없는 상황이었기 때문에 HTTP 기반 헬스 체크는 불가능했고, 대신 TCP 소켓 기반의 probe를 Pod 정의에 설정하였습니다. 아래는 예시입니다.

livenessProbe:
  tcpSocket:
    port: NNNN
  initialDelaySeconds: 30
  periodSeconds: 10
  timeoutSeconds: 2
  failureThreshold: 3

readinessProbe:
  tcpSocket:
    port: NNNN
  initialDelaySeconds: 5
  periodSeconds: 5
  timeoutSeconds: 2
  failureThreshold: 2
  • livenessProbe는 애플리케이션이 더 이상 작동하지 않는 경우 Kubernetes가 해당 Pod를 재시작하도록 합니다.
  • readinessProbe는 애플리케이션이 정상적으로 요청을 받을 준비가 되었는지를 판단하여, 실패 시 해당 Pod는 서비스에서 제외되어 트래픽을 받지 않게 됩니다.

2. HTTP 클라이언트 타임아웃 및 재시도 설정

통신 요청에 대한 응답이 지연되거나 실패하는 상황에 대비하여, HTTP 클라이언트(RestTemplate 등)에 타임아웃과 재시도 설정을 적용하였습니다.

HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setConnectTimeout(3000);
factory.setReadTimeout(3000);
RestTemplate restTemplate = new RestTemplate(factory);

일시적인 네트워크 장애에도 견딜 수 있도록 구성하였습니다.

3. CoreDNS 및 내부 DNS 상태 점검

DNS 해석 문제가 의심되는 상황이었기 때문에, 다음과 같은 명령어를 통해 내부 DNS 상태를 점검하였습니다.

kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl exec -it <pod-name> -- nslookup <service-name>

CoreDNS Pod의 상태가 정상인지 확인하고, 서비스 이름이 올바르게 해석되는지를 검증하였습니다.

핵심 요약

항목 설명
애플리케이션 hang GC 정체, 스레드 고갈 등으로 인해 요청에 응답하지 못하는 상황
DNS 문제 내부 서비스 이름이 IP로 제대로 해석되지 않아 통신 실패 발생 가능
네트워크 장애 일시적인 연결 실패 또는 클러스터 내부 네트워크의 불안정
probe 미설정 Kubernetes가 비정상 Pod를 감지하지 못하고 계속 트래픽 전달
대응 방안 설명
Liveness/Readiness Probe 설정 Pod의 상태를 자동 감지하고 복구 또는 요청 중단 가능
HTTP 클라이언트 타임아웃 및 재시도 일시적인 실패에도 견디는 통신 로직 구현
CoreDNS 점검 서비스 이름이 올바르게 해석되는지 확인하고 문제 감지

마무리하며

Kubernetes 환경에서는 여러 Pod들이 서로 통신하며 작동하는 구조이기 때문에, 네트워크 연결 오류나 DNS 이슈가 간헐적으로 발생할 수 있습니다. 이를 예방하고 자동으로 복구할 수 있도록 liveness/readiness probe 설정, HTTP 통신의 안정성 확보, 내부 DNS 시스템 점검 등의 노력을 병행하는 것이 중요합니다.

이번 사례를 통해, 애플리케이션 코드 차원의 문제뿐만 아니라 인프라 레벨에서의 견고한 설계가 운영 안정성 확보에 얼마나 중요한지 다시금 확인할 수 있었습니다.

반응형

'개발 (Development) > Kubernetes' 카테고리의 다른 글

[Kubernetes] Kubernetes에서 컨테이너와 파드는 무엇이 다를까?  (0) 2025.07.13
[Kubernetes] Kubernetes 클러스터 구조 확인 방법  (0) 2025.04.06
[Kubernetes] Kubernetes에서 Pod 간 직접 데이터 전송하는 방법  (0) 2025.04.05
'개발 (Development)/Kubernetes' 카테고리의 다른 글
  • [Kubernetes] Kubernetes에서 컨테이너와 파드는 무엇이 다를까?
  • [Kubernetes] Kubernetes 클러스터 구조 확인 방법
  • [Kubernetes] Kubernetes에서 Pod 간 직접 데이터 전송하는 방법
LoopThinker
LoopThinker
모르는 것을 알아가고, 아는 것을 더 깊게 파고드는 공간
  • LoopThinker
    CodeMemoir
    LoopThinker
  • 전체
    오늘
    어제
    • 분류 전체보기 (231)
      • 개발 (Development) (165)
        • Algorithm (1)
        • Angular (1)
        • AWS (6)
        • DeepSeek (2)
        • Docker (7)
        • Git (3)
        • Java (34)
        • JavaScript (4)
        • Kafka (5)
        • Kubernetes (4)
        • Linux (7)
        • PostgreSQL (38)
        • Python (31)
        • React (3)
        • TypeScript (3)
        • Vue.js (5)
        • General (11)
      • 데이터 분석 (Data Analysis) (1)
      • 알고리즘 문제 풀이 (Problem Solving.. (27)
      • 자격증 (Certifications) (24)
        • ADsP (14)
        • 정보처리기사 (4)
        • Linux Master (5)
        • SQLD (1)
      • 기술 동향 (Tech Trends) (11)
      • 기타 (Others) (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백준알고리즘
    자바
    오답노트
    docker
    JPA
    JSON
    백준
    pandas
    Kubernetes
    Linux master
    python
    백준온라인저지
    timescaledb
    springboot
    java
    Linux
    리눅스 마스터 2급
    데이터분석
    MyBatis
    Kafka
    Vue.js
    javascript
    AWS
    DevOps
    PostgreSQL
    ADsP
    deepseek
    리눅스 마스터 2급 2차
    Spring boot
    백준자바
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
LoopThinker
[Kubernetes] Kubernetes Pod 간 Connection reset 오류, 원인과 해결 방법
상단으로

티스토리툴바