이 글은 도커에 대해 간략히 살펴보고, 도커 컨테이너에 우분투, 텐서플로우, PyTorch(파이 토치)를 설치해 본다.
- Install Docker
- Windows 10에서 Docker for Windows 설치
- Docker Windows에 설치하기
- 도커 안내서 및 명령어
- PyTorch Tutorial (CNN)
이미지는 컨테이너 실행에 필요한 파일과 설정값을 포함하고 있다. 컨테이너는 이미지를 실행한 상태이다. 예를 들어, 우분투 이미지는 우분투 실행을 위한 모든 파일을 가지고 있다.
도커는 가상머신에 비해 사용이 쉽고 성능이 좋으나 한계가 있다. 운영체제의 라이브러리 및 시스템을 재활용하므로, 이에 의존되어 동작된다. 만약, 운영체제의 드라이버 설정에 GPU가 설치안되어 있다면, 도커 이미지도 이와 관련된 라이브러리를 사용하지 못할 것이다. 이는 성능은 느리나 운영체제 독립적인 가상머신과는 크게 다른 점이다.
참고 - 2019년 4월 도커 버전과 Kitematic 버전이 서로 문제를 일으켜서, 도커 이미지 다운로드 안되는 현상있음. 이 경우, https://github.com/docker/kitematic/releases 에서 Kitematic 0.17.3 버전을 다운로드 받아 실행해 볼것.
옵션 | 설명 |
---|---|
-d | detached mode 흔히 말하는 백그라운드 모드 |
-p | 호스트와 컨테이너의 포트를 연결 (포워딩) |
-v | 호스트와 컨테이너의 디렉토리를 연결 (마운트) |
-e | 컨테이너 내에서 사용할 환경변수 설정 |
–name | 컨테이너 이름 설정 |
–rm | 프로세스 종료시 컨테이너 자동 제거 |
-it | -i와 -t를 동시에 사용한 것으로 터미널 입력을 위한 옵션 |
–link | 컨테이너 연결 [컨테이너명:별칭] |
6. PyTorch 이미지 실행
PyTorch는 텐서플로우와 비슷한 머신러닝 플랫폼이다.
$ docker run -it --rm -p 8888:8888 stepankuzmin/pytorch-notebook
mkdir -p nginx-image
cd nginx-image/
touch Dockerfile
gedit Dockerfile
다음과 같이 우분투 20.04 버전을 기반으로 NGNIX 서버를 설치하고, 환경을 설정하는 명령을 Dockerfile에 입력한 후 저장한다.
# Download base image ubuntu 20.04
FROM ubuntu:20.04
# LABEL about the custom image
LABEL maintainer="admin@sysadminjournal.com"
LABEL version="0.1"
LABEL description="This is custom Docker Image for \
the PHP-FPM and Nginx Services."
# Disable Prompt During Packages Installation
ARG DEBIAN_FRONTEND=noninteractive
# Update Ubuntu Software repository
RUN apt update
# Install nginx, php-fpm and supervisord from ubuntu repository
RUN apt install -y nginx php-fpm supervisor && \
rm -rf /var/lib/apt/lists/* && \
apt clean
# Define the ENV variable
ENV nginx_vhost /etc/nginx/sites-available/default
ENV php_conf /etc/php/7.4/fpm/php.ini
ENV nginx_conf /etc/nginx/nginx.conf
ENV supervisor_conf /etc/supervisor/supervisord.conf
# Enable PHP-fpm on nginx virtualhost configuration
COPY default ${nginx_vhost}
RUN sed -i -e 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' ${php_conf} && \
echo "\ndaemon off;" >> ${nginx_conf}
# Copy supervisor configuration
COPY supervisord.conf ${supervisor_conf}
RUN mkdir -p /run/php && \
chown -R www-data:www-data /var/www/html && \
chown -R www-data:www-data /run/php
# Volume configuration
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d", "/var/log/nginx", "/var/www/html"]
# Copy start.sh script and define default command for the container
COPY start.sh /start.sh
CMD ["./start.sh"]
# Expose Port for the Application
EXPOSE 80 443
file=/dev/shm/supervisor.sock ; (the path to the socket file)
[supervisord]
logfile=/var/log/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trace)
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)
user=root ;
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///dev/shm/supervisor.sock ; use a unix:// URL for a unix socket
[include]
files = /etc/supervisor/conf.d/*.conf
[program:php-fpm7.4]
command=/usr/sbin/php-fpm7.4 -F
numprocs=1
autostart=true
autorestart=true
[program:nginx]
command=/usr/sbin/nginx
numprocs=1
autostart=true
autorestart=true
다음과 같이 start.sh 파일을 생성한다.
#!/bin/sh
/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
다음과 같이 실행권한으로 변경한다.
chmod +x start.sh
docker image ls
도커는 이를 위해 볼륨(volume), 바인드 마운트(bind mount) 두 가지 방법을 제공한다.
볼륨은 다음과 같은 명령으로 생성한다. 이를 통해 다중 도커 이미지 간 폴더 파일들을 함께 공유할 수 있다.
docker volume create
예를 들어 다음과 같이 볼륨을 생성하고, 도커를 실행하면, myvol이 도커 /app와 연결된다.
docker volume create my-vol
docker run -d --name devtest --mount source=myvol, target=/app nginx:latest
볼륨 저장 위치는 다음 명령으로 알 수 있다.
docker inspect my-vol
바인드 마운트는 호스트 파일 시스템의 중요 시스템 변경이 가능하다. 바인드를 위해서, 다음 $(pwd)부분을 현재 바인드할 폴더명령 입력한다. 다음 예는 ngnix 서버를 실행하며, 영구 저장할 파일이 보관될 곳으로 $(pwd)와 /app를 서로 바인딩하는 예이다.
docker run -d -it --name devtest --mount type=bind, source="$(pwd)"/target, target=/app nginx:latest
이를 통해, 도커 이미지를 종료하더라도 이미지에서 생성, 수정한 파일을 영구 보관할 수 있다. 다음 링크는 mysql database file을 마운트를 통해 영구 보관하는 방법을 보여준다.
지금까지 도커 개발 방법을 간단히 살펴보았다. 도커는 운영체계 라이브러리에 의존하므로, 윈도우에서는 아직 NVIDIA GPU 도커가 동작하지 않는다. 즉, GPU 모드 딥러닝 프레임웍을 사용할 수가 없다. 여기서는 NVIDIA GPU 우분투 도커 버전을 간략히 설명한다.
이 도커는 아래 구조로 동작한다.
NVIDIA GPU 도커 이미지는 우분투 16.04, 18.04, 20.04에서 동작한다.
다음 명령을 통해 NVIDIA GPU 도커를 설치한다.
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker
# Add the package repositories
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
zypper ar https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo
sudo zypper install -y nvidia-docker2 # accept the overwrite of /etc/docker/daemon.json
sudo systemctl restart docker
다음과 같이 사용한다.
#### Test nvidia-smi with the latest official CUDA image
docker run --gpus all nvidia/cuda:10.0-base nvidia-smi
# Start a GPU enabled container on two GPUs
docker run --gpus 2 nvidia/cuda:10.0-base nvidia-smi
# Starting a GPU enabled container on specific GPUs
docker run --gpus '"device=1,2"' nvidia/cuda:10.0-base nvidia-smi
docker run --gpus '"device=UUID-ABCDEF,1"' nvidia/cuda:10.0-base nvidia-smi
# Specifying a capability (graphics, compute, ...) for my container
# Note this is rarely if ever used this way
docker run --gpus all,capabilities=utility nvidia/cuda:10.0-base nvidia-smi
1. 컨테이너 목록 확인하기
$ docker ps -a
2. 컨테이너 중지하기
$ docker stop ${container ID}
3. 컨테이너 제거하기
$ docker rm ${container ID#1} ${container ID#2}
4. 이미지 목록 확인하기
$ docker images
5. 이미지 다운로드 하기
$ docker pull
6. 이미지 삭제하기
$ docker rmi ${image ID}
7. 컨테이너 로그 보기
$ docker logs --tail 10 ${container ID}
8. 실시간 컨테이너 로그 보기
$ docker logs -f ${container ID}
9. 실행중인 컨테이너에 명령 실행하기
$ docker exec [option] container command [arg ...]
run은 새로 컨테이너를 만들어 실행하고, exec는 실행 중인 컨테이너에 명령을 실행하는 차이이다.
다음은 MySQL 컨테이너의 /bin/bash 쉘을 실행하는 예이다.
$ docker exec -it mysql /bin/bash
10. 도커 컨테이너 업데이트
도커에서 컨테이너를 업데이트할 때 컨테이너에 생성된 파일은 모두 삭제될 수 있다. 그러므로, 유지해야 할 데이터가 있는 경우, 컨테이너 내부가 아닌 외부 스토리지에 저장해야 한다.
11. 도커 컴포즈
도커 컴포즈 툴을 이용해, 도커 명령을 하나의 설정으로 간편하게 처리할 수 있다. 자세한 내용은 다음 링크를 참고한다.
기타 도커에서 생성된 데이터를 보관하려면 호스트 드라이버와 연결해 데이터를 저장하거나, 도커 볼륨을 생성해 그 위에 도커를 생성해 사용해야 한다. 그냥 도커를 실행한 후 종료하면 그 동안 작업된 데이터는 삭제된다는 것을 주의해야 한다. 관련 내용은 아래를 참고한다.
레퍼런스
- Installing TensorFlow on Ubuntu
- Docker data save
- 도커 간단한 이미지 개발 및 빌드 방법
- 도커 GPU 버전 설치하기
- Docker Nginx server build
- 도커로 우분투, 아파치, PHP 이미지 만들기
- 도커로 Nginx, Node 서버 빌드 및 배포
- NVIDIA GPU docker usage
- NVIDIA GPU docker usage, 2019
- Kubernetes Tutorial for Beginners: Basic Concepts (spacelift.io)
- Understanding Docker Layers for Efficient Image Building