Docker
Docker는 코드, 라이브러리, 모델 가중치를 컨테이너 이미지로 패키징해 노트북, GPU 서버, CI 러너, 엣지 디바이스에서 동일하게 실행합니다.
Docker는 애플리케이션을 컨테이너에서 빌드하고 공유하며 실행하기 위한 오픈 소스 플랫폼입니다. 컨테이너는 코드, 라이브러리, 시스템 패키지가 포함된 자체 파일 시스템을 갖춘 격리된 프로세스이며, 호스트의 운영 체제 커널을 공유합니다. 이후 Docker, Inc.로 사명을 변경한 dotCloud는 2013년 3월 이를 오픈 소스로 공개했습니다. 명령줄 도구, 계층형 이미지 형식, 공개 레지스트리를 통해 Linux 컨테이너는 일상적인 개발자 도구가 되었습니다. 머신러닝에서 Docker 이미지는 정확한 Python 버전, CUDA 라이브러리, PyTorch 빌드, 모델 가중치를 고정하므로 노트북, GPU 서버, 지속적 통합 실행기, 엣지 디바이스에서 모델이 동일하게 동작합니다.
Docker의 작동 방식#
Dockerfile에는 이미지를 빌드하는 단계가 나열됩니다. 시작할 기본 이미지, 패키지를 설치하는 명령, 복사할 파일, 시작 시 실행할 명령이 포함됩니다. 각 RUN, COPY 또는 ADD 명령은 읽기 전용 계층을 추가합니다. 다음 빌드에서는 명령이나 입력 파일이 변경될 때까지 캐시된 계층을 재사용하므로, 일찍 설치한 종속성은 캐시된 상태로 유지되고 애플리케이션 코드는 몇 초 만에 다시 빌드됩니다. 이미지는 이러한 계층 스택과 메타데이터로 구성됩니다. 컨테이너는 이미지 위에 얇은 쓰기 가능 계층을 둔 실행 중인 이미지 인스턴스이며, 데이터를 마운트된 볼륨에 저장하지 않으면 컨테이너가 삭제될 때 이 계층도 삭제됩니다.
docker 명령은 각 컨테이너를 containerd와 저수준 runc 런타임에 전달하는 백그라운드 데몬인 Docker Engine과 통신합니다. 이들은 Linux 네임스페이스를 사용해 컨테이너의 프로세스, 네트워크, 파일 시스템을 격리하고 cgroups를 사용해 CPU와 메모리를 제한합니다. 이미지는 Docker Hub, GitHub Container Registry, NVIDIA NGC와 같은 레지스트리 및 각 클라우드 제공업체의 자체 레지스트리를 통해 공유됩니다. 이미지는 Open Container Initiative 이미지 형식을 따르므로 Podman, containerd, Kubernetes에서 변경 없이 실행됩니다.
Ultralytics는 CUDA GPU, CPU, ARM64 보드, NVIDIA Jetson 디바이스, AMD GPU를 포함한 각 하드웨어 대상용 공식 Docker 이미지를 게시합니다. 각 이미지는 재현 가능한 빌드를 위해 Ultralytics 릴리스 번호로도 태그됩니다. 아래에서 사용하는 경량 latest-python 이미지에는 Python, PyTorch, ultralytics 패키지, YOLO26 nano 가중치가 이미 포함되어 있으므로 프로젝트의 Dockerfile에는 자체 코드만 추가하면 됩니다:
# Official Ultralytics CPU image with Python, PyTorch, ultralytics, and yolo26n.pt
FROM ultralytics/ultralytics:latest-python
# Install extra dependencies in their own layer, cached until requirements.txt changes
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy the application last, so code edits rebuild only this layer
COPY app.py .
# Command every container runs when it starts
CMD ["python", "app.py"]docker build -t yolo-app .은 이 파일과 같은 디렉터리에 있는 파일을 이미지로 만들고, docker run --rm yolo-app은 해당 이미지에서 컨테이너를 시작합니다. 이미지를 레지스트리에 푸시하면 다른 머신에서도 동일한 환경을 가져와 실행할 수 있습니다. 예를 들어 모델 서빙 API 또는 야간 추론 작업으로 실행할 수 있습니다.
머신러닝을 위한 Docker#
컨테이너는 NVIDIA Container Toolkit을 통해 GPU에 접근합니다. NVIDIA 드라이버는 호스트에 유지하고, 이미지는 해당 드라이버가 지원해야 하는 CUDA 사용자 공간 라이브러리만 포함합니다. Linux에서는 Docker 28.2 이상에서 CDI가 기본적으로 활성화되므로 --device nvidia.com/gpu=all은 GPU를 CDI 디바이스로 요청하고 장시간 실행되는 컨테이너에서 GPU 접근을 유지합니다. 이 경우 호스트가 systemd를 다시 로드할 때 기존 --gpus all 플래그는 GPU 접근 권한을 잃을 수 있습니다.
학습에 중요한 설정이 두 가지 더 있습니다. PyTorch 데이터 로더 워커는 /dev/shm의 공유 메모리를 통해 배치를 학습 프로세스에 전달합니다. Docker는 이 메모리를 기본값인 64 MB로 제한하므로, 학습 컨테이너는 --ipc=host을 사용하거나 --shm-size를 더 큰 값으로 설정해야 합니다. 체크포인트를 컨테이너 안에 기록하는 학습 실행은 컨테이너를 제거하면 데이터가 사라지므로 데이터셋과 출력물은 마운트된 볼륨에 저장해야 합니다. latest 대신 릴리스 태그나 이미지 다이제스트를 고정하면 모든 머신에서 분산 학습 작업 또는 모델 배포에 동일한 이미지를 사용할 수 있습니다. NVIDIA Triton Inference Server와 같은 추론 서버와 Vertex AI와 같은 관리형 서비스도 모델을 컨테이너 이미지로 실행합니다.
Docker와 가상 머신 및 Kubernetes 비교#
- 가상 머신: 하이퍼바이저가 하드웨어를 에뮬레이션하고 각 VM은 자체 게스트 커널을 부팅합니다. 따라서 워크로드를 더 강력하게 격리하고 어떤 게스트 운영 체제든 실행할 수 있지만, VM마다 전체 OS 이미지가 필요하고 시작 시간도 더 오래 걸립니다. 컨테이너는 호스트의 Linux 커널을 공유하므로 macOS와 Windows의 Docker Desktop은 경량 Linux VM 안에서 컨테이너를 실행합니다.
- Docker Compose: 추론 API, 캐시, 메트릭 수집기처럼 한 호스트에서 함께 실행되는 여러 컨테이너를 정의합니다.
- Kubernetes: 클러스터 전체에 컨테이너를 배치하고, 실패한 컨테이너를 다시 시작하며, 트래픽에 따라 복제본을 확장합니다. Kubernetes 1.24에서는 Docker Engine용 내장 어댑터인 dockershim이 제거되었습니다. 따라서 클러스터는 containerd 또는 CRI-O를 통해 컨테이너를 실행하지만, Docker로 빌드한 이미지는 표준 OCI 이미지이므로 그대로 실행됩니다.










