搭建多人共用的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還能做很多好玩的事情。