1 搭建需求
工作室新进一台高配电脑,配置了双系统Windows+Ubuntu22.04,公用的电脑总不能让同学一个一个轮流坐到电脑前操作,所以就有了多人同时使用的需求。
虽说 Linux 可以设置各种用户和权限、Anaconda 可以建立各个虚拟环境,但难免遇到软件版本需求不同相互冲突、新手乱删文件等情况,最好还是给每个同学建立相互隔离的环境最舒服了,随便怎么折腾也不会干扰其他人。
大致讲一下整个方案的流程:
宿主机安装 Ubuntu22.04 系统,安装 GPU 驱动。
安装 LXD/ZFS 软件并进行配置。
创建容器模板(Ubuntu22.04),包括:GPU 驱动、共享目录、SSH 登录。
按需分配,克隆容器模板。
使用 lxdui 进行可视化容器管理。
2 宿主机GPU 驱动安装
往常 Linux 下的 GPU 驱动安装是很复杂的,网上 NVIDIA Driver 教程百花绽放。经过实践发现,装完系统后,使用系统软件和更新中提供的 NVIDIA 驱动是可行的,非常方便。
安装完成后,重启,输入 nvidia-smi 进行确认,注意显卡驱动版本:
3 安装LXD
我们需要安装 LXD 实现虚拟容器,ZFS 作为 LXD 的存储管理工具,bridge-utils 用于搭建网桥。由于 apt 安装的 LXD 不是最新版本,这里使用 snap 安装工具安装 LXD。
1 | # 安装 lxd、zfs 及 bridge-utils |
如果要删除LXD
1 | sudo snap remove --purge lxd |
初始化Lxd,具体修改点有以下三处
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
1 | Would you like to use LXD clustering? (yes/no) [default=no]: |
4 创建容器
创建的容器建议和宿主机系统相同。我这里宿主机使用的是ubuntu22.04,当然也可根据自己的需求创建其他ubuntu版本的容器。
1 | sudo lxc launch ubuntu:22.04 |
查看容器列表:
1 | lxc list |
5 更改容器名
为了后续方便辨识,我们将容器名进行修改:
1 | sudo lxc stop intense-raptor |
6 为容器添加设备和权限
1 | sudo lxc config device add ubuntu22-tmp gpu gpu |
注意,如果服务器或者电脑有多张显卡,这里一定要指定GPU的索引号id=xxx,不然后续运行项目会报如下图所示的错误
1 | /root/anaconda3/lib/python3.11/site-packages/torch/cuda/__init__.py:107: UserWarning: CUDA initialization: |
例如,指定索引号为0,可使用如下命令
1 | sudo lxc config device add ubuntu22-tmp gpu-tmp gpu id=0 |
7 更改容器用户名和密码
进入容器ubuntu22-tmp
1 | sudo lxc exec ubuntu22-tmp bash |
容器默认用户名为 ubuntu,这里想把他改成 ubuntu22-tmp,命令如下:
1 | usermod -l ubuntu22-tmp -d /home/ubuntu22-tmp -m ubuntu |
此时 /home 文件夹下只剩下 ubuntu22-tmp目录。
更改ubuntu22-tmp用户的密码
1 | passwd ubuntu22-tmp |
修改root用户密码
1 | passwd root |
8 配置容器 ssh 连接
1 | apt install openssh-server |
编辑 ssh 配置文件:
1 | vim /etc/ssh/sshd_config |
将 PasswordAuthentication 改为 yes,退出编辑后重启 ssh 服务:
1 | systemctl restart sshd |
此时可以用 exit 命令退出到宿主机中,用 ssh 命令远程连接容器:
1 | sudo ssh ubuntu-tmp@10.67.139.181 |
输入密码,能登录则没问题。
但是我们的需求不仅限于使用本电脑远程登录,每个容器都处于宿主机构建出来的小型局域网内,其他用户无法直接访问容器,我们的主要目的是让每一位同学都可以使用自己的电脑远程连接服务器。
有两种解决方案:端口转发,内网穿透
这里主要介绍端口转发方案,其中端口号可自行设置,我这里设置为6001
宿主机:wlo1:192.168.3.123,lxdbr1:10.13.153.1
容器ubuntu22-tmp:eth0:10.13.153.83
1 | lxc config device add ubuntu22-tmp proxy1 proxy listen=tcp:192.168.3.123:6001 connect=tcp:10.13.153.83:22 bind=host |
9 使用模板复制新容器
1 | # 克隆容器 参数一为模板容器名称,参数二为目标容器名称 |
重新配置端口号和容器ip地址,关闭容器后,再次启动容器
1 | lxc config edit test-lxd |
10 换apt源
备份sources.list文件
1 | sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak |
如下为哈工大源:
1 | # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 |
更新源:
1 | sudo apt update |
11 安装容器的显卡驱动
安装显卡这里提供两种方式:命令安装,脚本安装。
需要注意的是,容器和宿主机的显卡驱动必须保持一致
以此型号驱动为例,驱动型号为Driver Version: 535.104.05 CUDA Version: 12.2
11.1 命令直接安装
在容器内输入nvidia-smi查看可下载的显卡驱动,如果有版本相同的显卡驱动
apt install nvidia-utils-535 # version 535.104.05-0ubuntu0.22.04.1
1 | root@trusty-crappie:~/sharefile# nvidia-smi |
直接下载即可。如果没有请使用第二种方法脚本安装
1 | apt install nvidia-utils-535 |
11.2 官网脚本安装
首先在官网下载所需的linux显卡驱动 NVIDIA-Linux-x86_64-535.104.05.run
https://www.nvidia.com/download/index.aspx
由于容器和宿主机共享内核,所以在安装容器的显卡驱动时需要添加 –no-kernel-module 参数。
1 | bash ./NVIDIA-Linux-x86_64-535.104.05.run --no-kernel-module |
安装选项都选择no即可,安装好显卡驱动后用 nvidia-smi 命令查看显卡驱动是否合适
接下来可以安装anaconda和pytorch,测试是否可以调用显卡,显示true则没问题
1 | (base) zd@zd-System-Product-Name:~/sharefile$ python |
12 配置共享文件夹
为方便文件的传输与节约内存,我们需要设置共享文件夹来实现宿主机与容器之间的文件传输。
#新建共享文件夹
1 | mkdir sharefile |
在宿主机创建共享区域share-host
1 | sudo lxc profile create share-host |
检查是否创建成功
1 | sudo lxc profile show share-host |
将文件夹添加到制定LXD容器ubuntu22-tmp
1 | lxc config device add ubuntu22-tmp share-host disk source=/home/zd/sharefile path=/root/sharefile |
13 LXDUI 可视化管理界面
LXDUI 是一个 LXD/LXC 的 Web UI 工具,支持 LXD/LXC 的一些基本操作。
具体使用请参考:lxdui GitRepo
效果如下: