컨테이너 용어 사전
런타임json-file · 로그 드라이버 · max-size

컨테이너 로그

stdout/stderr를 도커가 수집한다. 기본 드라이버는 제한이 없어 디스크를 채운다.

docker logs -f --tail 100 web
  • 컨테이너의 stdout/stderr 를 도커가 수집한다
  • 애플리케이션은 파일이 아니라 표준 출력으로 로그를 낸다
    • (파일에 쓰면 컨테이너가 지워질 때 함께 사라진다)

기본 설정이 디스크를 채운다

json-file 드라이버는 기본적으로 크기 제한이 없다

  • /var/lib/docker/containers/<id>/<id>-json.log

  • 장애로 로그가 폭주하면 호스트 디스크를 통째로 채운다

  • 도커 데몬 자체가 멎는다

  • 다른 컨테이너까지 전부 영향을 받는다

/etc/docker/daemon.json
  {
    "log-driver": "json-file",
    "log-opts": { "max-size": "10m", "max-file": "3" }
  }

이 네 줄이 없는 호스트를 아직도 자주 본다 기존 컨테이너는 재생성해야 적용된다

확인

du -sh /var/lib/docker/containers/* | sort -h | tail
docker inspect web --format '{{.LogPath}}'

운영에서는 수집기로 보낸다

  • 드라이버 — fluentd · awslogs · gelf · journald · splunk
  • 또는 — 노드 에이전트가 파일을 읽어 간다 (Fluent Bit · Vector)

주의 — 로그 드라이버에 따라 docker logs 가 동작하지 않는다

  • (json-file · journald 외에는 대개 안 된다)
  • 디버깅 경로를 미리 정해 둔다

구조화 로그가 유리해진다

수집기로 보내는 순간 '한 줄 = 한 이벤트' 가 전제가 된다

스택트레이스처럼 여러 줄인 로그는 조각나 버린다

  • JSON 한 줄로 내보내면 이 문제가 사라진다
  • 필드로 검색·집계할 수 있게 된다

{"ts":"...","level":"ERROR","msg":"...","trace_id":"abc","stack":"..."}

무엇을 로그로 남길 것인가

  • 요청 식별자(trace_id)를 넣어 앞단 로그와 이을 수 있게 한다
  • 개인정보·토큰을 찍지 않는다 — 수집기로 나가는 순간 통제가 어려워진다
  • 헬스체크 요청은 대개 끈다 (로그의 대부분을 차지한다)
  • 로그 레벨을 환경변수로 바꿀 수 있게 해 둔다 (재빌드 없이 조정)

로그 폭주가 만드는 2차 장애

애플리케이션 오류 → 예외 로그 폭주 → 디스크 가득 참

  • 도커 데몬이 컨테이너를 못 띄운다
  • 같은 호스트의 '무관한' 서비스까지 멈춘다

원래 하나의 서비스 문제였던 것이 노드 전체 장애가 된다

max-size 설정은 그래서 '가용성' 설정이다. 편의 기능이 아니다

애플리케이션 쪽 대응

  • 반복되는 예외는 샘플링하거나 집계해서 남긴다
    • 같은 스택트레이스를 초당 수천 번 찍는 것은 정보가 아니라 소음이다
  • 로그 레벨을 런타임에 바꿀 수 있게 한다
  • 스택트레이스는 원인(root cause)만 남기고 반복 프레임은 줄인다

로그 양 자체를 줄이는 것이 근본 대응이고, max-size 는 최악을 막는 안전장치다

면접 함정

  • "로그는 파일에 쓰면 된다" → 컨테이너가 지워지면 사라진다. stdout으로 낸다.
  • "docker logs는 항상 된다" → 드라이버에 따라 동작하지 않는다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 실행과 운영 — PID 1·볼륨·네트워크·로그