搭建实验室公共GPU服务器
搭建需求,硬件配置,方案简介
搭建需求
实验室新进一台GPU服务器,带了两块Titan V,显存比单机多很多,公用的服务器总不能让同学一个一个轮流坐到电脑前操作,所以就有了多人同时使用的需求。
虽说Linux可以设置各种用户和权限、Anaconda可以建立各个虚拟环境,但难免遇到软件版本需求不同相互冲突、新手乱删文件等情况,最好还是给每个同学建立相互隔离的环境最舒服了,随便怎么折腾也不会干扰其他人。
具体的需求无非包括:
- 独立:不同用户的环境相互独立,不能互相访问,且可以同时使用。(唯一通道是共享文件夹)
- 隔离:用户是不可以访问宿主机的(唯一通道是共享文件夹)。
- 自由:用户可以像使用一台自己的Linux机器一样,方便访问,拥有最大的权限,自有安装程序、自由访问网络等等。(事实上,这种操作方式与购买GPU云主机的体验基本等同)
- GPU:最最重要的是每位同学能直接访问GPU。
- 可控:虽说要自由,但必要时候(同时使用的人太多),还是要能够限制每位同学的资源的(CPU,内存,GPU这些)
硬件配置
指标 | 参数 |
---|---|
CPU | Intel至强 E5-2680 v4 *2 |
GPU | NVIDIA TITAN V *2 |
Memory | 128G |
Disk | 480G SSD + 8T HDD + (4T RAID HDD) |
方案简介
鉴于之前搭建过一次GPU服务器的经历搭建公用GPU服务器过程记录 ,这次依旧采用LXD+ZFS的方案,即LXD做前端容器管理+ZFS做后端存储管理。虽然都说Docker这种方式是未来潮流,但我认为LXD/LXC并不差劲,且Docker的一应用一Docker的理念,可能与这种全权限访问容器主机的方式,是有本质上的区别的吧。
大致讲一下整个方案的流程:
- 宿主机安装Ubuntu18.04系统,安装GPU驱动。
- 安装LXD/ZFS软件并进行配置。
- 创建容器模板(Ubuntu16.04),包括:网络、GPU驱动、共享目录、SSH登录。
- 按需分配,克隆容器模板,并做个性化修改。
- 使用lxdui进行可视化容器管理。
第一步:安装系统、显卡驱动
系统
系统选择Ubuntu 18.04。
原因:Ubuntu 16.04下默认下载安装的是LXD2.0,LXD2.0不支持配置GPU到容器中,如果Ubuntu16.04需要配置GPU到容器,则需自行编译LXD3.0。而Ubuntu 18.04默认下载安装的则是LXD3.0的,安装方便。
安装完成后,注意将软件源配置为清华源,提高下载更新速度。具体步骤参考:Ubuntu 镜像使用帮助
GPU驱动
往常Linux下的GPU驱动安装是很复杂的,网上NVIDIA Driver教程百花绽放。经过实践发现,装完系统后,使用系统软件和更新
中提供的NVIDIA驱动是可行的,非常方便。
安装完成后,重启,输入nvidia-smi
进行确认,注意显卡驱动版本:
第二步:LXD/ZFS安装及配置
LXD软件安装
- LXD:用于创建和管理容器
- ZFS:用于管理物理磁盘,支持LXD高级功能,负责容器存储。
- Bridge-Utils:用于搭建网桥,负责容器上网。
运行命令进行安装:
1 | sudo apt-get install lxd zfsutils-linux bridge-utils |
配置
关于网络
需要注意的是,不同网络环境下,大家对于上网方式的诉求是不一样的。有些情况是希望用户在自己容器中登录校园网进行上网,有些情况则是上网免费,无所谓个人不个人。不同情况下,对于网络的配置是不同的。
目前我们是这样打算的,宿主机使用我的个人账号登录,每个容器就直接通过宿主机NAT上网,也不需要每个同学登录了,反正费用最后都能报销。对于较大的几十个G的数据集,则建议用户自己下载下来后,通过物理拷贝或者局域网内传输的方式上传到容器。
这种情况的下网络配置是最简单的,因为LXD默认初始化的网络方式就是:宿主机通过DHCP的方式给每个容器分配IP。如果上网方式跟我的相同的话,可以参考下节的配置。如果不是的话,请留意网络/网桥的配置
初始化LXD
运行sudo lxd init
进行LXD初始化配置,选项如下图:
- LXD Clustering:不需要
- new storage pool:需要创建一个存储池
- Name of storage pool:给存储池命名
- storage backend:存储后端,使用ZFS
- Create a new ZFS pool:需要创建一个ZFS池
- use an existing block device:Yes
Path to block device:使用已有的磁盘分区用于ZFS的存储后端。细节可以参考Be aware - MAAS server?:不知道是啥,不需要
- new local network bridge?:需要,我只需要使用LXD默认的网桥即可。
- new bridge be called:给网桥命名
- IPv4:默认auto
- IPv6:默认auto
- LXD available over the network?:默认no
- stale cached?:默认yes
- YAML printed?:打印信息,yes/no都行,原谅最后手抖的yno
测试
sudo zpool list lxd
查看ZFS的后端存储池。
sudo lxc info
查看LXD的配置信息。
sudo lxc profile show default
查看默认容器配置。
sudo lxc list
查看容器列表。
更多命令可以参考LXD Documentation
#第三步:创建容器模板
创建容器模板的意义在于:每次创建一个容器都需要重复大量工作(更新、配置GPU、共享目录、SSH登录等等),而创建容器模板以后,可以省去这些操作,利用LXD的克隆功能,复制一个容器稍作修改,就能成为用户独属的容器。
创建容器模板
LXC清华源
使用lxc清华源可以加速镜像的下载。LXC Images 镜像帮助
运行如下命令配置:
1 | # 创建一个remote链接,指向TUNA镜像站。 |
1 | # 查看镜像列表,寻找合适的镜像的FINGERPRINT,用于下载 |
下载创建
1 | # FINGERPRINT是镜像的指纹,在上条命令下查找,ContainerTemplateName为容器模板名称,自己定义。 |
运行 sudo lxc list
进行容器列表查看。
运行sudo lxc exec <ContainerTemplateName> bash
可进入容器的root用户下 bash。
可以使用su ubuntu
或 sudo su
进行用户切换。
如果容器下出现
sudo: no tty present and no askpass program specified
的问题。解决方式:
创建
/etc/sudoer.d/ubuntu
文件,编辑内容为
1 | ubuntu ALL=(ALL) NOPASSWD:ALL |
配置共享目录和GPU
共享目录设置
设置共享目录来实现宿主机与容器之间的文件传输。
1 | # 设置键值 |
GPU配置
添加GPU
1 | 为容器添加所有GPU: |
安装显卡驱动
还记得之前记录的宿主机显卡驱动的版本号码,根据版本号去官网下载驱动文件,通过共享目录传至容器中。
例如,宿主机中的NVIDIA Driver Version为390.77,则下载NVIDIA-Linux-x86_64-390.77.run
。
安装显卡驱动。
1 | 进入容器 |
运行nvidia-smi
进行确认。
配置SSH免密码登录
SSH免密登录网上资料一大把,有不明白的地方可以网上找。
###安装SSH服务
1 | 装OpenSSH服务 |
生成RSA文件
1 | 进入SSH目录 |
测试SSH
容器终端运行ifconfig
,确认容器IP和网段,这些是LXD自动分配的。如模板容器的IP为10.135.139.83。
宿主机终端运行ifconfig
,查看宿主机在网桥lxdbr0下的IP。如宿主机在该网段下的IP为10.135.139.1。
通过共享目录将SSH秘钥 id_rsa
文件拷贝到宿主机,宿主机运行如下命令登录容器:
1 | 给容器SSH秘钥文件合适权限 |
成功后,进行下一步frp的设置(端口转发)。
配置frp(内网穿透工具)
关于frp
根据上面的网络配置,可以看到,每个容器其实是处于宿主机构建出来的小型局域网内的,并不暴露在校园网内,也就是说用户从校园网是无法直接访问容器的。
一般来讲,要做的就是在宿主机上做端口转发了。我使用的是内网穿透工具frp,配置和使用都很简单。
架在宿主机上,我们可以通过校园网在校园内访问容器;架在公网服务器上,我们就可以在家访问容器。
使用方式
在 frp版本发布页面 下载linux的文件,如frp_0.21.0_linux_amd64.tar.gz
。解压后文件如下:
- frps:服务端执行文件
- frps_full.ini:服务端参数参考
- frps.ini:服务端参数文件
- frpc:客户端执行文件
- frpc_full.ini:客户端参数参考
- frpc.ini:客户端参数文件
服务端配置
服务端文件放置在宿主机中,宿主机的frps.ini可供参考,更多参数请看官方文档。
1 | [common] |
宿主机执行./frps -c frps.ini
开启服务。
客户端配置
客户端文件放置在用户容器中,容器的frpc.ini可供参考,更多参数请看官方文档。
1 | [common] |
容器执行./frpc -c frpc.ini
连接服务。
在校园网内进行测试
如上步骤,在已知宿主机校园网IP和容器SSH的映射端口之后,就可以在校园网内访问容器了。
这一步就不多讲了。
第四步:给用户分配容器
创建了容器模板之后,就可以按需给用户分配容器了。
克隆容器
1 | 克隆容器 参数一为模板容器名称,参数二为目标容器名称 |
修改hostname
克隆的容器还保留着模板的hostname,看起来令人不悦。快速修改hostname的步骤如下:
1 | 进入新容器bash |
修改SSH秘钥文件
克隆的容器还保留着模板的SSH id_rsa
文件,要是大家都用一份id_rsa文件访问不同的容器,就太扯了。所以要生成新的id_rsa
文件。快速修改id_rsa文件步骤如下:
1 | 进入新容器bash |
修改frp映射端口
道理很简单,要能访问不同的容器,就要将不同容器的SSH 22端口映射到宿主机不同的端口上。
直接修改容器中的frpc.ini,将转发实例中的括号名和remote_port。
然后容器执行./frpc -c frpc.ini
连接服务即可。
交付容器
把容器的SSH秘钥文件、SSH访问IP和SSH访问端口交付给同学即可。
Tips 记得交付之前,调用LXD的快照(snapshot)进行初始版本的备份,免得后面弄砸了,又要重新配置。
执行sudo lxc snapshot <ContainerName>
进行快照。
第五步:拓展
LXDUI 可视化管理界面
LXDUI是一个LXD/LXC的Web UI工具,支持LXD/LXC的一些基本操作。
具体使用请参考:lxdui GitRepo
效果如下:
##资源限制问题
目前是公平的给大家所有的硬件访问权限,后面如果涉及到资源拥挤的话,不可避免需要对每个人的资源进行限制,资源限制请参考:LXD 2.0 系列(四):资源控制
图形界面
目前我还没有实现图形界面,比较担心的是大家都用图形界面的话,带宽会不会被占用太多。
NAS资源访问
NAS后期更新。
驱动的更新
宿主机的软件一般不用更新,毕竟能够维持容器运行即可,所有的操作反正都在容器中进行。
但偶尔难免会出现打开终端双手不受控制的输入update和upgrade的情况,一般情况都还行,但是万一更新显卡驱动,就有糟心事了。
但是别慌,如果由于宿主机更新显卡驱动,导致容器显卡没法用了,就按照之前的安装容器显卡驱动一样,下载和宿主机显卡驱动版本相同的驱动文件,拷到容器内,无内核安装即可。
2019.1.9 更新:关于镜像自动备份
使用固然方便,如果能替大家实现定时备份容器的镜像就更好了。可以弄崩溃了恢复原来的备份即可。
解决方案参考:
需要注意的地方就是,关注一下代码和定时设置:定时间隔?哪些要保存?哪些过期删除?千万不要误删了重要的备份节点。
参考链接
- 搭建多人共用的GPU服务器
- 为实验室建立公用GPU服务器
- LXD, ZFS and bridged networking on Ubuntu 16.04 LTS+
- ZFS 与 LXC 与 GPU Passthrough,以及贵校超算队集群管理
- LXD 2.0 系列
这次的安装记录整理的实在太累了。下次都上带个相机,直接录下来就好了。