开始使用Docker部署之后,感觉相见恨晚。我现在开始尽量将之前应用的服务都改成以docker方式部署。这篇文章的讲的是如何用Docker来搭建一个Tensorflow + Jupyter。以及,如何对容器进行改造的问题。
Prerequisite
你需要安装好docker的环境。具体的方法参见安装Docker。
安装Tensorflow + Jupyter
安装nvidia-docker
nvidia-docker是面向Docker引擎的NVDIA GPU工具,这里列出在Ubuntu 64bit上的安装方法:
# If you have nvidia-docker 1.0 installed: we need to remove it and all existing GPU containers
docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f
sudo apt-get purge -y nvidia-docker
# Add the package repositories
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/ubuntu16.04/amd64/nvidia-docker.list | \
sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
# Install nvidia-docker2 and reload the Docker daemon configuration
sudo apt-get install -y nvidia-docker2
sudo pkill -SIGHUP dockerd
# Test nvidia-smi with the latest official CUDA image
docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi
安装和运行tensorflow镜像
Tensorflow拥有官方镜像tensorflow/tensorflow,官方文档给出的运行命令是
$ nvidia-docker run -it -p 8888:8888 tensorflow/tensorflow:latest-gpu
了解Docker运行方式的朋友应该知道Docker是为了一个单一主进程而生的,tensorflow本身是一个开发环境和工具,但是却不是一个独立进程。事实上这个镜像的主进程是Jupyter。在运行上述命令后,你可以在http://your_ip:8888
处访问Jupyter。不过光靠这个命令还不太适宜实际的运行环境。存在如下的几个问题:
- 这个命令以
-it
方式运行,会在terminal退出以后中断进程。我们在实际使用时,一般希望其作为daemon进程一直运行下去 - 没有挂载数据卷,将来想要上传数据比较麻烦
- Jupyter使用token方式访问,没有指定密码
所以我在部署自己的tensorflow业务时,会采用下面形式的命令
nvidia-docker run -e PASSWORD=your_jupyter_passwd \ # set password
-d \ # run as daemon
-p 8888:8888 \ # port binding
--name tensorflow \
-v /data/dir/on/host/:/data/ \ # bind data volume
tensorflow/tensorflow:latest-gpu
如果我们想把数据卷以只读方式绑定到容器内,-v
后的参数修改为/data/dir/on/host/:/data/:ro
。这样,可以保证容器在运行过程中,不会因为误操作或者其他原因导致数据损坏。
进一步定制(Optional)
在使用这个tensorflow镜像的过程中,你可能会需要做如下的改进:
修改Jupyter默认启动的terminal所使用的shell
在前面我们提到过了,这里我们使用的镜像的主进程是Jupyter,事实上,docker在从此镜像启动容器的过程中,实际使用的是可以在容器中找到的/run_jupyter.sh
脚本。想要修改Jupyter默认启动terminal所使用的shell,最简单的方法是在此脚本中设置SHELL
环境变量。通过Jupyter启动terminal或者是docker exec -it tensorflow bash
的方法进入容器,然后编辑/run_jupyter.sh
,在jupyer notebook "$@"
之前添加
export SHELL=/bin/bash
这里使用了bash,如果你想要使用其他的shell,可以替换成其他的值。修改完成后,通过docker container restart tensorflow
重启容器来应用更改。
使用Anaconda
Anaconda是非常流行的用于Data Science的Python“工具包”。如何在Jupyer中创建基于Anaconda的Python程序呢?其实突破口还是在/run_jupyter.sh
这个文件上。首先在容器内安装Anaconda,然后编辑/run_jupyter.sh
文件,将
jupyter notebook "$@"
修改为
/path/to/anaconda/bin/jupyter notebook "$@"
修改完成后重启容器。