从零到一:基于LXC搭建专业级GPU共享服务器的终极指南 ...

张裕  金牌会员 | 2024-10-27 21:49:31 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 562|帖子 562|积分 1686

写在前面

本文创作历时7个月,之前只在个人blog上公开,一直处于美满过程。目前该项目已经进入稳定阶段,因此打算向更多读者公开,建议先点赞收藏后食用


  
一、媒介

对于团队开发而言,资源共享是是提高生产服从的有效手段之一,尤其是在当今国际贸易制裁下,高端服务器资源公用将会成为常态。如何合理、高效地使用服务器资源,是本项目要办理的问题。
在多人共用一台GPU服务器的情况下,为了满足不同用户的使用方式和使用风俗特点,同时制止某些用户运行损害体系的命令导致整个服务器宕机,搭建一个支持多人同时在线、资源良好隔离且自愈性强的服务器平台成为了一个紧张需求。
多人在线服务器有多种方案,此中一个较为推荐的办理方案是通过假造化容器技术来隔离每个人的使用体系,并通过共享文件夹的形式达到多人共用的数据资源。
该堆栈包罗了关于super-server-platform的搭建、升级记录和使用建议,服务器搭建和升级过程中涉及到的质料将会被包罗到这个堆栈中,方便回溯和更新。
二、多人在线服务器架构方案

针对多人服务器平台通常有以下几种方案:
2.1 原生体系上直接创建多用户

这种方案简朴,只需要开放对应端口即可通过ssh和vnc实现远程操控。然而无法实现资源的隔离,比方无法按需分配GPU资源,无法个性化每个用户的开发情况,另外,某个用户运行损害体系的命令可能会导致整个体系宕机,影响其它用户使用。
2.2 原生体系上搭建假造机

该方案可以实现各个用户的开发情况隔离,同时各个用户的体系之间不会相互影响。 假造机包罗完整的使用体系和应用步伐,因此通常需要更多的内存和存储资源。假造机的引入会带来性能损耗,且硬件只能独占,不能共享,资源使用率低。
2.3 接纳Docker容器

Docker容器提供了一个隔离的开发情况,在不同容器中的用户资源不会受到影响,同时由于容器共享主机使用体系的内核,因此它们更轻量级且占用更少的资源,使用容器几乎不会带来性能损失。虽然是容器化的情况,但Docker是应用级容器,他更方向于PaaS平台,还是没办法做到让每个用户拥有一个独立的使用体系。
2.4 基于LXC (LinuX Container) 容器

LXC容器属于体系级假造化方案(LXD vs Docker),用在单个主机上运行多个隔离的Linux体系容器,比方同时运行Ubuntu和CentOS,各个体系公用一套Linux内核,并且具有完全独立的开发情况。LXC是基于Linux内核的容器技术,与Linux使用体系更加天然集成,提供更好的性能。但LXC也有缺点:如无法有效支持跨主机之间的容器迁徙、管理复杂等。而LXD很好地办理了这些问题。

2.5 基于LXD容器

LXD底层也是使用LXC技术,并可以提供更多机动性和功能。LXD支持Web图形用户界面,使得容器的管理变得更加直观和易用。因此LXD可以视作LXC的升级版。LXD的管理命令和LXC的管理命令大多雷同。
三、基于LXD容器的服务平台特性

基于LXD容器平台的核心是LXC,它允许建立多个体系级别的容器,每个容器即是一个完整的Linux使用体系。一个容器既可以支持多个用户共享,也可以一个用户独享。每个容器通过网络与共享文件夹的方式与宿主机举行通讯,每个容器可以独享一个IP地址。LXD支持Web图形用户界面,且兼容全部LXC的命令使用。通过设置LXC容器,可以实现对不同容器举行硬件资源(比方GPU)分配。宿主机体系和LXC容器体系共享一个Linux内核,雷同内核的不同Linux发行版本可以同时运行。

详细服务器设置细节参考文末链接,这里不再详细赘述,以下扼要介绍该平台使用方案。
3.1 设置方案

LXD支持多个用户,这里设置了Common-Server作为公共使用的容器平台,可以供全部用户临时使用。
对于需要长期使用的用户,建议创建独立的容器,并且根据自己需要设置个性化的开发情况,详细创建方法请参考。
这里接纳了独立IP设置,因此每个容器在局域网下都有具有独立的IP。
  1. (base) user@user-Super-Server:~$ sudo lxc list
  2. +---------------+---------+-----------------------+------+------------+-----------+
  3. |     NAME      |  STATE  |         IPV4          | IPV6 |    TYPE    | SNAPSHOTS |
  4. +---------------+---------+-----------------------+------+------------+-----------+
  5. | Common-Server | RUNNING | 192.168.31.90 (eth0)  |      | PERSISTENT | 0         |
  6. +---------------+---------+-----------------------+------+------------+-----------+
  7. | user1-server  | RUNNING | 192.168.31.xxx (eth0) |      | PERSISTENT | 1         |
  8. +---------------+---------+-----------------------+------+------------+-----------+
  9. | user2-server  | RUNNING | 192.168.31.xxx (eth0) |      | PERSISTENT | 1         |
  10. +---------------+---------+-----------------------+------+------------+-----------+
  11. | user3-server  | RUNNING | 192.168.31.xxx (eth0) |      | PERSISTENT | 0         |
  12. +---------------+---------+-----------------------+------+------------+-----------+
复制代码
3.2 资源隔离

如图,在宿主机上可存在4个4090GPU,通过对容器举行设置,可以指定宿主机上的GPU2和GPU3映射到容器体系的GPU0和GPU1上,并且其它的GPU资源对于容器是不可见的,因此可以实现良好的资源隔离。
  1. (base) user@user-Super-Server:~$ nvidia-smi
  2. Mon Jul  8 23:02:38 2024      
  3. +---------------------------------------------------------------------------------------+
  4. | NVIDIA-SMI 535.146.02             Driver Version: 535.146.02   CUDA Version: 12.2     |
  5. |-----------------------------------------+----------------------+----------------------+
  6. | GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
  7. | Fan  Temp   Perf          Pwr:Usage/Cap |         Memory-Usage | GPU-Util  Compute M. |
  8. |                                         |                      |               MIG M. |
  9. |=========================================+======================+======================|
  10. |   0  NVIDIA GeForce RTX 4090        Off | 00000000:31:00.0 Off |                  Off |
  11. | 69%   72C    P2             311W / 450W |  11140MiB / 24564MiB |     91%      Default |
  12. |                                         |                      |                  N/A |
  13. +-----------------------------------------+----------------------+----------------------+
  14. |   1  NVIDIA GeForce RTX 4090        Off | 00000000:4B:00.0 Off |                  Off |
  15. | 68%   72C    P2             307W / 450W |   7552MiB / 24564MiB |     95%      Default |
  16. |                                         |                      |                  N/A |
  17. +-----------------------------------------+----------------------+----------------------+
  18. |   2  NVIDIA GeForce RTX 4090        Off | 00000000:B1:00.0 Off |                  Off |
  19. | 60%   66C    P2             303W / 450W |   7552MiB / 24564MiB |     97%      Default |
  20. |                                         |                      |                  N/A |
  21. +-----------------------------------------+----------------------+----------------------+
  22. |   3  NVIDIA GeForce RTX 4090        Off | 00000000:CA:00.0 Off |                  Off |
  23. | 63%   67C    P2             301W / 450W |   7552MiB / 24564MiB |     92%      Default |
  24. |                                         |                      |                  N/A |
  25. +-----------------------------------------+----------------------+----------------------+
复制代码
  1. (base) user@user-Super-Server:~$ sudo lxc config edit Common-Server
  2. ### A sample configuration looks like:
  3. ### name: container1
  4. ### profiles:
  5. ### - default
  6. ### config:
  7. ###   volatile.eth0.hwaddr: 00:16:3e:e9:f8:7f
  8. ### devices:
  9. ###   homedir:
  10. ###     path: /extra
  11. ###     source: /home/user
  12. ###     type: disk
  13. ### ephemeral: false
  14. ###
  15. ### Note that the name is shown but cannot be changed
  16. architecture: x86_64
  17. config:
  18.   image.architecture: amd64
  19.   image.description: Ubuntu bionic amd64 (20240113_07:42)
  20.   image.os: Ubuntu
  21.   image.release: bionic
  22.   image.serial: "20240113_07:42"
  23.   security.privileged: "true"
  24.   volatile.base_image: 64509028accfe5a2727603687820708af03fa9a04f6821d40d1734a620cd587d
  25.   volatile.eth0.hwaddr: 00:16:3e:09:74:9f
  26.   volatile.idmap.base: "0"
  27.   volatile.idmap.next: '[]'
  28.   volatile.last_state.idmap: '[]'
  29.   volatile.last_state.power: RUNNING
  30. devices:
  31.   data:
  32.     path: /home/user/share
  33.     source: /home/user/share
  34.     type: disk
  35.   gpu0:
  36.     id: "2"
  37.     type: gpu
  38.   gpu1:
  39.     id: "3"
  40.     type: gpu
  41. ephemeral: false
  42. profiles:
  43. - default
  44. stateful: false
  45. description: ""
复制代码
  1. user@Common-Server:~$ nvidia-smi
  2. Mon Jul  8 15:06:34 2024      
  3. +---------------------------------------------------------------------------------------+
  4. | NVIDIA-SMI 535.146.02             Driver Version: 535.146.02   CUDA Version: 12.2     |
  5. |-----------------------------------------+----------------------+----------------------+
  6. | GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
  7. | Fan  Temp   Perf          Pwr:Usage/Cap |         Memory-Usage | GPU-Util  Compute M. |
  8. |                                         |                      |               MIG M. |
  9. |=========================================+======================+======================|
  10. |   0  NVIDIA GeForce RTX 4090        Off | 00000000:4B:00.0 Off |                  Off |
  11. | 68%   72C    P2             304W / 450W |   7552MiB / 24564MiB |     92%      Default |
  12. |                                         |                      |                  N/A |
  13. +-----------------------------------------+----------------------+----------------------+
  14. |   1  NVIDIA GeForce RTX 4090        Off | 00000000:B1:00.0 Off |                  Off |
  15. | 60%   66C    P2             292W / 450W |   7552MiB / 24564MiB |     92%      Default |
  16. |                                         |                      |                  N/A |
  17. +-----------------------------------------+----------------------+----------------------+
复制代码
3.3 文件共享

为了实现各个容器体系的文件共享,需要引入共享文件夹。如图,宿主机和Common-Server容器体系可以同时访问/home/user/share文件夹
  1. (base) user@user-Super-Server:~$ ls /home/user/share/
  2. bcompare-4.4.7.28397_amd64.deb  BSDS500  EnvConfig                frpnc                                   
  3. user@Common-Server:~$ ls /home/user/share/
  4. bcompare-4.4.7.28397_amd64.deb  BSDS500  EnvConfig                frpnc                                   
复制代码
四、基于LXD容器的服务平台使用方式及使用指南

4.1 连接方式

4.1.1 局域网下的SSH访问

比方要连接Common-Server,可在局域网下使用以下命令连接
  1. (base) user@user-Super-Server:~$ ssh user@192.168.31.90
  2. user@192.168.31.90's password:
  3. Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-150-generic x86_64)
复制代码
4.1.2 非局域网下的SSH访问

为了实现非局域网下访问,引入了内网穿透,这里将Common-Server映射到公网IP,可实现非局域网下访问。注意非局域网下仅有10M带宽,因此传输大文件建议使用局域网,大概接纳网盘传输。详细连接方式如图
  1. (base) user@user-Super-Server:~$ ssh -p 2222 user@xxx.domain
  2. user@xxx.domain's password:
  3. Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-150-generic x86_64)
复制代码
4.1.3 在PyCharm中使用SSH远程开发

使用该方案,可以办理服务器界面不友好的问题。详见How to develop using SSH in PyCharm
4.2 镜像和快照

由于容器是运行在宿主机上的,宿主机具有对容器体系举行备份、恢复的本领。LXD容器提供了镜像和快照功能,将当前体系天生镜像可以将其快速部署到新的体系上(需要LXD情况);通过天生体系快照,可以在体系出现问题时快速恢复到原先正常的状态。详细使用参考How to create LXD snapshot and image,注意:这一使用需要有权限访问宿主机。
4.3 新增用户

基于LXD容器的体系最大的利益就是能够为每个用户提供一个完整的独立的开发情况(Linux内核是全部用户公用的),每个用户都可以根据自己的需求修改体系设置而不会影响到其他用户。
然而,更强盛的方案往往意味着更高的技术门槛。因此,在不损失可玩性的同时,保证全部程度的用户拥有一个较好的体验,这里提供了两种使用方式。
4.3.1 在Common-Server上新增用户

第一种方式是在一个公用容器(已经建立好了一个Common- Server)上直接建立多个用户,然后每个用户分配对应的权限(目前按照最高用户权限来)。这种方式的利益是使用简朴,无需重新设置情况,对于新手大概对于无特别情况要求的开发者友好(Common-Server的内网穿透、PyTorch情况已经设置好了)。详细使用参考How to create a new LXD-based system,注意:这一使用需要有权限访问宿主机。
4.3.2 新增LXC容器用户

某些用户对开发情况有特别要求,且不希望和其它用户共享情况设置,则建议新增一个LXD容器体系。对于新增LXD容器体系,目前有两种方式,此中一种是直接根据Common-Server的镜像克隆一个体系(体系版本是Ubuntu18.04)。对于需要其它版本体系的用户,需要重新下载新的镜像安装,此时可根据需要设置开发情况。详细使用参考How to create a new LXD-based system,注意:这一使用需要有权限访问宿主机。
4.4 拓展空间

LXC体系给每个用户提供了一个独立、完整的存储管理体系,这个用户的数据被体系打包放到一个存储池被LXC平台统一管理,全部用户通过抢占的方式共享这个存储池。
然而,随着用户数目的增多这个存储池占用的空间会显著的变大,有时间需要添加额外的存储空间才能满足用户的需求。
在LXC平台中,可以存在多个存储池,每个存储池又可以包罗多个分区,体系有一套自动机制来管理数据的存储。因此要扩充存储池既可以直接增加存储池的个数,也可以增加包罗的分区个数来增加存储池的大小,另外还可以直接扩大分区的大小来增加存储池的大小。这三种方式分别对应不同层级的使用,同时具有不同的机动性、复杂性。
由于我需要添加的是同一块硬盘上的其他分区,且考虑到实现的复杂性,这里选择直接增加分区个数来增加存储池的大小。

实现细节见How to expand storage pool
五、远程桌面

5.1 方案选择和部署细节

在Windows下远程访问Linux服务器的桌面,有几种常见的方法:
xrdp(X Remote Desktop Protocol):xrdp允许Windows使用RDP(Remote Desktop Protocol)来连接到Linux服务器的桌面。这种方式相对简便,由于它使用Windows自带的远程桌面客户端。
VNC(Virtual Network Computing):VNC是一种基于图形界面的远程桌面协议,它允许用户远程访问Linux桌面。
由于xrdp可以兼容Windows远程桌面,因此这里接纳xrdp这种方法。
5.1.1 安装 RDP 服务器

在Ubuntu体系上,需要安装一个RDP服务器,如xrdp。使用以下命令安装:
  1. sudo apt-get update
  2. sudo apt-get install xrdp
复制代码
5.1.2 设置 Xfce4 桌面

xrdp默认使用Xfce4作为桌面情况,使用以下命令安装:
  1. sudo apt-get install xfce4
复制代码
5.1.3 设置 xrdp

安装完成后,可能需要设置xrdp以使用Xfce4。这通常涉及到编辑.xsession文件,确保它指向Xfce4。这里使用文本编辑器 Vim 编辑 ~/.xsession 文件,并添加以下行:
  1. xfce4-session
复制代码
5.1.4 启动 xrdp 服务

  1. sudo systemctl enable xrdp
  2. sudo systemctl start xrdp
复制代码
5.1.5 允许通过防火墙

这一步非必须,如果能连接到 RDP 服务器,则不需要执行这一步。否则,需要确保 RDP 端口 3389 在您的防火墙中是开放的。如果您使用的是ufw,可以使用以下命令:
  1. sudo ufw allow 3389/tcp
复制代码
5.2 远程桌面使用方式

5.2.1 局域网内连接到RDP服务器

首先连接局域网,在Windows机器上,打开Remote Desktop Connection应用步伐,并输入Ubuntu服务器的IP地址(比方192.168.31.90)。您应该会看到登录界面,输入Ubuntu的用户名和密码后,您就可以通过RDP访问Xfce4桌面了。比方:

5.2.2 从外部网络连接到RDP服务器

从外部网络访问内网的RDP服务器,需要把涉及的端口映射到公网IP,通常是3389端口,详细方法自行查阅资料,连接方法为:
  1. 公网IP/域名:公网映射的端口号
复制代码
比方:
  1. jack.tshinghua.me:33389
复制代码
本实行室人员需获取连接方式请接洽管理员。
六、TODO

6.1 LXD管理界面

LXD相比于LXC的利益就是多了界面管理,但是目前由于某些技术上的原因,还未能实现界面,请期待后续更新
6.2 一些办理的BUG

6.2.1 主机断电导致的GPU无法辨认

  1. user@Common-Server:~$ conda activate pytorch
  2. (pytorch) user@Common-Server:~$ python
  3. Python 3.8.18 (default, Sep 11 2023, 13:40:15)
  4. [GCC 11.2.0] :: Anaconda, Inc. on linux
  5. Type "help", "copyright", "credits" or "license" for more information.
  6. >>> import torch
  7. >>> print(torch.cuda.is_available())
  8. /home/user/.conda/envs/pytorch/lib/python3.8/site-packages/torch/cuda/__init__.py:138: UserWarning: CUDA initialization: CUDA unknown error - this may be due to an incorrectly set up environment, e.g. changing enble devices to be zero. (Triggered internally at ../c10/cuda/CUDAFunctions.cpp:108.)
  9.   return torch._C._cuda_getDeviceCount() > 0
  10. False
  11. >>> exit()
  12. (pytorch) user@Common-Server:~$ sudo reboot
复制代码
可能由于主机断点重启之后分配给容器的某些参数错误,详细原因参考UserWarning: CUDA initialization: CUDA unknown error - this may be due to an incorrectly set up environment, e.g. changing env variable CUDA_VISIBLE_DEVICES after program start. Setting the available devices to be zero - PyTorch Forums。
办理方法是再LXC服务启动之前在宿主机上初始化一下torch情况,首先需要新建一个脚本
  1. #!/bin/bash
  2. # 激活 conda 环境
  3. source /path/to/anaconda3/etc/profile.d/conda.sh
  4. conda activate pytorch
  5. # 运行 Python 脚本
  6. python - <<EOF
  7. import torch
  8. print(torch.cuda.is_available())
  9. EOF
  10. # 退出 conda 环境
  11. conda deactivate
复制代码
添加权限
  1. chmod +x /home/your_user/scripts/init_torch.sh
复制代码
新建自启动服务
  1. sudo nano /etc/systemd/system/init_torch.service
复制代码
内容如下
  1. [Unit]
  2. Description=Run init_torch script before LXC containers start
  3. Before=lxc-net.service
  4. [Service]
  5. Type=oneshot
  6. ExecStart=/home/your_user/scripts/init_torch.sh
  7. RemainAfterExit=true
  8. [Install]
  9. WantedBy=multi-user.target
复制代码
添加自启动服务到体系中
  1. sudo systemctl daemon-reload
  2. sudo systemctl enable init_torch.service
  3. sudo systemctl start init_torch.service
  4. sudo systemctl status init_torch.service
复制代码
参考文献

   LXD vs Docker
基于LXD搭建多人共用GPU服务器,简朴易用,全网最详细!
ubuntu使用VNC实现远程桌面
LXD教程入门实践 设置独立ip 挂载gpu显卡驱动 制作镜像
【保姆级教程】Windows 远程登录 Ubuntu桌面情况_windows登录ubantu桌面-CSDN博客
  所需要的质料可以在这里找到

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张裕

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表