컨테이너 용어 사전
런타임OOM Killer · 메모리 초과 · MaxRAMPercentage

OOMKilled

메모리 제한을 넘겨 커널이 죽인 상태. 애플리케이션 로그에 아무것도 남지 않는다.

메모리 제한을 넘겨 커널이 프로세스를 죽인 상태.

$ docker inspect web --format '{{.State.OOMKilled}} {{.State.ExitCode}}'
true 137
컨테이너 안 프로세스가 limit 을 넘겨 쓰려 한다
  → 커널이 그 cgroup 안에서 프로세스를 하나 죽인다
  → 보통 가장 많이 쓰는 프로세스, 즉 우리 애플리케이션
  → 상태 OOMKilled · 종료 코드 137

로그가 안 남는 이유

SIGKILL 은 잡을 수 없다
→ 종료 훅 · 셧다운 로그 · 스택 덤프가 전혀 돌지 않는다
→ 애플리케이션 로그의 마지막 줄이 평범한 처리 로그다

확인은 밖에서 한다
  dmesg | grep -i "killed process"
  docker events --filter event=oom
  kubectl describe pod  (Last State: Terminated, Reason: OOMKilled)

런타임이 제한을 인식해야 한다

JVM 은 Java 10+ 에서 컨테이너 제한을 인식한다 (UseContainerSupport, 기본 켜짐) -XX:MaxRAMPercentage=75 limit 대비 비율로 힙을 잡는다 -Xmx 를 직접 주면 limit 이 바뀌어도 안 따라간다

주의 — 힙 밖에도 메모리가 든다 메타스페이스 · 코드 캐시 · 스레드 스택 · 다이렉트 버퍼 · GC 자체 구조 힙을 limit 의 100% 로 잡으면 반드시 OOMKilled 된다 실무 감각은 limit 의 60~75%

컨테이너 limit 2GB 예산 예시
  힙            1,200MB
  메타스페이스    128MB
  코드 캐시        64MB
  스레드 200개    200MB
  다이렉트 버퍼   128MB
  JVM 내부·GC    ~200MB
  ─────────────────────
  합계          ~1,920MB

스왑을 열어 두면 더 나쁠 수 있다

--memory-swap 을 --memory 보다 크게 두면

  • 메모리를 넘겨도 스왑으로 버틴다
  • 안 죽는 대신 극도로 느려진다
  • 살아 있는데 응답이 없는, 진단하기 더 어려운 상태

대개 --memory-swap 을 --memory 와 같게 잠그는 편이 낫다 "빨리 죽고 빨리 재시작" 이 더 나은 경우가 많다

진짜 누수인지 가른다

  • 제한 부족 — 사용량이 limit 근처에서 평평하다가 튄다
    • 부하가 오를 때만 발생한다
  • 누수 — 사용량이 시간에 따라 계속 우상향한다
    • 부하와 무관하게 며칠 뒤 발생한다

메모리 사용량 그래프를 며칠 단위로 보면 둘이 바로 갈린다 제한만 올리면 누수는 시점만 미뤄진다

노드 전체가 압박받는 경우와 구분한다

  • 컨테이너 OOM — 그 cgroup 의 limit 초과 → 그 컨테이너만 죽는다
  • 노드 OOM — 호스트 전체 메모리 부족 → 커널이 아무 프로세스나 고른다
    • limit 을 안 걸어 둔 컨테이너가 원인인 경우가 많다

노드 OOM 이면 무관한 컨테이너가 죽는다 — 원인 찾기가 훨씬 어렵다 그래서 '모든 컨테이너에 limit 을 건다' 가 기본 규칙이다

메모리를 실제로 재는 법

docker stats --no-stream
cat /sys/fs/cgroup/memory.current      # 컨테이너 안에서
cat /sys/fs/cgroup/memory.peak         # 최고치 (v2)
memory.current 에는 페이지 캐시도 포함된다
→ 파일을 많이 읽는 워크로드는 사용량이 높게 보인다
→ 캐시는 압박이 오면 회수되므로 그것만으로 OOM 이 나지는 않는다
→ memory.stat 의 anon(익명 메모리)을 함께 본다. 이쪽이 진짜 사용량에 가깝다

면접 함정

  • "OOM이면 애플리케이션 로그에 남는다" → SIGKILL이라 아무것도 안 남는다.
  • "힙을 limit만큼 주면 된다" → 힙 밖 메모리 때문에 반드시 초과한다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 트러블슈팅 — 증상에서 원인으로