问题:网络不通:压后处理
另外nvidia-smi出现版本问题
【背景】
多人共用一台GPU服务器的情况,但是每个人的使用方式和操作习惯都不一样,对于系统的软件、环境、文件、配置等要求也各不相同,甚至还有小白运行损害系统的命令。
那么如何让多人井井有条的共用服务器,还不影响服务器性能呢?那就是通过虚拟化容器技术来隔离每个人的操作系统,并通过共享文件夹的形式达到多人共用的数据资源。
【方案对比】
二、方案对比
通常会做出的方案如下:
2.1 单用户
即大家都使用同一个用户来使用服务器,这样会导致每个用户文件都存放在一起,太乱且容易误删;一个用户更改系统环境后会影响到其他用户使用,比如CUDA版本等;多个用户之间不能方便的协调管理等。
2.2 多用户
多用户管理虽然可以解决每个人的文件存储管理问题,但仍然会导致每个人都有可能修改系统环境和配置影响其他用户使用。并且如果某人将系统损坏所有人都将受到影响。
2.3 KVM虚拟机
虚拟机可以通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。可以达到我们想要的系统隔离效果, 但使用虚拟机会浪费一定资源用于硬件虚拟化,且硬件只能独占,不能共享,资源利用率低。
2.4 Docker
虽然是容器化的环境,但Docker是应用级容器,他更偏向于PaaS平台,还是没办法做到让每个用户拥有一个独立的操作系统。
2.5 LXC
系统级虚拟化方案,用在单个主机上运行多个隔离的Linux系统容器。但LXC也有缺点:如无法有效支持跨主机之间的容器迁移、管理复杂等。而LXD很好地解决了这些问题。Docker是应用级,LXC是系统级。
2.6 LXD
LXD底层也是使用LXC技术,并可以提供更多灵活性和功能。因此LXD可以视作LXC的升级版。LXD的管理命令和LXC的管理命令大多相同。
2.7 OpenPAI
微软先进的任务隔离方法,主要适用于任务型隔离,比较适合集群化部署,人数较多的使用场景。
基于上面常见的七种方法,能拥有系统级隔离、容器化成本最低、操作方便简单的方案就是使用:LXD了。
2.8 LXD最终能实现什么
每个用户都有用了独立的系统以及所有权限,但不被允许之间操作宿主机;
每个容器拥有可以在局域网内访问的独立IP地址,用户可以使用SSH方便地访问自己的“机器”;
所有用户都可以使用所有的资源,包括CPU、GPU、硬盘、内存等;
可以创建共享文件夹,将共用数据集、模型、安装文件等进行共享,减少硬盘浪费;
可以安装图形化桌面进行远程操作;
容器与宿主机使用同一个内核,性能损失小;
轻量级隔离,每个容器拥有自己的系统互不影响;
容器可以共享地使用宿主机的所有计算资源。
LXD也有缺点:显卡驱动不方便更新;
容器与宿主机共同内核,一个容器内核出错,全体爆炸。
上段截取自:http://t.csdnimg.cn/OyjDa
【安装与配置】
安装ubuntu,安装显卡驱动:详见我以往教程:
ubuntu18.4(后改为20.4)部署chatglm2并进行基于 P-Tuning v2 的微调_chatglm2环境配置ubuntu-CSDN博客
检查是否安装成功
输入:nvidia-smi
命令:
安装nvidia-container-runtime
Nvidia官方出的容器运行GPU组件,安装后在容器中就可以直接调用宿主机的显卡驱动。
# Add the package repositories
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | tee /etc/apt/sources.list.d/nvidia-docker.list
apt-get update
apt install libnvidia-container-dev libnvidia-container-tools nvidia-container-runtime -y
安装LXD、ZFS和Bridge-utils:
sudo apt-get install zfsutils-linux bridge-utils
snap install lxd
LXD 实现虚拟化容器;ZFS 用于管理物理磁盘,支持LXD高级功能;Bridge-utils 用于搭建网桥
配置存储池
安装完软件后,我们要选一块区域来存储LXD所使用的空间。我们可以在一个磁盘上分出一块分区,也可以把整个磁盘作为存储池。我们先看一下磁盘情况:sudo fdisk -l
:
找到你想操作的磁盘,如这里的/dev/sdb,可以直接sudo fdisk /dev/sdb
来对磁盘进行分区,fdisk命令如果不记得可以输入m
查看帮助说明。
如果已经有分区了,可以输入d
删除分区,然后输入n
创建分区,最后w
保存分区就可以了,我这里选择/dev/sdb作为我的zfs存储池。
初始化LXD
执行:sudo lxd init
LXD初始化脚本将询问你存储、网络、容器各种配置项的默认值:
注意an exsiting empty block device写yes,写/dev/sdb1
网络配置那里有两种方式,一种是全部走一个公网,容器都是局域网ip,访问每个容器都需要通过唯一的公网IP+端口号的形式,也就是我上面采用的方式。还有一种形式是不创建桥接网络,直接让所有容器都获取上游独立ip,相当于每个容器都能够获取独立ip。我这边是只有一个公网,所以采用了这种方式,你可以根据自己需求修改这里的网络配置。
相关配置输入错了也没关系,可以通过sudo lxc profile edit default或者再运行一遍sudo lxd init来再次修改配置。
然后是: 创建容器
所有准备工作准备齐全后就可以来创建容器了,和Docker的使用方式很类似,我们先选个镜像,我这里选择Ubuntu 20.04,然后直接通过launch命令启动容器(如果本机镜像找不到则会去网上自动下载并使用):
lxc launch ubuntu:20.04 tf
tf是容器的名字,启动成功后,我们可以通过lxc list
命令查看现在运行的容器:
通过lxc image ls
查看本机已有的镜像。
通过lxc exec tf bash
可以进入容器内进行操作:
exit
:退出容器lxc stop tf
:停止容器lxc delete tf
:删除容器lxc restart tf
:重启容器
配置容器
现在容器已经创建好了,可以进容器,现在还需要做三件事才可以让其他伙伴使用:
1 共享文件夹
【在宿主机创建个共享文件夹,然后共享给每个容器。这样容器之间就可以相互存取文件,比较适合放一些共用的软件包和数据集:
sudo lxc config set <container> security.privileged true
sudo lxc config device add <container> <device-name> disk source=/home/xxx/share path=/home/xxx/share
其中 path 为容器路径,source 为宿主机路径。device-name 随意取名字即可。
sudo lxc config set tf security.privileged true
sudo lxc config device add tf datacys disk source=/root/data path=/root/data
移除共享文件夹:
sudo lxc config device remove <container> <device-name>】
直接可以在/root/snap/lxd共享文件夹下看到文件,
2.安装显卡驱动
1.添加GPU硬件
添加GPU硬件
在宿主机中执行以下命令
lxc config device add tf gpu gpu
然后进入容器,安装显卡驱动。驱动程序可以放到宿主机的共享文件里,这样进入容器就可以直接使用了。
安装驱动
因为LXD是复用了Linux内核,所以在容器内安装显卡驱动就不用安装内核了:
sudo sh ./NVIDIA-Linux-x86_64-***.run --no-kernel-module
这配置好繁琐,这么多命令参数,有没有现成的GUI工具可以鼠标点点就可以操作呢?当然是有,要不然就不会有这段话,因为LXD 在 LXC 基础上增加了 RESTful API,所以是有基于这个API操作的可视化界面:lxdui。
照着Github仓库说明安装就可以了,我这里贴一下我的操作:
检查Python3和pip是否安装成功,必须。
Clone仓库,并进入目录:
git clone https://github.com/AdaptiveScale/lxdui.git
cd lxdui
python3 -m venv mytestenv,创建虚拟环境,可选。
# 激活虚拟环境
source mytestenv/bin/activate
安装依赖包
python3 setup.py install
运行程序
# 启动:
python3 run.py start
# 或者使用CLI启动:
lxdui start
# 后台运行
nohup python3 run.py start > python.log3 2>&1 &
管理界面
启动成功后,可以浏览器访问宿主机ip:15151
----------------------------------------------------------
换个时间,打开,
1.运行lxc exec tf bash
2.ping 不通
lxc list tf # 查看容器列表和状态
lxc exec tf -- ip addr add 10.138.9.100 dev eth0
有两种解决方案:端口转发,内网穿透
这里主要介绍端口转发方案,其中端口号可自行设置,我这里设置为6001
宿主机:wlo1:192.168.0.107,lxdbr0:10.138.9.1
容器tf:eth0:10.138.9.100
lxc config device add tf proxy1 proxy listen=tcp:192.168.0.107:6001 connect=tcp:10.138.9.10:22 bind=host
参考https://zhuanlan.zhihu.com/p/661754584
还是没连上网,有点麻烦!
systemctl start systemd-networkd
nano /etc/netplan/01-network-manager-all.yaml
#Let NetworkManager manage all devices on this system
network:
version: 2
# renderer: NetworkManager
ethernets:
eth0:
addresses: [168.168.100.111/16]
gateway4: 168.168.0.1
dhcp4: no
dhcp6: no
容器参数
通过lxc config edit tf
配置容器的参数:
在宿主机执行:
-
分配 IP 地址: 首先,使用
lxc exec
命令在容器tf
中分配 IP 地址10.138.9.100
到eth0
接口:lxc exec tf -- ip addr add 10.138.9.100/24 dev eth0
-
设置默认网关: 接下来,您需要设置默认网关。通常,默认网关是连接到同一子网的路由器的 IP 地址。例如,如果您的 LXD 网桥
lxdbr0
的 IP 地址是10.138.9.1
,那么您可以将其设置为默认网关:lxc exec tf -- ip route add default via 10.138.9.1
这条命令会将所有非本地网络的数据包发送到
10.138.9.1
,这是您的 LXD 网桥的 IP 地址。 - 容器可访问网络,但是不能解析域名,在/etc/resolv.conf文件里添加nameserver 8.8.8.8,没用,好像这里不是这个问题!!
搞了一整天一整晚,先这样吧,费时有点多