【入门向】搭建一个自己的docker容器【集群】【SSH】【Docker Hub】


我们已经知道可以根据一个现有的镜像创建容器,这个容器同时封装了项目工程所需的依赖和运行环境,当我们准备在不同的集群上运行程序时,无需重新配置环境,只需要把一个配置好的镜像pull下来,就可以直接用了。
基于镜像A创建一个容器b,在b内进行一系列操作(安装各种依赖环境),根据b再创建一个新的镜像B,将B push到Docker Hub上,就实现了对容器b的备份。具体操作过程见下文。

1 pull一个(官方)镜像

在Docker Hub上pull一个官方镜像,也可以是其他用户的镜像,但是具体内部配置是否能够满足你的使用需求就不确定了,因此最好pull官方的再自行修改。
nvidia/cuda的Docker Hub官方账号:https://hub.docker.com/r/nvidia/cuda/tags

docker pull [OPTIONS] IMAGE_NAME[:TAG]

sudo docker pull nvidia/cuda:11.3.1-cudnn8-devel-ubuntu18.04

docker指令前基本都要加sudo,后文省略sudo,实际使用时别忘记加上!

根据项目所需的cuda版本在Docker Hub的nvidia官方账号下选择要pull的镜像,有runtime和devel两个版本,两者最直观的区别就是大小,有的还有base版本,具体差异参考附录,这里我们选择devel版本,Ubuntu也是和本机操作系统相同的18.04版本。runtime or devel

在执行完上述指令后,检查镜像是否成功地pull下来了:

docker image ls -a

2 基于镜像创建一个容器

run是创建并运行一个容器:

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

docker run -it -name gait nvidia/cuda:11.3.1-cudnn8-devel-ubuntu18.04 bash

如果一个容器已经存在(之前创建好的,被临时关闭或退出),则使用start指令:

docker start [OPTIONS] CONTAINER [CONTAINER...]

docker start -i gait
docker start gait

前者 -i 进入交互模式,后者是在后台启动容器,不进入交互端。

3 配置容器

现在我们基于镜像创建了一个新的容器,容器里面所需要的依赖都还没有,可以使用inspect查看容器信息(返回好多内容,暂时还都看不太懂):

docker inspect [OPTIONS] NAME|ID [NAME|ID...]

docker inspect gait

配置容器前先检查基于的镜像是否正确,键入:

nvcc -V

返回cuda信息

3.1 安装python

这一步或许可以省略
更新软件包列表和系统:

apt update
apt upgrade

3.1.1 安装构建工具和依赖

安装一些常见的开发和构建工具以及依赖库:

apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev wget

3.1.2 下载并解压python源代码包

wget https://www.python.org/ftp/python/3.8.16/Python-3.8.16.tgz
tar -xf Python-3.8.16.tgz

3.1.3 进入源代码目录并配置安装选项

cd Python-3.8.16
./configure --enable-optimizations

3.1.4 编译并安装python

make altinstall

这里使用altinstall而非install,可以避免替换系统默认的python版本

3.1.5 检验是否安装成功

python3.8 --version

3.2 安装torch及相关配置

推荐使用whl方式安装,这样会更稳定,不用考虑远程挂代理安装下载慢之类的问题。

3.2.1 安装pip

apt-get install -y python3.8-pip

这里我用的apt-get,其实应该用apt的

3.2.2 安装torch

在官网上找到所需版本的whl文件,本地下载再上传到服务器,最后从服务器copy到容器中

docker cp [OPTIONS] SRC_PATH DEST_PATH

※更新pip(之前版本的pip不能用install指令安装whl文件,不清楚是什么原因,更新一下就好了)

python3.8 -m pip install --upgrade pip
pip install torch-1.10.0+cu113-cp38-cp38-linux_x86-64.whl

检查是否安装成功

python3.8
import torch
print(torch.cuda.is_avalibale())

返回True就对了(也可以pip list看一下)

3.3 安点别的

pyyaml、tensorboard、opencv-python、tqdm、kornia

pip install pyyaml==6.0 tensorboard==2.11.0 opencv-python==4.6.0.66 tqdm==4.64.1 kornia==0.6.10

4 将容器打包成镜像push到Docker Hub上

记得login一下你的Docker Hub账号,前面login或者在这一步都可以

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
docker push [OPTIONS] NAME[:TAG]

docker commit gait gait_img:v1.0
docker tag gait_img:v1.0 carrothu0727/gait_img:v1.0
docker push carrothu0727/gait_img:v1.0

冒号后面是tag标签,如果没有指定标签,默认是latest

5 集群提交作业,运行报错,补充安装依赖

5.1 集群提交作业

5.1.1 基本设置

基本设置

任务名称: 一般默认,也可以改成自己便于查看的名称
资源池: claster cloud
多机多卡: 单机(以单机为例)

5.1.2 任务设置

任务设置1

任务设置2

任务角色名称: 默认(没法改)
资源规格: 应该是哪个能用就选哪个,这里我就随便选了
Docker镜像: 如果之前有作业打包容器存储到集群平台上了,可以在下拉菜单里直接选择;如果没有,把右侧的选择开关关掉,输入Docker Hub里的镜像名给它pull下来
命令: 默认sleep infinity

5.1.3 存储配置

存储配置

新增一个存储卷,下拉菜单选存储节点,存储卷里存放和工程相关的数据集、代码……默认路径是/root/data1
可以自行修改成便于记忆的名称,只有在这一步可以显式地看到路径,提交作业之后还得现查,别忘了。
这里的/root/data1是挂载点,挂载指的是将设备文件中的顶级目录连接到Linux根目录下的某一目录(这个目录最好是空目录),访问此目录就等同于访问设备文件。

5.1.4 环境变量配置

默认就行,都不用选环境变量配置

以上4步(5.1.1~5.1.4)完成后,作业状态显示 “创建中”,一般需要等待10~30分钟不等,时间长短与镜像大小有关。
创建中

请添加图片描述

创建完成后会显示 “运行中”,这样一个作业就提交成功了!
运行中

5.2 运行报错及解决方式(跳过)

下面是针对我这个工程文件运行时出现的一些error,纯记录,大家跳过就可以了,因为每个工程文件可能会出现不一样的错误,对症下药即可~

ERROR1——没有_bz2

ModuleNotFoundError: No module named '_bz2'

从系统的python3.8文件中复制到local文件夹下的python3.8文件中,缺啥补啥。

ERROR2——没有_lzma

ModuleNotFoundError: No module named '_lzma'

解决方法同上。

ERROR3——CUDA OOM

RuntimeError: CUDA out of memory.

这是一个大问题,参考这篇文章:
通过设置PYTORCH_CUDA_ALLOC_CONF中的max_split_size_mb解决Pytorch的显存碎片化导致的CUDA:Out Of Memory问题

ERROR4——cuDNN找不着

RuntimeError: Unable to find a valid cuDNN algorithm to run convolution

有很多种原因会导致这种报错,有人说改小batch就行,我忘了最终怎么解决的了,应该就是改batch……

ERROR5——没有ANTIALIAS

AttributeError: module'PIL.Image'has no attribute'ANTIALIAS'

最新版本的pillow没有’ANTIALIAS’,需要降低版本:

pip install pillow==9.4.0

0 ssh连接集群

当我们前面的准备安装配置工作都完成了,就可以在网页上直接打开终端(也就是进入集群中的容器)运行程序了,算是“大功告成”了!但是有一点不容忽视,网页连接不稳定,经常出现终端窗口莫名其妙失去连接的情况,一方面我们可以使用tmux终端复用工具,避免一断连接啥都没了;另一方面更推荐使用ssh连接,不用网页直接连接了,下面简单介绍安装和配置ssh,以及pycharm ssh连接到集群的过程。

0.1 docker容器内安装ssh

还是在本地一开始自己配的那个容器里,不是集群上的那个,集群容器关了下次就没了。
原教程使用的是apt-get,这个是比较旧的包管理工具,现在更推荐使用apt!

apt update
apt install openssh-server

0.2 设置root密码

这个密码在后面本地pycharm远程连接集群的时候要用到

passwd

0.3 修改配置文件

vim /etc/ssh/sshd_config

注释掉PermitRootLogin prohibit-password,这句表示禁止以root用户身份使用密码进行ssh登录;
添加PermitRootLogin yes,这句话表示允许以root身份ssh登录。

0.4 重启ssh服务

/etc/init.d/ssh restart

至此,我们完成了一个具有ssh连接功能的容器,按照上文步骤把它push到Docker Hub中,再进行后文操作。

0.5 集群提交作业时暴露ssh端口

请添加图片描述
在命令中添加一条ssh开机自启动:

/etc/init.d/ssh restart && sleep infinity

新增端口设置
服务: 其他
容器端口: 22(容器默认端口是22,这一点可以参见附录SFTP连接的介绍)
主机端口: 11111(自己随便输一个就行,在pycharm配置的时候会用到)

0.6 pycharm配置ssh连接

请添加图片描述

Type: 选SFTP
Host: 集群容器ip(就是集群上的主机IP)
User name: root
Password: 就是前面设置过的
以上内容填写完毕后Test Connection一下,成功!

附录1:runtime、devel、base的区别

runtime devel base
是用于运行已编译的应用程序的软件包版本。它通常包含了应用程序所需的最低限度的运行时库和依赖项,以确保应用程序能够在目标系统上正常运行。运行时库包含了程序在运行时所需的函数和资源。 是用于开发和编译软件的软件包版本。它包含了编译和构建应用程序所需的头文件、静态库、动态库和其他开发工具。开发版本的软件包让开发人员能够在其系统上编译和测试应用程序。 是最基本的软件包版本,包含了最少的文件和功能,通常是用于构建其他版本的基础。
一般不包含用于开发的头文件、静态库等,因为这些对于正常运行应用程序并不是必需的。 通常包含了与运行时库对应的开发文件,以便开发人员能够链接和使用这些库。 可能包含一些核心库和工具,但通常没有运行时库或开发工具。它可以作为其他版本的基础,根据需要安装其他组件以实现特定的功能。

总的来说,runtime 版本用于运行应用程序,devel 版本用于开发和编译应用程序,而 base 版本是最基础的版本,作为其他版本的基础。在进行软件开发和部署时,根据需要选择合适的版本,以满足开发和运行的需求。
内存大小:devel>runtime>base

附录2:FTP、FTPS、SFTP的区别

FTP(File Transfer Protocol),FTPS(FTP over SSL/TLS),SFTP(SSH File Transfer Protocol)是用于文件传输的不同协议,它们之间的区别如下:

FTP(File Transfer Protocol) FTPS(FTP over SSL/TLS) SFTP(SSH File Transfer Protocol)
是一种使用明文传输的标准网络协议,用于在客户端和服务器之间进行文件传输。 FTPS是FTP的扩展,通过在FTP上层添加SSL/TLS加密层来提供安全的文件传输。 SFTP是通过SSH(Secure Shell)协议在安全通道上进行文件传输的协议。
FTP不提供加密功能,意味着文件和凭据在传输过程中可能会以明文形式传输,存在安全风险。 FTPS使用SSL/TLS加密保护控制连接和数据连接,确保传输的机密性和数据完整性。 SFTP使用SSH会话进行身份验证和数据加密,提供了对文件传输的安全保护。
FTP使用两个独立的连接(控制连接和数据连接)来进行文件传输。 FTPS使用的默认端口号是990(控制连接),和FTP相同的数据连接端口(通常是20),需要服务器具有SSL/TLS证书,以提供加密和身份验证。 SFTP使用单个连接,既用于控制命令,又用于数据传输,通过SSH协议在安全通道中进行,使用的默认端口号是22,与SSH默认端口一致。

总结:
FTP是最基本的文件传输协议,不提供加密功能;
FTPS通过添加SSL/TLS层在FTP上提供了加密和安全性;
SFTP是使用SSH协议进行加密和安全文件传输的协议。

参考博客:

通过设置PYTORCH_CUDA_ALLOC_CONF中的max_split_size_mb解决Pytorch的显存碎片化导致的CUDA:Out Of Memory问题

AttributeError: module ‘PIL.Image‘ has no attribute ‘ANTIALIAS‘

【docker-cuda】——base,runtime,devel的区别

猜你喜欢

转载自blog.csdn.net/weixin_45074807/article/details/131812147