实验室GPU服务器共享方案 LXD

南楼画角 提交于 2019-12-07 16:45:36

LXD安装

需求

实验室有两台配置不高,显卡还算可以的服务器,用来作为深度学习的实践和学习。但是实验室人多,隔离环境必不可少,但是服务器cpu和内存并不高,跑虚拟机太重太浪费,跑docker又不合适。于是有了LXD的方案。

需求列表

  • 不同用户之间不能相互影响
  • 用户要能方便地访问自己的“虚拟机”
  • 用户要有足够大的权限,能自由地安装程序,能自由地访问网络
  • 用户不被允许直接操作宿主机
  • 用户要能够使用 GPU
  • 为满足这些需求,额外的开销应该小得可以忽略
  • 管理员应该能轻松地添加新的用户

方案发现

前面说了虚拟机太重,在机器本身配置不高的情况下负担太重,而且显卡是1080&1080ti(两台机器分别为1080*2, 1080ti*2),并不支持显卡虚拟化,也就是说一张卡只能在在同一时间供给一个虚拟机,这显然太浪费了。
考虑过docker,但是docker毕竟是应用级的容器,单进程,文件系统冗余太多,操作久了整个docker文件非常庞大,并不适合将它当虚拟机用。
我们需要的是开销小的虚拟机或者说环境隔离,安全性并不重要,在搜索中发现了docker的前身LXC(Linux Container),一个系统级的容器,非常适合我们的需求,可以当作一个低开销的虚拟机。
至于LXC和Docker的区别,这里就不进行细表了,毕竟我也了解的不多,只能说LXC更符合我的需求。
互联网是强大的,需求明确的话大概率能够找到比较匹配的解决方案,找到一篇博客为实验室建立公用GPU服务器,可以说是和我的需求基本一样,完美符合我的要求,正准备着手开始干,又找到一篇LXD容器的博客可爱的 LXD 系统容器,发现LXD似乎对于新手更加友好,操作封装的更好,而且更新。意外之喜是LXD能够支持前两篇博客并没有提到的 nvidia.runtime,能够和nvidia docker一样很好的支持nvidia显卡,这样就规避了宿主机和容器的nvidia driver和cuda的版本必须一致的大坑(毕竟容器不是自己在用,环境并不可控)。
LXC & LXD 官网
闲话说完,下面开始环境搭建。

LXD环境安装

基础环境:

OS: Ubuntu 18.04 bionic
CPU: Intel Xeon E5-1620 v4 (可能是最垃圾的E5 v4,只有4个物理核心)
Mem: 16GB
GPU: 1080TI * 2
操作时间: 2018年10月31日

1. 换源 & 更新

装完系统后首先就是换源,基本是复制地址,然后粘贴到 /etc/apt/sources.list 覆盖原文件,具体操作请参考相应源网站,比较理想的源有:

中科大源
清华源

学校的源有教育网出口,对于校园网用户是个最佳的选择

aliyun源

等等其他公司的镜像源

换源之后,更新一下,再安装必要的工具

sudo apt update
sudo apt upgrade
sudo apt install vim openssh-server
sudo apt install git gcc g++ make cmake build-essential curl

2. 安装驱动、CUDA和LXD等工具

18.04的apt源里集成了很多16.04里并没有的东西,nvidia驱动和cuda都可以通过apt安装,避开很多坑且操作更加简单,但是这里我们apt安装的驱动最高为390,cuda为9.1,比较尴尬,我们需要cuda9.2。这里,网上很多教程都是单独安装驱动再安装cuda,说是cuda带的驱动有问题,经测试,直接在官网下的cuda安装包直接安装配套的cuda和驱动在我的机器上是没有问题的,所以直接下载安装包安装,安装后重启。

# 卸载可能存在的nvidia驱动
sudo apt-get remove --purge nvidia*
​
#把 nouveau 驱动加入黑名单并禁用用 nouveau 内核模块
sudo vim /etc/modprobe.d/blacklist-nouveau.conf
​
# 在文件 blacklist-nouveau.conf 中加入如下内容:
blacklist nouveau
options nouveau modeset=0
​
# 保存退出,执行
sudo update-initramfs -u

# 安装驱动,地址是官网给的cuda下载地址
wget https://developer.nvidia.com/compute/cuda/9.2/Prod2/local_installers/cuda_9.2.148_396.37_linux https://developer.nvidia.com/compute/cuda/9.2/Prod2/patches/1/cuda_9.2.148.1_linux

# 下载cuda9.2的base包和patch包后,需要改名(文件不带后缀),并给执行权限
mv cuda_9.2.148.1_linux cuda_9.2.148.1_linux.run
mv cuda_9.2.148_396.37_linux cuda_9.2.148_396.37_linux.run
sudo chmod +x cuda_9.2.148_396.37_linux.run cuda_9.2.148.1_linux.run

# 安装cuda和打patch,一路默认选项,可以忽略提示
sudo ./cuda_9.2.148_396.37_linux.run
sudo ./cuda_9.2.148.1_linux.run

# 安装lxd
sudo apt install lxd lxd-client lxd-tools

# 安装nvidia-runtime-tools
# 添加源
curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \ 
sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list
# 安装
sudo apt install libnvidia-container-dev libnvidia-container-tools nvidia-container-runtime

正常安装好后:

# nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 396.37                 Driver Version: 396.37                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 108...  Off  | 00000000:02:00.0  On |                  N/A |
| 29%   38C    P8    11W / 250W |    221MiB / 11176MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GTX 108...  Off  | 00000000:03:00.0 Off |                  N/A |
| 29%   36C    P8    16W / 250W |      2MiB / 11178MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0       985      G   /usr/lib/xorg/Xorg                            14MiB |
|    0      1052      G   /usr/bin/gnome-shell                          55MiB |
|    0      1249      G   /usr/lib/xorg/Xorg                            74MiB |
|    0      1444      G   /usr/bin/gnome-shell                          74MiB |
+-----------------------------------------------------------------------------+

# nvidia-container-cli info
NVRM version:   396.37
CUDA version:   9.2

Device Index:   0
Device Minor:   0
Model:          GeForce GTX 1080 Ti
Brand:          GeForce
GPU UUID:       GPU-f659c541-0d5c-239a-dd8f-32367df58edf
Bus Location:   00000000:02:00.0
Architecture:   6.1

Device Index:   1
Device Minor:   1
Model:          GeForce GTX 1080 Ti
Brand:          GeForce
GPU UUID:       GPU-a58db27f-98d8-636e-1668-cfa34a2649fe
Bus Location:   00000000:03:00.0
Architecture:   6.1

3. 创建LXD模板镜像

准备工作与基础环境已经搞定,现在需要配置LXD容器的默认配置项,在创建容器时直接根据该配置生成。

# 配置添加镜像源 & 手动下辖镜像到本地
sudo lxc remote add tuna-images https://mirrors.tuna.tsinghua.edu.cn/lxc-images/ --protocol=simplestreams --public
sudo lxc image copy tuna-images:ubuntu/16.04 local: --alias ubuntu/16.04 --copy-aliases --public

# 配置默认参数:网络、存储池、开启nvidia.runtime、传入gpu
sudo lxd init --auto --network-address=0.0.0.0
sudo lxd init --auto --storage-backend=dir
sudo lxc profile set default nvidia.runtime true
# gpu这里,不能使用特权模式,会报错,具体为啥不清楚,但是直接传gpu是可以的
sudo lxc profile device add default gpu gpu id=0 #id看情况,多个gpu就多add几次
# 看看默认配置项
# sudo lxc profile show default
config:
  nvidia.runtime: "true"
description: Default LXD profile
devices:
  eth0:
    name: eth0
    nictype: bridged
    parent: lxdbr0
    type: nic
  gpu:
    id: "0"
    type: gpu
  root:
    path: /
    pool: default
    type: disk
name: gpu0
used_by: []

剩下的就是创建一个基础的镜像模板,这样可以方便新开容器,使得容器一创建不需额外操作就可以使用。本次主要实例是基于ubuntu16.04的基础镜像。

# 创建虚拟机,并进入
sudo lxc init ubuntu/16.04 template -p default
sudo lxc start template
sudo lxc exec template bash

# 下面所有的命令都是在容器里的,需要注意

# 换源 & 更新
vim /etc/apt/sources.list
# 拷贝下面的内容代原文件,清华tuna源,也可以选其他的
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security main restricted universe multiverse

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

# ----------分割线-------------
# 安装必要工具
apt install make cmake openssh-server gcc g++ build-essential

# 其他工具让用户进行把,模板到此为止,我们看看gpu是否正常
# nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 396.37                 Driver Version: 396.37                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 108...  Off  | 00000000:02:00.0  On |                  N/A |
| 29%   38C    P8    10W / 250W |    220MiB / 11176MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+

# 退出容器
exit

打包模板镜像供以后使用

sudo lxc stop template
sudo lxc publish template --alias template --public
sudo lxc rm template

# 查看镜像列表
# sudo lxc image list
+-----------------------+--------------+--------+--------------------------------------+--------+----------+------------------------------+
|         ALIAS         | FINGERPRINT  | PUBLIC |             DESCRIPTION              |  ARCH  |   SIZE   |         UPLOAD DATE          |
+-----------------------+--------------+--------+--------------------------------------+--------+----------+------------------------------+
| template              | 960ce038b955 | yes    |                                      | x86_64 | 214.88MB | Nov 4, 2018 at 10:27am (UTC) |
+-----------------------+--------------+--------+--------------------------------------+--------+----------+------------------------------+
| ubuntu/16.04 (7 more) | 09b9af2a67e7 | yes    | Ubuntu xenial amd64 (20181101_07:42) | x86_64 | 105.50MB | Nov 4, 2018 at 8:13am (UTC)  |
+-----------------------+--------------+--------+--------------------------------------+--------+----------+------------------------------+
| ubuntu/18.04          | 72f74ccbb968 | yes    | Ubuntu bionic amd64 (20181101_07:42) | x86_64 | 120.59MB | Nov 4, 2018 at 7:50am (UTC)  |
+-----------------------+--------------+--------+--------------------------------------+--------+----------+------------------------------+

# 以后使用默认配置和模板生成新容器
sudo lxc init template ${name} -p default

结束语

其实可以通过脚本来做更多的工作,比如在用户(非sudo用户)ssh到host之后,自动用用户名创建默认模板的容器并启动,等等。在这里就没有做相应的工作了,我采取的办法是将用户加入lxd用户组,这样启动容器不需要sudo权限,相对来说自由度更大,用户也更加方便。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!