Nvidia CUDA 開發環境 Docker 容器啟用顯卡
1. 準備 docker>19.03 環境,配置好 nvidia-container-toolkit 2. 確定本機已安裝的顯卡驅動版本,匹配需要的容器版本 3.Pull 基礎 docker 鏡像,可以從官方或者 dockerhub 下載 https://ngc.nvidia.com/catalog/containers/nvidia:cuda/tags https://gitlab.com/nvidia/container-images/cuda
cuda10-py36-conda 的 Dockerfile
FROM nvidia/cuda:10.0-cudnn7-devel-ubuntu18.04
MAINTAINER Limc #close frontend
ENV DEBIAN_FRONTEND noninteractive
add cuda user#
--disabled-password = Don't assign a password#
using root group for OpenShift compatibility#
ENV CUDA_USER_NAME=cuda10
ENV CUDA_USER_GROUP=root
add user#
RUN adduser --system --group --disabled-password --no-create-home --disabled-login $CUDA_USER_NAME
RUN adduser $CUDA_USER_NAME $CUDA_USER_GROUP
Install basic dependencies#
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
cmake \
git \
wget \
libopencv-dev \
libsnappy-dev \
python-dev \
python-pip \
#tzdata \
vim
Install conda for python#
RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-py37\_4.8.2-Linux-x86\_64.sh -O ~/miniconda.sh && \
/bin/bash ~/miniconda.sh -b -p /opt/conda && \
rm ~/miniconda.sh
Set locale#
ENV LANG C.UTF-8 LC_ALL=C.UTF-8
ENV PATH /opt/conda/bin:$PATH
RUN ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh && \
echo ". /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \
echo "conda activate base" >> ~/.bashrc && \
find /opt/conda/ -follow -type f -name '*.a' -delete && \
find /opt/conda/ -follow -type f -name '*.js.map' -delete && \
/opt/conda/bin/conda clean -afy
copy entrypoint.sh#
#COPY ./entrypoint.sh /entrypoint.sh
install#
#ENTRYPOINT ["/entrypoint.sh"]
Initialize workspace#
COPY ./app /app
make workdir#
WORKDIR /app
update pip if nesseary#
#RUN pip install --upgrade --no-cache-dir pip
install gunicorn#
RUN pip install --no-cache-dir -r ./requirements.txt#
install use conda#
#RUN conda install --yes --file ./requirements.txt
RUN while read requirement; do conda install --yes $requirement; done < requirements.txt
copy entrypoint.sh#
COPY ./entrypoint.sh /entrypoint.sh
install#
ENTRYPOINT ["/entrypoint.sh"]
switch to non-root user#
USER $CUDA_USER_NAME
運行容器 Makefile
IMG:=`cat Name`
GPU_OPT:=all
MOUNT_ETC:=
MOUNT_LOG:=
MOUNT_APP:=-v `pwd`/work/app:/app
MOUNT:=$(MOUNT_ETC) $(MOUNT_LOG) $(MOUNT_APP)
EXT_VOL:=
PORT_MAP:=
LINK_MAP:=
RESTART:=no
CONTAINER_NAME:=docker-cuda10-py36-hello
echo:
echo $(IMG)
run:
docker rm $(CONTAINER_NAME) || echo
docker run -d --gpus $(GPU_OPT) --name $(CONTAINER_NAME) $(LINK_MAP) $(PORT_MAP) --restart=$(RESTART) \
$(EXT_VOL) $(MOUNT) $(IMG)
run_i:
docker rm $(CONTAINER_NAME) || echo
docker run -i -t --gpus $(GPU_OPT) --name $(CONTAINER_NAME) $(LINK_MAP) $(PORT_MAP) \
$(EXT_VOL) $(MOUNT) $(IMG) /bin/bash
exec_i:
docker exec -i -t --name $(CONTAINER_NAME) /bin/bash
stop:
docker stop $(CONTAINER_NAME)
rm: stop
docker rm $(CONTAINER_NAME)
Entrypoint.sh
set -e
Add python as command if needed#
if [ "${1:0:1}" = '-' ]; then
set -- python "$@"
fi
Drop root privileges if we are running gunicorn#
allow the container to be started with `--user`#
if [ "$1" = 'python' -a "$(id -u)" = '0' ]; then
# Change the ownership of user-mutable directories to gunicorn
for path in \
/app \
/usr/local/cuda/ \
; do
chown -R cuda10 "$path"
done
set -- su-exec python "$@"
#exec su-exec elasticsearch "$BASH\_SOURCE" "$@"
fi
As argument is not related to gunicorn,#
then assume that user wants to run his own process,#
for example a `bash` shell to explore this image#
exec "$@"
幾個注意點 1. 顯卡運行需要 root 用戶權限,否則會出現以下, docker: Error response from daemon: OCI runtime create failed: container_linux.go:345 考慮安全性可以在容器內創建新用戶並加入到 root 組 2. 本機顯卡驅動和 CUDA 必須匹配官方容器的版本,cudnn 則不需要匹配,可以使用多個不同版本的 cudnn,但是必須滿足顯卡要求的使用範圍 3.docker 運行容器非正常結束時會佔用顯卡,如果卡死,會造成容器外部無法使用,重啟 docker-daemon 也無效,這時只能重啟電腦