Docker 컨테이너 메모리 누수 3일 만에 잡은 썰

3일 내내 붙잡고 있다가 결국 원인 찾아서 정리해봅니다. 회사 서비스가 하루에 한 번씩 죽길래 로그 뒤지다가, 메모리 그래프 찍어보니 새벽 3시쯤 급격히 늘어나더라고요.

원인은 로그 수집 컨테이너였습니다. Elasticsearch로 로그를 보내는데, 예외 발생 시 스택 트레이스가 아주 길면 인덱싱 실패가 반복되면서 버퍼가 계속 쌓이더군요. 버퍼 크기 제한도 안 걸려 있어서 메모리 2GB까지 점유하고 컨테이너가 죽었습니다.

해결 방법은 간단했어요.

  • 로그 메시지 최대 길이를 10KB로 자르기
  • 백프레셔가 걸리면 드랍하도록 버퍼 설정 변경

이걸로 안 죽습니다. 혹시 비슷한 증상 있으면 로그 파이프라인부터 보세요.

작성자 코딩하는곰448

9 개의 답변

ㅇㅇ 로그 버퍼 개수 제한 안 걸어두면 저런 일 흔함ㅋㅋ

작성자 뉴비탈출159 · ▲0

오 이건 몰랐네. 우리도 로그 파이프라인 한번 점검해봐야겠다.

작성자 월급루팡60 · ▲0

근데 그거 메모리 누수라기보다 버퍼 설정 문제 아님? 암튼 해결하신 거 축하

작성자 코딩하는곰519 · ▲0

나도 저번에 fluentd retry 때문에 같은 증상 겪었는데, max_buffer_size 제한 걸고 멀티라인 로그 합치는 걸로 해결했었음. 로그 길이 10KB 자르는 방법도 실용적이네.

작성자 취준생김씨414 · ▲0

좋은 글 감사합니다. 저희도 로그 수집 컨테이너가 주기적으로 죽어서 고민이었는데, 버퍼 크기부터 확인해볼게요.

작성자 AI덕후573 · ▲0

Elasticsearch 인덱싱 실패가 반복되면 DLQ로 빼는 게 좋아. 버퍼에 계속 쌓아두는 건 근본 해결이 아님. 카프카 쓰면 백프레셔 관리도 편하고.

작성자 디지털노마드961 · ▲0

글쎄, 나는 로그 길이 자르는 게 근본 해결 같지는 않은데. 차라리 스택 트레이스는 파일로 빼고 메시지는 요약 보내는 게 낫지 않나?

작성자 밤샘코더361 · ▲0

3일이면 금방이지 ㅋㅋ 나는 한 달 걸렸었는데 알고 보니 그냥 log_level을 debug로 해둔 거였음...

작성자 궁금한사람112 · ▲0

디스크 여유 있는데 왜 메모리에 쌓게 뒀음? 걍 파일로 쓰게 하면 됐잖아 ㅋㅋ

작성자 디지털노마드74 · ▲0