본문 바로가기
IT/Docker

Docker 메모리 제한 설정 방법

by 하루 또다시 하루 2026. 3. 26.
반응형

Docker 메모리 제한 설정 방법을 찾고 있다면, 먼저 --memory, mem_limit, --memory-swap이 각각 무엇을 제한하는지부터 정확히 구분해야 합니다.
Docker 메모리 제한 설정 방법을 잘못 이해하면 OOMKilled를 막으려다가 오히려 swap 때문에 더 느려지거나, 호스트 전체 메모리를 압박하는 상황이 생깁니다.
이 글에서는 Docker 메모리 제한 설정 방법을 운영 기준으로 정리하고, 어떤 상황에서 어떤 값을 잡아야 하는지 실전 감각으로 풀어보겠습니다. Docker는 기본적으로 컨테이너에 자원 제한이 없을 수 있고, 메모리 부족 시 리눅스 OOM 동작 때문에 개별 컨테이너가 먼저 죽기 쉬운 구조입니다.

왜 Docker 메모리 제한을 먼저 잡아야 할까

Docker 공식 문서 기준으로, 기본 상태의 컨테이너는 호스트 커널 스케줄러가 허용하는 만큼 자원을 사용할 수 있습니다. 문제는 메모리 부족이 오면 리눅스가 OOM을 발생시키고 프로세스를 종료해 버릴 수 있다는 점입니다. Docker는 데몬이 먼저 죽지 않도록 우선순위를 조정하지만, 컨테이너 쪽 OOM 우선순위는 그렇게 조정되지 않기 때문에 개별 컨테이너가 먼저 희생될 가능성이 큽니다.

그래서 Docker 메모리 제한 설정 방법은 “나중에 튜닝할 옵션”이 아니라, 운영 환경에서는 거의 기본 설정에 가깝습니다. 특히 Java, Node.js, Python처럼 런타임 특성상 메모리 사용량이 출렁이는 서비스는 더 그렇습니다. Docker도 운영 전에 애플리케이션의 메모리 요구량을 테스트하고, 호스트에 충분한 자원이 있는지 확인하라고 안내합니다.


Docker 메모리 제한 설정 방법에서 가장 먼저 구분할 것

--memory: RAM 하드 제한

-m 또는 --memory는 컨테이너가 사용할 수 있는 최대 메모리 양입니다. 쉽게 말해 실제 RAM 상한선입니다. Docker 문서상 최소 허용 값은 6m입니다.

예를 들어:

docker run -d --name app --memory="512m" my-app:latest
 

이렇게 두면 컨테이너는 512MB를 넘는 메모리 사용에서 강하게 제한됩니다.

--memory-reservation: 소프트 제한

--memory-reservation은 하드 제한보다 먼저 걸어두는 소프트 제한입니다. 평소에는 더 쓸 수도 있지만, 호스트에 메모리 압박이나 경합이 생기면 Docker가 이 예약치 아래로 줄이려 시도합니다. 공식 문서도 이 값은 --memory보다 낮아야 하며, 소프트 제한이라 초과를 완전히 막아주지는 않는다고 설명합니다.

예를 들어:

docker run -d \
    --name app \
    --memory="512m" \
    --memory-reservation="256m" \
    my-app:latest
 

운영에서는 이 조합이 생각보다 유용합니다. 평소엔 여유롭게 쓰되, 메모리 압박이 생기면 너무 공격적으로 호스트를 잡아먹지 않게 만들 수 있기 때문입니다.

--memory-swap: 추가 swap이 아니라 “RAM + swap 총합”

여기서 가장 많이 헷갈립니다. --memory-swap은 추가 swap 양이 아니라, 메모리와 swap을 합친 총 사용 가능량입니다. Docker 문서가 이 부분을 아주 명확하게 설명합니다. --memory="300m"와 --memory-swap="1g"를 같이 주면, RAM 300MB와 swap 700MB를 써서 총 1GB까지 쓸 수 있습니다.

즉, 이렇게 이해하면 됩니다.

  • --memory=300m만 설정 → 총량은 기본적으로 600MB 수준(RAM 300MB + swap 300MB)으로 동작할 수 있습니다.
  • --memory=300m --memory-swap=1g → 총량 1GB, 그중 RAM 300MB.
  • --memory=300m --memory-swap=300m → swap 사용 금지.
  • --memory=300m --memory-swap=-1 → RAM은 300MB로 막고, swap은 호스트가 허용하는 범위까지 무제한.

이 한 줄만 제대로 기억해도 Docker 메모리 제한 설정 방법의 절반은 정리됩니다. --memory-swap은 총합이고, --memory와 같은 값이면 swap이 막힌다는 점입니다.


Compose에서는 mem_limit을 어떻게 봐야 할까

Compose 서비스 문서에는 mem_limit, mem_reservation, mem_swappiness, memswap_limit이 정의돼 있습니다. 여기서 mem_limit은 컨테이너가 할당할 수 있는 메모리 제한을 설정하고, mem_reservation은 예약량을 설정합니다. memswap_limit은 swap 관련 총량 제어에 해당합니다.

예를 들면 이런 식입니다.

services:
    app:
        image: my-app:latest
        mem_limit: 512m
        mem_reservation: 256m
        memswap_limit: 768m
 

또 하나 중요한 점은 Compose의 deploy 섹션입니다. 공식 문서에는 deploy.resources.limits.memory와 deploy.resources.reservations.memory도 따로 정의돼 있지만, deploy 자체는 Compose 스펙의 optional 영역이라 구현되지 않으면 무시될 수 있다고 적혀 있습니다. 그래서 Docker 메모리 제한 설정 방법을 정리할 때는 서비스 수준 설정과 deploy 수준 설정을 혼동하지 않는 것이 중요합니다.


왜 이런 문제가 자꾸 발생하는가

1. --memory-swap을 “추가 swap”으로 착각하는 경우

실무에서 제일 흔한 실수입니다. --memory=512m --memory-swap=1g를 넣고 “swap 1GB를 추가했다”고 생각하는 경우가 많은데, 실제 의미는 총합 1GB입니다. 즉, swap은 512MB가 아니라 1GB 전체가 아니라 1g - 512m만큼입니다.

2. --memory만 넣고 끝내는 경우

Docker 문서에 따르면 --memory만 설정하고 --memory-swap을 비워두면, 호스트에 swap이 구성돼 있을 때 컨테이너는 메모리 한도만큼의 swap을 추가로 쓸 수 있습니다. 예를 들어 --memory=300m만 설정하면 총 사용 가능량이 600MB가 될 수 있습니다. 이걸 모르고 있으면 “분명 300MB로 막았는데 왜 swap을 쓰지?”라는 상황이 생깁니다.

3. 호스트가 swap limit을 제대로 지원하지 않는 경우

Docker는 docker info로 지원 여부를 확인하라고 안내합니다. 커널 기능이 꺼져 있으면 WARNING: No swap limit support 같은 경고가 보일 수 있습니다. 이런 환경에서는 Docker 메모리 제한 설정 방법을 문서대로 했더라도 기대한 대로 동작하지 않을 수 있습니다.

4. 컨테이너 안에서 free만 보고 판단하는 경우

공식 문서에 따르면 컨테이너 내부의 free 같은 도구는 컨테이너에 실제로 허용된 swap이 아니라 호스트의 swap 정보를 보여줄 수 있습니다. 그래서 “컨테이너 안에서 보면 swap이 많아 보이는데 왜 OOM이 나지?” 같은 혼란이 생깁니다. 이런 경우는 반드시 호스트 쪽 설정과 docker inspect, docker stats를 함께 봐야 합니다.

5. Docker Desktop VM 한도를 놓치는 경우

Mac, Hyper-V 기반 Windows, 일부 Docker Desktop 환경에서는 컨테이너가 바로 호스트 메모리를 쓰는 게 아니라 Docker VM 자원 한도 안에서 움직입니다. Docker Desktop 문서에는 Advanced 리소스 설정에서 CPU, 메모리, swap을 조절할 수 있고, 메모리 기본값은 호스트 메모리의 50%, swap 기본값은 1GB라고 나와 있습니다. 즉, 컨테이너 메모리 제한만 보고 있으면 실제 병목을 놓칠 수 있습니다.


Docker 메모리 제한 설정 방법, 운영 기준으로 이렇게 잡으면 편합니다

1. 응답 속도가 중요한 API 서버라면 swap을 막는 편이 낫다

API 서버, 웹 애플리케이션처럼 지연 시간에 민감한 서비스는 swap이 열려 있으면 버티긴 해도 갑자기 느려질 수 있습니다. Docker도 swap은 메모리보다 느리고, 자주 쓰면 성능 페널티가 있다고 설명합니다. 이런 서비스는 차라리 한도를 명확히 주고 빨리 이상 징후를 드러내는 편이 운영에서 낫습니다.

docker run -d \
    --name api \
    --memory="512m" \
    --memory-swap="512m" \
    --restart unless-stopped \
    my-api:latest
 

이 설정은 RAM 512MB만 허용하고 swap은 막습니다.

2. 순간 피크가 있는 배치성 작업은 제한된 swap을 허용할 수 있다

배치, 크롤러, 이미지 처리처럼 평소엔 조용하지만 순간 피크가 있는 작업은 아주 조금의 swap을 허용하는 쪽이 더 안정적일 때가 있습니다.

docker run -d \
    --name batch \
    --memory="512m" \
    --memory-swap="768m" \
    my-batch:latest
 

이 경우 RAM 512MB에 swap 256MB 정도를 완충재로 두는 셈입니다. 다만 swap이 자주 발생하면 성능이 크게 떨어질 수 있으니, 어디까지나 “버퍼”로 보는 게 맞습니다.

3. Compose 단일 서버 운영이면 서비스 설정을 명확히 적어두자

services:
    app:
        image: my-app:latest
        mem_limit: 512m
        mem_reservation: 256m
        memswap_limit: 512m
        restart: unless-stopped
 

이 조합은 운영용 기준으로 이해하기 쉽습니다.

  • mem_limit: RAM 상한
  • mem_reservation: 소프트 기준선
  • memswap_limit: RAM + swap 총합
  • memswap_limit을 mem_limit과 같게 두면 swap 차단 효과

이렇게 정리해두면 나중에 OOMKilled가 났을 때도 원인 추적이 훨씬 빨라집니다. 관련 의미 자체는 Docker의 메모리/스왑 제어 문서와 Compose 서비스 문서가 동일한 방향으로 설명합니다.

4. Swarm이나 deploy 자원 정책을 쓰는 환경이면 deploy.resources도 함께 이해해야 한다

Compose Deploy 스펙은 limits와 reservations로 자원 제약을 나누고, memory는 limit 또는 reservation 값으로 지정할 수 있다고 정의합니다. 다만 앞서 말했듯 deploy는 구현되지 않으면 무시될 수 있으므로, 현재 운영 방식이 무엇인지 먼저 확인하는 것이 좋습니다.

예시는 아래처럼 가져갈 수 있습니다.

services:
    app:
        image: my-app:latest
        deploy:
            resources:
                limits:
                    memory: 512M
                reservations:
                    memory: 256M
 

적용 후 반드시 확인해야 할 명령어

Docker 메모리 제한 설정 방법은 “설정 파일에 적는 것”으로 끝나면 안 됩니다. 실제로 적용됐는지 확인해야 합니다. Docker 공식 문서 기준으로 docker inspect는 Docker 객체의 저수준 정보를 보여주고, docker stats는 실행 중인 컨테이너의 메모리 사용량과 제한값을 보여줍니다.

1. 설정값 확인

docker inspect --format '{{.HostConfig.Memory}} {{.HostConfig.MemorySwap}} {{.HostConfig.MemoryReservation}}' app
 

2. 현재 사용량 확인

docker stats --no-stream
 

docker stats는 메모리 사용량과 limit를 같이 보여주기 때문에, 지금 한도가 너무 빡빡한지 아니면 너무 널널한지 판단할 때 가장 먼저 보기 좋습니다.

3. 커널 지원 상태 확인

docker info
 

출력 하단에 WARNING: No swap limit support 같은 경고가 보이면 swap 관련 동작을 다시 점검해야 합니다.


많이 하는 실수 5가지

1. --memory만 주고 안심하기

이 경우는 swap이 열려 있을 수 있습니다. 결국 느려지면서 버티는 상태가 생길 수 있습니다.

2. --memory-swap을 swap 추가 용량으로 계산하기

가장 흔한 오해입니다. 총합 기준으로 계산해야 합니다.

3. --memory-reservation을 하드 제한처럼 믿기

이건 소프트 제한입니다. 넘지 못하게 막는 장치가 아니라, 경합이 생겼을 때 우선 줄이려는 기준에 가깝습니다.

4. 컨테이너 안의 free만 믿기

실제 허용 swap과 다르게 보일 수 있습니다.

5. Docker Desktop VM 메모리 한도를 놓치기

컨테이너 설정은 맞는데도 계속 메모리 부족이 난다면 Desktop 자원 한도를 먼저 봐야 할 수 있습니다.


운영용 기준으로 추천하는 기본값

Docker 메모리 제한 설정 방법을 실무에서 단순하게 가져가려면, 처음엔 아래처럼 생각하면 편합니다.

  • 응답 속도 중요한 서비스: memory = X, memory-swap = X
  • 순간 피크 있는 작업: memory = X, memory-swap = X보다 조금 크게
  • 소프트 제어도 필요하면 memory-reservation 또는 mem_reservation 추가
  • 적용 후 docker stats로 며칠 관찰
  • swap limit 지원 여부와 Desktop VM 한도까지 함께 점검
반응형

 

반응형