实验室GPU服务器的共享

我们的需求

在购买了一台单4090顶配游戏机后,接下来的问题是如何将这一台电脑分配给多个学生使用。我的微型团队深度学习才刚刚入门,学生大多数时间都花在配环境调代码阶段。虽然如此,配环境调代码也是极其耗费时间的,不可能让学生一个一个轮流坐到电脑前操作。因此,需要给每个学分配独立的开发环境并且可以直接访问CPU资源。也就是说,每个学生的实际使用体验类似于网上租用GPU云主机。具体而言,我们的需求可以概括为以下5点:

  1. 每个用户分配单独的开发环境,互不影响
  2. 每个用户可以可直接调用GPU
  3. 用户对自己的环境拥有最高权限
  4. 用户的开发环境配置出了问题删掉不心疼,可以随时复制新环境
  5. 远程登录访问足够方便

方案选型

那么具体怎么做才能做到这样的分配呢?大致有三种方案:

  1. linux系统的原生多用户环境
  2. linux系统下vmware虚拟机
  3. linux系统下LXD虚拟机

其中,浙大时用的8卡3090服务器就是采用方案1进行管理的。具体的说,是先装一个linux server无桌面版,然后按照linux的一般方式设置各种用户和权限。用户本身的环境是互相独立的,但是有共享文件夹。服务器本身的显卡驱动是统一安装的,普通用户不能更新。使用SSH远程登录进行控制。这种方案的好处是配置比较简单;坏处一是anaconda版本有限制,cuda driver版本不能随便更新。二是每个普通用户权限比较低,不能运行apt, sudo之类的命令。当然这也是一种保护措施,但是遇到一些不太好配的环境,对于菜鸟而言就不好办了。总之对于我们的五点诉求,其不能完全满足。

1 每个用户分配单独的开发环境,互不影响
2 每个用户可以可直接调用GPU
3 用户对自己的环境拥有最高权限 X
4 用户的开发环境配置出了问题删掉不心疼,可以随时复制新环境 X
5 远程登录访问足够方便

第二个方案是使用经典的VMware虚拟机软件分配虚拟机,这是我读研究生博士的时候常用方法。好处是每个虚拟机的用户都有完整权限并且相互隔离,就算搞崩了也不影响别人。但是,消费级NVIDIA显卡并不能直接在vmware虚拟机中运行。虚拟机想用显卡有两种办法:一种是虚拟显卡,好配置但无法启用cuda,等于没用;另一种是直通型显卡,隐藏虚拟机属性然后让虚拟机使用显卡。但是这样操作宿主机必须安装vmware EXSI版本,普通版本的vmware workstation都不行,具体配置详见此文档。而且多个虚拟机之间还需要手动调换GPU使用权。总之,使用vmware虚拟机做GPU共享,我们尝试后发现限制特别多,只能放弃。

1 每个用户分配单独的开发环境,互不影响
2 每个用户可以可直接调用GPU 麻烦
3 用户对自己的环境拥有最高权限
4 用户的开发环境配置出了问题删掉不心疼,可以随时复制新环境
5 远程登录访问足够方便

第三个方案是使用LXD(Linux Container Daemon)。LXD是Linux操作系统容器的管理工具,是介于vmware虚拟机和docker容器之间的一种容器。从历史上看,LXD 的前身LXC也是流行的虚拟化技术Docker的基础。LXD和Docker的主要区别是Docker是应用程序容器,而LXD包括完整的操作系统。所以使用LXD可以像vmware虚拟机那样拥有完整权限地操作,同时就算环境配置失败也可以无压力地删除以后再装一个。最后LXD完全依赖于linux操作系统,对显卡的支持远比vmware来的好。因此最后我选择了这个方案。

1 每个用户分配单独的开发环境,互不影响
2 每个用户可以可直接调用GPU
3 用户对自己的环境拥有最高权限
4 用户的开发环境配置出了问题删掉不心疼,可以随时复制新环境
5 远程登录访问足够方便

LXD具体安装和使用

我们是参考以下文档安装部署:

https://www.shenxiaohai.me/gpu-server-lab/

https://xungejiang.com/2022/07/14/lxd-new/

我们的具体安装部署流程:

我们选取的方案:采用所有硬盘作为宿主机硬盘

我们需要安装 LXD 实现虚拟容器,ZFS 作为 LXD 的存储管理工具,bridge-utils 用于搭建网桥。由于 apt 安装的 LXD 不是最新版本,这里使用 snap 安装工具安装 LXD。

sudo snap install lxd
sudo apt install zfsutils-linux bridge-utils

如果要删除LXD:
sudo snap remove --purge lxd
sudo rm -rf /var/lib/lxd

安装时有一些选项要配置:
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]: lxd_pool
Name of the storage backend to use (ceph, dir, lvm, zfs, btrfs) [default=zfs]:
Create a new ZFS pool? (yes/no) [default=yes]:
Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]:
Size in GiB of the new loop device (1GiB minimum) [default=30GiB]: 600
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
Would you like the LXD server to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]:
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
具体修改点有以下三处
Create a new ZFS pool? (yes/no) [default=yes]: yes
Would you like to use an existing block device? no
Would you like to create a new local network bridge? (yes/no) [default=yes]: yes

我们选取的方案:采用所有硬盘作为宿主机硬盘

创建容器模板(Ubuntu22.04)

包括配置:网络、GPU 驱动、共享目录、SSH 登录。