← 아티클 목록

도커 컨테이너 메모리 제한 — CPU·메모리 리소스 설정

2027-02-22#docker#리소스#운영

컨테이너는 기본적으로 호스트의 모든 CPU와 메모리를 제한 없이 쓸 수 있습니다. 그래서 한 컨테이너에서 메모리 누수가 나면 호스트 전체 메모리를 먹어버리고, 커널 OOM Killer가 다른 멀쩡한 컨테이너까지 죽입니다. 한 컨테이너의 문제가 호스트 전체로 번지는 것을 막는 것이 리소스 제한입니다.

1단계 — 지금 얼마나 쓰는지 본다

제한값을 정하려면 먼저 실제 사용량을 알아야 합니다.

로컬 터미널
# 컨테이너별 실시간 CPU·메모리 사용량
docker stats

# 컨테이너가 OOM으로 죽었는지 확인
docker inspect -f '{{.State.OOMKilled}}' <컨테이너>

# 종료 코드 137이면 메모리 초과 강제 종료
docker inspect -f '{{.State.ExitCode}}' <컨테이너>

docker statsMEM USAGE / LIMIT에서 LIMIT이 호스트 전체 메모리로 잡혀 있다면 제한이 없는 상태입니다.

OOMKilled 신호 읽기

신호의미
ExitCode 137메모리 limit 초과로 SIGKILL
OOMKilled: true커널이 컨테이너를 강제 종료
호스트 전체 응답 없음제한 없는 컨테이너가 호스트 메모리 고갈

ExitCode 137은 거의 항상 메모리 부족 신호입니다. 제한이 없는데 죽었다면 호스트 메모리가 고갈된 것이고, 제한이 있는데 죽었다면 limit이 너무 낮은 것입니다.

메모리 제한 설정

가장 중요한 건 메모리입니다. --memory로 상한을 둡니다.

Docker
docker run -d \
  --memory 512m \
  --memory-swap 512m \
  myapp

--memory는 물리 메모리 상한, --memory-swap은 메모리+스왑 합계입니다. 둘을 같은 값으로 두면 스왑을 막아, 느려진 채 살아 있는 것보다 빨리 OOM으로 드러나게 할 수 있습니다.

CPU 제한 설정

CPU는 여러 컨테이너가 나눠 쓰므로 보통 비율로 제한합니다.

Docker
docker run -d \
  --cpus 1.5 \
  myapp

--cpus 1.5는 코어 1.5개 분량만 쓰게 합니다. 메모리와 달리 CPU 초과는 컨테이너를 죽이지 않고 **스로틀링(속도 제한)**만 걸립니다.

docker-compose에서

YAML
services:
  app:
    image: myapp
    deploy:
      resources:
        limits:
          memory: 512m
          cpus: "1.5"

Compose v2 standalone에서는 deploy.resources.limits가 적용되며, Swarm 없이도 동작합니다.

체크리스트

로컬 터미널
docker stats                                          # 실제 사용량으로 limit 산정
docker inspect -f '{{.State.OOMKilled}}' <컨테이너>    # OOM 여부
docker inspect -f '{{.HostConfig.Memory}}' <컨테이너>  # 제한 적용 확인(0이면 무제한)

제한값은 docker stats로 본 평소 사용량에 여유를 더해 잡는 것이 안전합니다. 너무 빡빡하면 정상 부하에도 OOM이 납니다.


메모리 제한을 걸고 일부러 초과시켜 OOMKilled를 직접 재현해 보는 실습은 도커 트랙에서 무료로 할 수 있습니다.