Nvidia-NGC容器使用全过程
NGC镜像下载
注册账户 https://ngc.nvidia.com/signup
注册,注意不要用google浏览器,否则收不到验证码
查看镜像仓库 https://ngc.nvidia.com/catalog/all 进入NGC界面即可看到由Nvidia官方封装的诸多镜像
查看所需镜像并拉取 以pytorch镜像为例 Terminal中下载该镜像
$ docker pull nvcr.io/nvidia/pytorch:19.09-py3
创建自定义镜像及自动备份
相关文件地址:https://github.com/y18810919727/Dgx-station_forum/
定制化容器为满足以下需求:
支持ssh进入容器(用于配置pycharm远程解释器)设置entrypoint自动打开所需服务
构建自定义镜像
此过程采用Dockerfile实现,以nvcr.io/nvidia/pytorch:19.09-py3为例 在宿主机内构建如下目录:
- ngc
- Dockerfile
- utils
- entrypoint.sh
- xxx.sh(其他脚本)
- utils.rar(把utils压缩成.rar)
建议把entrypoint.py文件和其他启动脚本放到utils压缩包里,压缩命令tar -cvf utils.tar utils。
在ngc路径下执行docker build -t image_name .命令即可创建自定义镜像,如:
docker build -t ngctorch_mine:1.0 .
Dockerfile和entrypoint.sh内容如下:
Dockerfile
FROM nvcr.io/nvidia/pytorch:19.09-py3
MAINTAINER yourname
# environment install
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
RUN apt-get update
RUN apt-get -y install sudo curl openssh-client openssh-server vim
# set root login
RUN echo "root:passwd123" | chpasswd
RUN sed -ri 's/^#PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config
# 网上搜到的多是下面这条命令,但是如果安装的ssh配置文件里面写的 #PermitRootLogin xxx 就会匹配不到,所以要加上面那句
RUN sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config
# port expose
EXPOSE 22 6006 8888
ADD utils.tar /root/
RUN chmod a+x /root/utils/entrypoint.sh
#python requirement list
RUN pip install numpy
RUN pip install opencv-python
ENTRYPOINT ["/root/utils/entrypoint.sh"]
entrypoint
#!/bin/bash
set -e
cat < ================ Your Name =============== EOF # jupyter 访问密码,自行修改 TOKEN='passwd123' # 容器内jupyter代码存放路径,自行修改 JUPYTER_DIR="/code" echo "总共参数: $#" echo "脚本名字: $0" service ssh start nohup jupyter notebook --no-browser --ip=0.0.0.0 --allow-root --NotebookApp.token="$TOKEN" --notebook-dir="$JUPYTER_DIR" & if [[ $# -eq 0 ]]; then exec "/bin/bash" else exec "$@" fi 容器定期备份与自启动 我们可以将代码文件和运行日志挂载到宿主机目录里,那为什么还要进行容器定期备份与自启动: 进行深度学习研究时经常需要额外装一些包,此部分无法挂载在外部,通过定期备份可依照装包之后的容器生成新的镜像。服务器、工作站如果出现宕机、断电等情况,可以自动恢复容器,省去人工操作。 创建启动与动备份脚本,ngc_backup.sh # 镜像定期备份脚本 # 将该脚本添加到crontab命令中实现定时启动,如: # 0 0 * * * /root/ngc_backup.sh # 该命令可以让工作站每天0点执行一次备份 # 宿主机文件路径 DATA_DIR="/home/jupyter_data" # 容器内文件路径 JUPYTER_DIR="/code" # 查找复合筛选规则的最新的容器,可以自定义grep规则,我这里是用jupyter端口 ngctorchid=`docker ps | grep '9909' | awk '{print $1}'` set -e if [ -z $ngctorchid ]; then # 说明容器不存在,使用最新image创建新容器 echo 'The ngctorch docker is not running, can not backup.' # 查找最新image latest_backup=`docker images | grep 'ngctorch' | awk '{print $3}' | head -n 1` echo 'Trying to back it online... from' $latest_backup # 创建容器 # 主机端口 | 容器端口 | 备注 # 9909 | 8888 | 用于浏览器访问jupyter # 8422 | 22 | 用于ssh直接进入容器,可以使用pycharm远程解释器 # xxx | xxx | 按照自己需求可配置其他端口映射 nvidia-docker run --rm -it -p 9909:8888 -p 8422:22 -v $DATA_DIR:$JUPYTER_DIR $latest_backup echo 'Done.' exit 0 fi # 容器正在运行,将当前容器备份为新镜像 docker commit $ngctorchid "ngctorch-backup:$(date +%m%d-%H%M)" # 删除旧镜像 # 存档镜像数量设定为1,除了当前最新的镜像,其他全部删除(当前镜像的祖先节点不会被删除) MAX_BACKUP_NUM=1 backupid=`docker images | grep 'ngctorch' | awk '{print $3}'` backupnum=`echo $backupid | wc -w` echo $backupid echo $backupnum if [ $backupnum -gt $MAX_BACKUP_NUM ]; then echo 'Delete old backup...' echo $backupid | tr ' ' '\n' | tail -n $(expr $backupnum - $MAX_BACKUP_NUM) echo $backupid | tr ' ' '\n' | tail -n $(expr $backupnum - $MAX_BACKUP_NUM) | xargs docker rmi fi echo 'Done.' 在容器未打开时可以直接运行该脚本以打开容器,运行该命令后,将直接进入容器的/bin/bash,可以按Ctrl+p+q退回宿主机切保持容器不关闭。 如果在/bin/bash中输入exit将使得终端窗口关闭,entrypoint运行结束,容器直接关闭。 创建crontab定时命令(每天备份一次) $ crontab -e #在下面添加 m h dom mon dow command 0 0 * * * /root/ngc_backup.sh $ service cron restart # 重启crontab $ service cron status # 查看crontab服务状态,active即为启动 这样系统每天会在半夜0点自动检查容易是否运行,如果不存在将自动创建容器。如果存在容器则将根据该容器生成docker 镜像,并删除当前使用镜像及其父节点以外的历史存储镜像。 什么是父节点镜像? 假如容器a生成于镜像A,现在使用容器a执行commit命令将生成镜像B。镜像A是B父节点。镜像删除规则: 如果镜像A是镜像B的父节点,则在B删除之前是无法删除镜像A的。因此上述脚本执行rmi命令时,由于最新镜像不会被删除,因此其祖先节点镜像将被全部保留保留如此多的镜像,是否会浪费过多存储空间: 不会,按上述方法新镜像的生成是增量的,都是在原镜像基础上铺上了一层,因此实际存储空间近似于最新的镜像大小。 Tips: 可通过docker system df命令查看总Images、Containers所占空间