LabHub

볼륨·네트워크·컴포즈 · 헬스체크와 재시작 정책 · 이론

컨테이너는 살아 있는데 서비스는 죽어 있다

LabHub 에서 이어서 보기

한 줄 요약

프로세스가 살아 있다는 것과 요청을 처리할 수 있다는 것은 다른 사실입니다.
헬스체크는 그 둘 사이의 간격을 메우고, 재시작 정책은 실패했을 때
무엇을 할지 정합니다.

왜 이게 필요했나

docker psUp 3 hours 라고 나옵니다. 그런데 사용자는 500 을 받고
있습니다. 프로세스는 살아 있지만 DB 커넥션 풀이 고갈됐거나, 스레드가
데드락이거나, 디스크가 차서 쓰기를 못 하는 상태입니다.

도커가 아는 것은 PID 1 이 아직 안 죽었다는 사실 하나뿐입니다. 그것만으로
"서비스 중"이라고 판단하면 장애를 몇 시간씩 놓칩니다.

어떻게 동작하나

HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \  CMD curl -fsS http://localhost:8080/healthz || exit 1

| 옵션 | 뜻 | 잘못 잡으면 |
| --- | --- | --- |
| interval | 검사 주기 | 너무 짧으면 부하, 길면 감지가 늦다 |
| timeout | 한 번의 검사 제한 시간 | 너무 짧으면 정상인데 실패 판정 |
| start-period | 기동 유예 — 이 구간의 실패는 재시도로 안 침 | 없으면 느리게 뜨는 앱이 계속 죽는다 |
| retries | 연속 실패 허용 횟수 | 1이면 순간적인 지연에도 unhealthy |

상태는 startinghealthy / unhealthy 로 움직입니다.
docker inspect --format '{{.State.Health.Status}}' 로 볼 수 있습니다.

중요한 함정: 도커 단독으로는 unhealthy 가 되어도 **컨테이너를 재시작하지
않습니다.** 상태를 표시할 뿐입니다. 재시작은 오케스트레이터(Compose 의
depends_on: condition: service_healthy, 스웜, 쿠버네티스의 liveness probe)가
합니다. 헬스체크를 넣었으니 알아서 살아나겠지 — 라고 믿으면 안 됩니다.

헬스체크 엔드포인트를 어떻게 쓸 것인가

/healthz 가 무조건 200 OK 만 돌려주면 아무것도 검사하지 않는 것과
같습니다. 반대로 DB·캐시·외부 API 를 전부 확인하면, 외부 API 하나가
흔들릴 때 우리 서비스가 통째로 unhealthy 가 됩니다.

경계는 이렇게 잡습니다.

이 구분을 안 하면 "DB 가 잠깐 느려졌다 → liveness 실패 → 재시작 → 커넥션 다시
맺느라 더 느려짐 → 또 실패" 라는 되먹임에 빠집니다. 실제로 자주 일어납니다.

재시작 정책

| 정책 | 동작 |
| --- | --- |
| no (기본) | 죽으면 그대로 둔다 |
| on-failure[:N] | 0 이 아닌 종료코드일 때만, 최대 N 번 |
| always | 항상 재시작. 데몬 재시작 시에도 다시 뜬다 |
| unless-stopped | always 와 같되, 사람이 stop 한 것은 그대로 둔다 |

always 는 무한 재시작 루프를 만들 수 있습니다. 설정 오류로 즉시 죽는
컨테이너가 초당 몇 번씩 재시작하며 로그를 채우는 상황이 대표적입니다.
도커는 재시작 간격을 점점 늘려(백오프) 완화하지만, 근본 해결은 아닙니다.

depends_on 은 순서만 보장한다

services:  app:    depends_on: [db]     # db 컨테이너가 '시작'된 뒤 app 을 시작할 뿐

db요청을 받을 준비가 됐는지는 보지 않습니다. PostgreSQL 은 프로세스가
뜨고 나서도 초기화에 몇 초가 더 걸립니다. 그 사이 앱이 접속하면 실패합니다.
condition: service_healthy 로 헬스체크와 묶어야 의미가 생깁니다.

현장에서 만나는 모습

다음 확인에서 볼 것

이어지는 퀴즈에서는 실행 중(running)과 정상(healthy)을 구분하고,
start-period·재시작 정책·Compose 의 헬스 조건을 어떤 장애에 적용해야 하는지
판단합니다. 앞 실습에서 만든 컨테이너의 상태 전이와 종료코드를 근거로 답해 보세요.