카테고리 없음

Docker 기본 - 리소스 제한 완전 정복

cell-devlog 2026. 5. 21. 10:29
반응형

컨테이너 생성 시 CPU·메모리·GPU·디스크·네트워크·프로세스 등 모든 리소스 제한 옵션 총정리


1. CPU 제한

--cpus — CPU 코어 수 제한 (가장 많이 씀)

docker run --cpus="4" <이미지>
  • 물리 코어 수와 관계없이 논리적으로 사용할 코어 수를 제한
  • --cpus="1.5" → 1.5개 코어 분량 사용 가능
  • docker stats에서 최대 400%(4코어)까지 올라감

--cpu-shares — CPU 가중치 (상대적 우선순위)

docker run --cpu-shares=512 <이미지>
  • 기본값: 1024
  • 절대 제한이 아닌 상대적 비율 — CPU 경합 시 우선순위 결정
  • 1024 : 512 = 2:1 비율로 CPU 분배
  • CPU가 여유 있을 때는 제한 없이 다 씀

--cpu-period + --cpu-quota — CFS 스케줄러 직접 제어

# 500ms 주기에서 250ms만 사용 → 50% 제한 (0.5코어)
docker run --cpu-period=500000 --cpu-quota=250000 <이미지>

# 100ms 주기에서 400ms 사용 → 400% (4코어)
docker run --cpu-period=100000 --cpu-quota=400000 <이미지>
  • --cpu-period: 측정 주기 (마이크로초, 기본 100000 = 100ms)
  • --cpu-quota: 주기 내 사용 가능한 시간 (마이크로초)
  • --cpus가 내부적으로 이 두 값을 자동 계산해서 설정함

--cpuset-cpus — 특정 CPU 코어 고정

# 0번, 1번 코어만 사용
docker run --cpuset-cpus="0,1" <이미지>

# 0~3번 코어만 사용
docker run --cpuset-cpus="0-3" <이미지>
  • NUMA 아키텍처 최적화나 코어 격리에 사용
  • CPU affinity 고정 → 캐시 효율 향상

--cpuset-mems — NUMA 메모리 노드 고정

# NUMA 노드 0번 메모리만 사용
docker run --cpuset-mems="0" <이미지>

CPU 설정 조합 예시 (실무)

docker run \
  --cpus="16" \           # 최대 16코어
  --cpu-shares=512 \      # 우선순위 낮음 (기본의 절반)
  --cpuset-cpus="0-15" \  # 물리 0~15번 코어만 사용
  <이미지>

CPU 설정 확인

# inspect로 확인
docker inspect <컨테이너> | grep -E "NanoCpus|CpuShares|CpuQuota|CpuPeriod|CpusetCpus"

# NanoCpus → 실제 코어 수 = NanoCpus / 1,000,000,000
# 16코어 → NanoCpus: 16000000000

2. 메모리 제한

--memory — 최대 메모리 제한

docker run --memory="8g" <이미지>
docker run --memory="512m" <이미지>
docker run --memory="1024k" <이미지>
  • 단위: b, k, m, g
  • 제한 초과 시 → OOM Killer가 컨테이너 프로세스 종료

--memory-swap — 스왑 포함 총 메모리 제한

# 메모리 8g + 스왑 8g → 총 16g 가능
docker run --memory="8g" --memory-swap="16g" <이미지>

# 스왑 완전 비활성화 (--memory와 같은 값)
docker run --memory="8g" --memory-swap="8g" <이미지>

# 스왑 무제한 허용
docker run --memory="8g" --memory-swap="-1" <이미지>

--memory-swap메모리+스왑의 합산 값임. 스왑 단독 크기가 아님.
스왑 실제 크기 = --memory-swap - --memory

--memory-reservation — 소프트 메모리 제한 (보장량)

docker run --memory="40g" --memory-reservation="20g" <이미지>
  • 호스트 메모리 부족 시 이 값까지 줄어들도록 유도 (강제 아님)
  • 최소 보장 메모리 개념
  • 반드시 --memory보다 작아야 함

--memory-swappiness — 스왑 사용 경향 조절

# 스왑을 최대한 안 씀 (0~100, 기본 -1 = 호스트 설정 따름)
docker run --memory-swappiness=0 <이미지>

--oom-kill-disable — OOM Killer 비활성화

docker run --memory="8g" --oom-kill-disable <이미지>
  • 메모리 초과 시 프로세스를 죽이지 않고 대기
  • 주의: 호스트 전체 OOM 유발 위험 있음. --memory와 함께만 사용

--oom-score-adj — OOM 우선순위 조정

# 높을수록 OOM 시 먼저 종료됨 (-1000 ~ 1000)
docker run --oom-score-adj=300 <이미지>

# 가장 마지막에 종료되도록
docker run --oom-score-adj=-500 <이미지>

--shm-size — 공유 메모리 크기

docker run --shm-size="20g" <이미지>
  • /dev/shm 크기 설정 (기본 64MB)
  • ML 학습, 멀티프로세스 통신에서 중요
  • PyTorch DataLoader num_workers 쓸 때 반드시 늘려야 함

메모리 설정 확인

docker inspect <컨테이너> | grep -E "Memory|Swap|Shm"

3. GPU 제한

--gpus — GPU 할당

# 전체 GPU 사용
docker run --gpus all <이미지>

# GPU 1개 사용
docker run --gpus 1 <이미지>

# 특정 GPU 지정 (device ID)
docker run --gpus '"device=0"' <이미지>
docker run --gpus '"device=0,1"' <이미지>
docker run --gpus '"device=5"' <이미지>

# 복수 지정
docker run --gpus '"device=0,2,5"' <이미지>

nvidia-container-toolkit 설치 필요

GPU 사용 확인

# 컨테이너 내부에서
docker exec <컨테이너> nvidia-smi

# 호스트에서 컨테이너별 GPU 사용량
nvidia-smi

# GPU 메모리 포함 상세
nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv

4. 디스크 I/O 제한

--device-read-bps / --device-write-bps — 초당 바이트 제한

# /dev/sda 읽기 10MB/s 제한
docker run --device-read-bps /dev/sda:10mb <이미지>

# 쓰기 20MB/s 제한
docker run --device-write-bps /dev/sda:20mb <이미지>

--device-read-iops / --device-write-iops — 초당 IOPS 제한

# 읽기 1000 IOPS 제한
docker run --device-read-iops /dev/sda:1000 <이미지>

# 쓰기 500 IOPS 제한
docker run --device-write-iops /dev/sda:500 <이미지>

--blkio-weight — 블록 I/O 가중치

# 10~1000, 기본 500
docker run --blkio-weight=300 <이미지>

5. 네트워크 제한

도커 자체에는 네트워크 대역폭 제한 옵션이 없음. tc (traffic control) 조합 필요.

# 컨테이너 내부에서 대역폭 제한 (tc 사용)
docker exec <컨테이너> tc qdisc add dev eth0 root tbf \
  rate 100mbit burst 32kbit latency 400ms

또는 --network 옵션으로 네트워크 격리:

# 네트워크 없음 (완전 격리)
docker run --network=none <이미지>

# 호스트 네트워크 사용 (성능 최대)
docker run --network=host <이미지>

6. 프로세스 수 제한

--pids-limit — 최대 프로세스(PID) 수

# 최대 200개 프로세스
docker run --pids-limit=200 <이미지>

# 무제한
docker run --pids-limit=-1 <이미지>
  • Fork 폭탄 방지에 효과적
  • 기본값은 호스트 설정을 따름

7. 재시작 정책

# 항상 재시작
docker run --restart=always <이미지>

# 비정상 종료 시만 재시작 (종료코드 0이 아닐 때)
docker run --restart=on-failure <이미지>

# 최대 5회까지만 재시작
docker run --restart=on-failure:5 <이미지>

# 도커 데몬 시작 시에만 재시작 (수동 stop은 안 함)
docker run --restart=unless-stopped <이미지>

# 재시작 안 함 (기본값)
docker run --restart=no <이미지>

8. ulimit 제한

# 열 수 있는 파일 수 제한 (nofile)
docker run --ulimit nofile=65536:65536 <이미지>

# 스택 크기 제한
docker run --ulimit stack=67108864:67108864 <이미지>

# 코어 덤프 크기
docker run --ulimit core=-1 <이미지>

# 여러 ulimit 동시 적용
docker run \
  --ulimit nofile=65536:65536 \
  --ulimit nproc=65536:65536 \
  <이미지>

9. 실무 예시 템플릿

ML/딥러닝 컨테이너

docker run -d \
  --name ml_train \
  --ipc=host \
  --gpus '"device=0,1"' \
  --cpus="32" \
  --cpu-shares=1024 \
  --memory="64g" \
  --memory-swap="64g" \
  --memory-reservation="32g" \
  --shm-size="32g" \
  --oom-score-adj=300 \
  --pids-limit=4096 \
  --restart=unless-stopped \
  -v /raid/DATA:/data \
  pytorch/pytorch:latest

웹 서버 (리소스 절약형)

docker run -d \
  --name web_server \
  --cpus="2" \
  --cpu-shares=512 \
  --memory="2g" \
  --memory-swap="2g" \
  --memory-reservation="512m" \
  --pids-limit=200 \
  --restart=always \
  --log-opt max-size=100m \
  --log-opt max-file=3 \
  -p 80:80 \
  nginx:latest

DB 컨테이너 (안정성 우선)

docker run -d \
  --name postgres_db \
  --cpus="8" \
  --memory="16g" \
  --memory-swap="16g" \
  --memory-reservation="8g" \
  --oom-kill-disable \
  --shm-size="1g" \
  --ulimit nofile=65536:65536 \
  --restart=always \
  -v pg_data:/var/lib/postgresql/data \
  postgres:15

배치 작업 (일회성, 낮은 우선순위)

docker run --rm \
  --name batch_job \
  --cpus="4" \
  --cpu-shares=256 \
  --memory="8g" \
  --memory-swap="16g" \
  --pids-limit=100 \
  --oom-score-adj=500 \
  batch_image:latest

10. 실행 중 컨테이너 리소스 제한 변경 (재시작 없이)

# CPU 제한 변경
docker update --cpus="8" <컨테이너명>

# 메모리 제한 변경
docker update --memory="16g" --memory-swap="16g" <컨테이너명>

# CPU + 메모리 동시 변경
docker update \
  --cpus="8" \
  --memory="16g" \
  --memory-swap="16g" \
  <컨테이너명>

# 재시작 정책 변경
docker update --restart=always <컨테이너명>

# 여러 컨테이너 동시 변경
docker update --cpus="4" container1 container2 container3

11. Docker Compose에서 리소스 제한

# docker-compose.yml

services:
  app:
    image: myapp:latest
    deploy:
      resources:
        limits:
          cpus: "4"
          memory: 8G
        reservations:
          cpus: "1"
          memory: 2G
    ulimits:
      nofile:
        soft: 65536
        hard: 65536
    shm_size: "2gb"
    restart: unless-stopped
    logging:
      driver: json-file
      options:
        max-size: "100m"
        max-file: "3"

  gpu_service:
    image: pytorch:latest
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids: ["0", "1"]
              capabilities: [gpu]

12. 리소스 제한 확인 명령어 모음

# CPU 관련 전체
docker inspect <컨테이너> | grep -E \
  "NanoCpus|CpuShares|CpuQuota|CpuPeriod|CpusetCpus|CpusetMems"

# 메모리 관련 전체
docker inspect <컨테이너> | grep -E \
  "Memory|Swap|Shm|OomKill|OomScore"

# 리소스 제한 요약 (한 번에)
docker inspect <컨테이너> --format \
  'CPU: {{.HostConfig.NanoCpus}} nano | Shares: {{.HostConfig.CpuShares}} | Mem: {{.HostConfig.Memory}} | Swap: {{.HostConfig.MemorySwap}} | Shm: {{.HostConfig.ShmSize}}'

# 현재 실시간 사용량
docker stats <컨테이너>

13. 옵션 한눈에 보기

옵션 기본값 설명
--cpus 무제한 사용 가능한 CPU 코어 수
--cpu-shares 1024 CPU 상대적 우선순위 가중치
--cpuset-cpus 무제한 사용할 물리 코어 번호 고정
--cpu-period 100000 CFS 주기 (마이크로초)
--cpu-quota -1(무제한) CFS 주기 내 사용 시간
--memory 무제한 최대 메모리
--memory-swap --memory의 2배 메모리+스왑 합산 제한
--memory-reservation 무제한 소프트 메모리 보장량
--memory-swappiness -1(호스트 따름) 스왑 사용 경향 (0~100)
--shm-size 64MB 공유 메모리(/dev/shm) 크기
--oom-kill-disable false OOM Killer 비활성화
--oom-score-adj 0 OOM 종료 우선순위
--gpus 없음 GPU 할당
--pids-limit -1(무제한) 최대 프로세스 수
--blkio-weight 500 블록 I/O 가중치
--restart no 재시작 정책
--ulimit 호스트 따름 ulimit 설정

반응형