服务器深度学习环境搭建+docker使用

总结下在实验室的服务器上搭建深度学习环境的过程,并通过docker创建不同开发需求的环境,实现本地远程连接。

安装Ubuntu系统

首先要给服务器安装Linux系统,这里安装的是Ubuntu 20.04,安装教程网上一大堆不做赘述了。安装完后要对系统进行一些配置:

更换软件源

  1. 备份原来的源,将以前的源备份一下,以防以后可以用的。

sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup

  1. 打开/etc/apt/sources.list文件,在前面添加如下条目,并保存。

sudo vi /etc/apt/sources.list

# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse

# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
  1. 更新源和软件

sudo apt-get update

sudo apt-get upgrade

配置SSH 连接

  • 查看是否安装了ssh-server服务。默认只安装ssh-client服务。
    dpkg -l | grep ssh

  • 安装ssh-server服务

    sudo apt-get install openssh-server

  • 确认ssh-server是否启动了:

    ps -e | grep ssh

如果没有可执行sudo service ssh start,完成之后就可以SSH登录服务器(推荐使用MobaXterm)

挂载机械硬盘

服务器一般都有一块固态和一个大容量的机械硬盘,我在固态上安装系统,机械硬盘则用来存放大的文件比如数据集。

  • 查看磁盘容量及分区状况(可以查看未挂载分区):sudo lsblk -f

  • 将机械硬盘格式化为 ext4: sudo mkfs.ext4 /dev/sda

  • 挂载硬盘:

  sudo mkdir /home/用户名/hhd
  sudo mount /dev/sda /home/用户名/hhd
  df -Th  # 磁盘容量及分区状况(不能查看未挂载分区)
  • 设置开机自动挂载,编辑 /etc/fstab ,在其内容中追加/dev/sda /home/用户名/hhd ext4 defaults 0 0
  • 重启后验证:lsblk -f

经常需要使用ssh工具传输文件,对挂载的目录添加写入权限:sudo chmod 777 目录名。注意必须要精确到改目录下(改变其上级目录权限都不行)

使用Docker创建多个深度学习工作环境

通常实验室会有多人使用服务器,为此我们需要服务器能给每个用户分配一个干净的运行环境。

主流的工具是conda、virtualenv以及docker。相比较于前两者主要用来隔离python不同版本的虚拟环境;有时候我们的开发环境并不只是用到python,比如有的native库需要对应gcc版本的编译环境,或者进行交叉编译时会安装很多工具链等等。如果这些操作都在服务器本地上进行,那时间久了就会让服务器的文件系统非常杂乱,而且还会遇到各种软件版本冲突问题。这时候docker就可以发挥用场了,只需要在本机安装显卡驱动,其他的操作在docker镜像里已

安装Nvidia显卡驱动

禁用secure boot

联想的设备开机F2禁用BIOS的secure boot,即disable它,如果不关闭,使用第三方源安装显卡驱动会安装后不能使用。

禁用nouveau

打开终端,输入:

sudo vi /etc/modprobe.d/blacklist.conf 

在blacklist.conf文件末尾加上这两行,并保存:

blacklist nouveau
options nouveau modeset=0

然后执行命令:

sudo update-initramfs -u  //应用更改

安装驱动

这里我们通过命令行安装,需要使用到aptitude工具,首先进行安装:sudo apt-get install aptitude

输入ubuntu-drivers devices查看当前机器支持的驱动,选择recommended那项执行安装,例如:

sudo aptitude install nvidia-driver-470 --without-recommends

使用–without-recommends可以只安装需要的东西,节省空间。

结束后输入nvidia-smi即可查看显卡信息

安装docker和nvidia-container-toolkit

为了在docker中支持GPU,NVidia之前是弄了个nvidia-docker2,现在升级为NVIDIA Container Toolkit了。

安装教程

Docker Hub 中提供了非常多的高质量的官方镜像,可以直接从上面选择你需要的镜像拉取到本地作为基础镜像 。国内从 Docker Hub 拉取镜像有时会遇到困难,需要配置docker镜像加速。

以下列举了docker常用的操作指令,更多运行指令可点击

docker ps -a	# 查看所有的容器信息
docker ps 	# 查看所有运行的容器
docker stop <容器 ID>	# 停止一个容器
docker start <容器 ID> / <容器名> # 重新启动已经停止的容器
快捷键ctrl + P + Q(必须是大写模式下):使容器不停止退出到宿主机的terminal界面。
docker attach <容器 ID> <容器名> # 附着到已经运行的容器,会沿用docker run命令时的参数
docker rm <容器 ID>	# 删除一个容器

解决docker默认安装空间不足导致无法安装镜像

容器创建与配置

容器创建

这里推荐使用deepo这样一款中国人做出来的深度学习镜像,包含了现在多数流行的深度学习框架。

在下载好deepo镜像后,输入以下命令创建一个容器:

sudo docker run -it --gpus all --ipc=host -p 6666:8888 -p 6022:22 -v /mnt/hhd:/workspace --name zhangwen_dp ufoym/deepo:all-jupyter-py36-cu111 /bin/bash
  • -it:进入交互模式,启动bash
  • --gpus all:宿主机全部GPU可供容器使用
  • --ipc=host:容器共享宿主机内存
  • -p 7777:8888 -p 8022:22 :端口映射,主要是两个目的:
    • 通常我们需要安装jupyter notebook进行处理,其默认为容器的8888端口,将它映射到宿主机7777端口,
    • 将ssh服务的22端口映射到宿主机的8022端口,之后可通过vscode访问到服务器上运行的镜像环境
  • -v /mnt/hhd:/workspace:深度学习框架的docker镜像都默认带有/workspace目录,可实现和宿主机的指定目录(我把它设置为之前机械硬盘挂载的目录)进行文件共享
  • --name:对容器命名

设置以root账户ssh连接

  • 设置 root 账户密码:

    passwd root
    
  • 很多镜像都不会默认安装 ssh,所以需要在容器内安装 ssh 服务:

    apt update && apt install -y openssh-server
    
  • 一般进入容器时使用的都是 root 账号,但是 ssh 默认是禁止 root 账号使用密码远程登录的,所以需要修改 ssh 配置文件使其允许:

    vim /etc/ssh/sshd_config 
    
    # 修改如下两处地方,允许root用户以任何认证方式登录(用户名密码认证和公钥认证)
    #PermitRootLogin without-password 改为 PermitRootLogin yes
    #PasswordAuthentication yes 改为 PasswordAuthentication yes
    

需要注意的是由于ssh配置文件的权限是只读,vim编辑后,退出时需要输入:wq!强制保存更改

编辑完后确认ssh-server是否启动了:ps -e | grep ssh。 如果没有可执行service ssh start

配置jupyterlab

插件支持

jupyter lab支持许多插件,一般需要安装node.js才能使用:

# 安装nod.js 14.x版本
curl -fsSL https://deb.nodesource.com/setup_14.x | bash -
apt-get install -y nodejs

设置jupyter登录密码

# 生成配置文件
jupyter lab --generate-config

# 进入python或ipython,设置密码,并记录
from notebook.auth import passwd
passwd()

保存生成的密钥 'argon2:$argon2id$v=19$m=10240,t=10,p=8$VYZtIvepEs0vp85l5HUgDg$B3Kjge2nLIrlDxNY6gYRGw'

修改配置文件

vim /root/.jupyter/jupyter_lab_config.py

# 添加内容如下:
c.NotebookApp.password = 'argon2:$argon2id$v=19$m=10240,t=10,p=8$VYZtIvepEs0vp85l5HUgDg$B3Kjge2nLIrlDxNY6gYRGw'	#秘钥
c.NotebookApp.ip='0.0.0.0' 	# *允许任何ip访问
c.NotebookApp.open_browser = False	# 默认不打开浏览器
c.NotebookApp.allow_remote_access = True
c.NotebookApp.notebook_dir = '/mnt/hhd' # 修改为之前设置于宿主机共享的路径

在容器内启动:jupyter lab --allow-root,然后在服务器的浏览器里打开映射端口:127.0.0.1:7777输入密码就能访问。

正常退出不关闭容器,请按Ctrl+P+Q

通过VsCode实现远程连接

  • 使用 VSCode 连接,添加新的 ssh host 的时候地址这么写:ssh root@your-server-ip -p 8022,这个 8022 就是启动容器的时候设置的映射端口。之后输入root账户密码即可,和正常的连接远程服务器一样。
  • 连接到容器后,输入jupyter lab --allow-root启动容器内的jupyter,在VsCode终端设置端口转发规则,即可把jupyter默认端口转发到本地指定端口打开。

内网穿透实现公网地址访问

通常服务器是放在实验室的局域网的,如果我们在局域网外就没法进行访问了。为此可以使用frp之类的软件做反向代理来实现内网穿透,这个方案需要你先准备一台带公网IP的云服务器(我用的是阿里云的ECS),优点就是完全可控,自己想配置多少个端口的穿透都可以,速度跟你的云服务器带宽有关。

frp分为frps(server)和frpc(client)两个包 ,其中前者安装到我们的云服务器上,后者安装在需要被外网访问到的各个设备上,这里就是指我们的深度学习工作站。
服务器深度学习环境搭建+docker使用_第1张图片

阿里云ECS配置:

在这里下载适合你服务器系统的frp软件,之后解压:

tar -zxvf frp_0.37.0_linux_amd64.tar.gz

解压之后的文件夹中既包含了服务端的文件又包括客户端的文件,这里所有 frpc 开头的文件都是客户端文件,强迫症可以全部删了,在云服务器只需要保留 frps 开头的文件。

修改frps.ini文件如下(注意删除中文注释):

[common]
# frp server的工作端口,默认7000,可以更改
bind_port = 7000

# http和https的端口定义
vhost_http_port = 80
vhost_https_port = 443

# dashboard图形管理页面使用端口
dashboard_port = 7500

# dashboard帐号
dashboard_user = admin
# dashboard登陆密码,可以自己修改,这里用admin
dashboard_pwd = admin

更多帮助见frp帮助文档:传送门

注意:以上端口都需要去阿里云控制台打开对应端口

服务器深度学习环境搭建+docker使用_第2张图片

内网的深度学习服务器端配置:

  1. 安装相应版本的frpc软件包(同上一步)
  2. 修改frpc.ini配置文件,内容如下:
[common]
server_addr = 101.201.71.144    # 填写自己的云服务器公网IP地址,有域名的读者也可以填写域名
server_port = 7000       # 云服务器设置的端口为7000,所以这里填7000
# token = 000000         # 与frps.ini设置的token一致,没设置则删去

[ssh]
type = tcp
local_ip = 127.0.0.1	# 计算机网络中,127.0.0.1代表本地地址
local_port = 22			# 需要映射出去的端口号,80为http默认端口号,此端口号必须被本机放行
remote_port = 20022		# 映射到云服务器上面的端口号,同理需要在阿里云的控制台开放

通过上述的设定,就把对于云服务器特定端口的访问给重定向到本地服务器的某个端口了,简单地讲就是:假如我用SSH客户端访问 [ECS 公网ip]:20022,就可以经过反向代理直接访问到[本地的深度学习服务器ip]:22

设置frp开机启动

  1. 配置frp 服务端,sudo vim /lib/systemd/system/frps.service写入以下内容
[Unit]
Description=Frp Server
After=network.target syslog.target
Wants=network.target 

[Service]
# frp启动时,网络可能还没准备好,导致frp启动失败,当frp服务启动失败时,时隔5秒后重新启动它
Restart=always
RestartSec=5

#启动服务的命令(此处写你的frps的实际安装目录,删除注释)
ExecStart=/frp_0.37.0_linux_amd64/frps -c /frp_0.37.0_linux_amd64/frps.ini

[Install]
WantedBy=multi-user.target

然后刷新配置

systemctl daemon-reload

启动frps
systemctl start frps
再打开自启动
systemctl enable frps

  • 如果要重启应用,可以这样sudo systemctl restart frps
  • 如果要停止应用,可以输入sudo systemctl stop frps
  • 如果要查看应用的日志,可以输入sudo systemctl status frps
  1. 同理,配置frp 客户端,sudo vim /etc/systemd/system/frpc.service 写入以下内容
[Unit]
Description=Frp Client
After=network.target syslog.target
Wants=network.target 

[Service]
# frp启动时,网络可能还没准备好,导致frp启动失败,当frp服务启动失败时,时隔5秒后重新启动它
Restart=always
RestartSec=5

#启动服务的命令(此处写你的frpc的实际安装目录,删除注释)
ExecStart=/home/yf703a/frp_0.37.0_linux_amd64/frpc -c /home/yf703a/frp_0.37.0_linux_amd64/frpc.ini 

[Install]
WantedBy=multi-user.target

同理,刷新配置

systemctl daemon-reload

启动frpc
systemctl start frpc
再打开自启动
sudo systemctl enable frpc

完成这些配置后,现在可以通过ssh -p [端口] [用户名]@[公网IP],在任何网络下连接到内网的机器:
注意: 这里的用户名是内网主机的用户名,不是公网服务器的用户名,我就是掉这坑里了,端口号为设置的远程端口(即上面设置的20022)

如果需要使用内网穿透方式访问jupyter,我们可以把服务器的7777端口映射到阿里云服务器上,实现在公网访问jupyter。修改frps.ini文件如下(注意删除中文注释):

[jupyter]
type = tcp
local_ip = 127.0.0.1	
local_port = 7777	
remote_port = 27777			# 记得去阿里云开启端口

你可能感兴趣的:(ubuntu,docker,深度学习)