콘텐츠로 이동

컨테이너가 unhealthy로 표시되나 서비스는 정상

컨테이너 — 보통 프런트엔드 — 가 docker ps에서 unhealthy로 표시되는데도, 애플리케이션은 브라우저에서 정상적으로 도달하고 서비스됩니다. 서비스가 작동 중인데도 헬스 프로브는 “connection refused”를 로깅합니다.

원인: 프로브가 localhost를 대상으로 하는데, 이는 IPv6(::1)와 IPv4(127.0.0.1) 모두로 해석됩니다. 프로브 도구는 IPv6를 먼저 시도하지만, 컨테이너 내부의 서버는 IPv4에서만 수신 대기하므로 — IPv6 시도가 거부되고 프로브가 컨테이너를 다운으로 잘못 보고합니다.

컨테이너가 보고한 헬스 상태를 실제 도달 가능성과 비교해 확인하세요:

Terminal window
docker ps --format '{{.Names}}\t{{.Status}}' | grep aiboard

컨테이너가 (unhealthy)로 표시되는데 IPv4로 직접 접근했을 때 앱이 응답한다면, 이 거짓 음성입니다:

Terminal window
# 컨테이너 내부에서 — IPv4 명시
docker compose -f docker-compose.release.yml exec frontend \
sh -c 'wget -qO- http://127.0.0.1:8080/ >/dev/null && echo "IPv4 OK"'

IPv4 OK가 출력되면 서비스는 정상이고 프로브만 잘못된 것입니다.

현재 이미지는 이미 IPv4를 명시적으로 프로빙하므로 정상 박스에서는 이 문제가 발생하지 않습니다. 이전 이미지에서 이를 본다면:

  1. 서비스가 실제로 작동 중인지 확인하세요(위의 IPv4 검사가 IPv4 OK를 출력). 출력되면 애플리케이션 측 조치는 필요 없습니다 — 컨테이너는 정상입니다.

  2. 현재 릴리스 이미지로 업데이트하세요. 여기서는 헬스 프로브가 127.0.0.1을 직접 대상으로 하여 거짓 음성이 사라집니다:

    Terminal window
    docker compose -f docker-compose.release.yml up -d
  3. 상태가 해소되는지 다시 확인하세요:

    Terminal window
    docker ps --format '{{.Names}}\t{{.Status}}' | grep aiboard
  • 서버가 실제로 바인딩하는 주소를 프로빙하세요. 서버가 IPv4에서만 수신 대기할 때는 헬스 프로브가 127.0.0.1을 명시적으로 대상으로 해야, 이름 해석이 프로브를 바인딩되지 않은 IPv6 주소로 보내지 않습니다.
  • 프로브 실패와 서비스 실패를 구분하세요. unhealthy 상태에 반응하기 전에 직접 IPv4 요청으로 확인하세요. 빨간 프로브 뒤의 녹색 앱은 장애가 아니라 프로브 버그입니다.