1. 程式人生 > >搭建多人共用的GPU伺服器

搭建多人共用的GPU伺服器

背景

目前實驗室GPU使用情況是:大部分同學的配有單臺1080/TITAN Xp。後來購入了兩臺4卡的機器,老師的意思是希望可以作為伺服器使用,能夠多人同時使用,互不影響。於是便開始了本次折騰,記錄採坑經歷。

通過本文,多卡讀者可以實現分配每塊GPU給特定同學使用,也可以多人共用多塊GPU。單卡讀者可以實現多人共用一塊GPU。

需求

說需求之前先來列一下機器配置:

CPU: i7-6850K CPU
記憶體:DDR4 2400Hz 32G *4
儲存:512G SSD *1 + 4TB 機械 *3
顯示卡:TITAN Xp *4

需求很明顯:像使用一臺帶有GPU的自己的機器一樣使用伺服器

具體來說要滿足:

  • 不同使用者之間不能相互影響且可以同時使用
  • 使用者要能方便地訪問自己的“機器”
  • 使用者有所有許可權
  • 使用者不被允許直接操作宿主機
  • 靈活配置GPU,可以每一分一塊GPU,只有一個人用的時候可以用四塊。
  • 上網方便,使用自己的校園網帳號上網,可以使用IPV6

調研

首先可以肯定,Ubuntu多使用者下可能存在誤刪其他同學檔案,所需軟體版本不相容,GPU使用需要程式碼中指定等問題。

經過多方調研對比,在此省略xx字,最終選擇使用LXD來搭建容器,實現上述需求。

我主要看好LXD:

  • 相比LXC更簡單,功能更強大
  • 相比部署應用用的Docker更時候做操作使用的容器
  • 相比KVM更輕便
  • 支援GPU等裝置Passthrough
  • 調研過程中看到的資料足夠滿足我實現上述需求
  • 支援RESTful API

所以整體思路是通過LXD容器實現多使用者共用GPU伺服器。

主要參考文獻見文章最後一章節。

安裝

安裝過程主要安裝了
- ZFS 用於管理物理磁碟,支援LXD高階功能
- LXD 實現虛擬容器
- bridge-utils 用於搭建網橋

sudo apt install zfs
sudo apt -t xenial-backports install lxd
sudo apt install bridge-utils

配置

配置LXD

sudo lxd init,按照提示,這裡我選擇將第一塊1TB的機械硬碟通過ZFS作為容器的儲存後端。當提示是否建立bridge時,選擇否。lxd init建立的bridge每個容器通過宿主機用NAT上網,我更希望每個人分配一個IP,通過自己的校園網上網。如果不需要,請選擇是並忽略下一個章節。

配置網橋

修改/etc/network/interfaces,內容如下:

auto lo
iface lo inet loopback

auto br0
iface br0 inet dhcp
   bridge_ports enp14s0

iface enp14s0 inet manual

其中enp14s0可通過ifconfig檢視網絡卡資訊得到。

配置LXDlxc network attach-profile br0 default eth0。配置完成後需要重啟下機器。

新建容器

如果你網速可以:lxc launch ubuntu:xenial yourContainerName可以試試直接下載,100M多點。

如果有網速不行建議新增清華大學的映象,並且IPV6正好免校園網流量:

lxc remote add tuna-images https://mirrors.tuna.tsinghua.edu.cn/lxc-images/ --protocol=simplestreams --public
lxc image list tuna-images:

之後使用lxc launch tuna-images:biasOrfootprint yourContainerName新建容器。

安裝驅動

lxc exec yourContainerName bash可進入容器bash,在容器中顯示卡驅動不需要安裝核心檔案,只需要sudo sh /NVIDIA-Linux-x86_64-xxx.xx.run --no-kernel-module進行安裝。

配置顯示卡

為容器新增所有GPU: lxc config device add yourContainerName gpu gpu

新增指定GPU: lxc config device add yourContainerName gpu0 gpu id=0

共享目錄
lxc config set yourContainerName security.privileged true
lxc config device add privilegedContainerName shareName disk source=path1 path=path2

path1為宿主機路徑,path2為容器內路徑。

nvidia-uvm

興沖沖的裝好環境,發現TensorFlow無法使用顯示卡,原因是宿主機沒有/dev/nvidia-uvm裝置,需要通過以下命令掛載裝置:

/sbin/modprobe nvidia-uvm
D=`grep nvidia-uvm /proc/devices | awk '{print $1}'`
mknod -m 666 /dev/nvidia-uvm c $D 0

掛載裝置到容器:

lxc config device add yourContainerName nvidia-uvm unix-char path=/dev/nvidia-uvm
桌面環境

考慮到需要桌面環境的同學,我們通過VNC訪問桌面環境。首先嚐試的配置Ubuntu自帶桌面,多次嘗試失敗,後來選擇使用gnome桌面。

# 可選 --no-install-recommends 安裝不必要組建
apt install ubuntu-desktop gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal vnc4server -y

~/.vnc/xstartup檔案中加入:

gnome-panel &
gnome-settings-daemon &
metacity &
nautilus &

然後即可使用vnc4server,VNC具體使用不再贅述。

CUDA與cuDNN

CUDA與cuDNN安裝本質上來講只是解壓檔案(標頭檔案,動態庫等),所以我把不同版本的CUDA與cuDNN安裝到了公共磁碟上,這個公共磁碟通過配置檔案預設掛載到所有容器,其他同學在使用時按需新增環境變數和動態庫路徑即可。

其他

我整體的解決方案是把配置好的容器做成映象,後續建立從這個映象建立。這個映象配置了SSH,VNC,普通使用者等。

第二塊硬碟通過ZFS管理zpool create A-pool /dev/sdb。通過配置檔案掛載到容器。CUDA和cuDNN安裝在這裡。後續拷貝大型資料集也可以直接通過物理機拷貝。

上網處理可以通過VNC開啟瀏覽器上網外,用上了之前寫的一個Python登入校園網的庫,可以通過指令碼登入網路。

GPU預設通過配置檔案掛載到容器。LXD相關操作見參考中的[3],用到了編輯配置檔案,快照,映象等相關操作,本文沒有細說。

寫份使用說明,並告知使用者一定要修改預設SSH和VNC密碼。

因為有RESTful API,所以可以做個WEB管理系統,後來發現了lxdui還挺好用:

由於載入映象拖慢速度,對程式碼簡單進行了修改備用。後續準備基於lxdui增加許可權控制等功能,每個使用者可以方便的對自己的容器進行控制,快照等。

總結

本次折騰完美解決了需求,每個人通過SSH + VNC使用完全屬於自己的機器,作為宿主機的管理員,我深知責任重大,更應該嚴守宿主機密碼,常常以刪除容器來威脅舍友,耐心幫助同學。

此外,有RESTful API還能做很多好玩的事情。

參考