如何配置高性能服务器用于实验室科研?
由于实验室的科研活动日益丰富,对计算机算力的需求也直线攀升,现有的两台小型服务器算力均有限,常常显得捉襟见肘。因此,配置一台高性能服务器用于日常科研、同时配合合适的软件架构在实验室成员之间形成硬件资源共享显得迫在眉睫。本文记录了2023年夏季开始为实验室配置高性能服务器的一些碎片信息。
1. 硬件
1.1. 小杯版
该版本是面向个人使用的廉价版服务器,因此也是凑齐了各种洋垃圾,怎么便宜怎么来;同时又在一定程度上兼顾性能,不至于运行不了常用的科学计算环境。
部件名称 | 品牌型号 | 性能参数 | 数量 | 单价 |
主板 | 华南金牌X99-F8D PLUS | C612芯片组,2个LGA2011-3处理器接口,8个DDR4-2400内存插槽(2DPC, 256GB, ECC),3个PCIe3×16插槽,3个PCIe3×8插槽,2个PCIe3×4 M2NVME接口,6个SATA3接口。EATX规格(12×13in),1个24pin主板供电,2个8pinCPU供电。 | 1 | 918.00 |
处理器 | 英特尔志强E5-2690V4 | LGA2011-3接口,2.6GHz基频/3.5GHz睿频,14核心28线程,4通道DDR4-2400内存(1.5TB, ECC),40条PCIe3线路,135W额定功率。 | 2 | 144.50 |
处理器散热 | 寒冰A700 | 1个12CM风扇,6热管。 | 2 | 99.00 |
显卡 | 微星RTX 2080 Ti改显存版 | 300A核心,4352CUDA核心,1.35GHz基频/1.64GHz睿频,22GB GDDR6显存,352bit显存位宽。PCIe3×16接口,双槽厚单涡轮,2个8pinPCIe供电,250W额定功率。 | 1 | 2699.00 |
内存 | 三星16G 2RX4 PC4-2400T | 16GB容量,DDR4-2400频率(RECC)。 | 8 | 124.75 |
固态硬盘 | 英睿达P3 PLUS 1TB | 1TB容量,PCIe4×4 M2NVME接口,R5000M/W3600M/RR650K/RW800K。 | 2 | 299.00 |
机械硬盘 | (无) | |||
电源 | 航嘉MVP P1000 | 80PLUS白金,12V83.4A。 | 1 | 1059.00 |
机箱 | X99双路主板开放式托架 | 支持EATX/ATX/MATX/ITX规格。 | 1 | 39.00 |
机箱散热 | (无) | |||
键盘鼠标 | 罗技MK315键鼠套装(旧) | 无线鼠标M330+无线键盘K235。 | 1 | 0.00 |
显示器 | CFORCE便携式显示器CF015QMax | 4K QLED面板,100% AdobeRGB色域,500nits亮度,60Hz刷新率。 | 1 | 1349.00 |
其它 | 开博尔DP转HDMI线 | 8K@60Hz/4K@144Hz/2K@240Hz分辨率,2米长。 | 1 | 209.00 |
总计 | 8147.00 |
部件名称 | 品牌型号 | 性能参数 | 数量 | 单价 |
主板 | 华硕Pro WS W790E-SAGE SE | W790芯片组,1个LGA4677处理器接口,8个DDR5-4800内存插槽(1DPC, 2TB, RECC),6个PCIe5×16插槽,1个PCIe5×8插槽,2个PCIe5×4 M2NVME接口,8个SATA3接口。EEB规格(12×13in),1个24pin主板供电,2个8pinCPU供电,1个8pinPCIe供电,1个6pinPCIe供电。 | 1 | 12541.90 |
处理器 | 英特尔志强W9-3475X | LGA4677接口,2.2GHz基频/4.8GHz睿频,36核心72线程,8通道DDR5-4800内存(4TB, ECC),112条PCIe5线路,300W额定功率/360W睿频功率。 | 1 | 29628.60 |
处理器散热 | abee Apex Plus SPR360一体式水冷 | 3个12CM风扇。 | 1 | 1529.50 |
显卡 | 英伟达RTX 4090 FE公版 | 16384CUDA核心,2.23GHz基频/2.52GHz睿频,24GB GDDR6X显存,384bit显存位宽。PCIe4×16接口,三槽厚双涡轮,3个8pinPCIe供电,450W额定功率。 | 2 | 15999.00 |
内存 | 海力士32GB DDR5 4800 ECC RDIMM | 32GB容量,DDR5-4800频率(RECC)。 | 8 | 899.00 |
固态硬盘 | 英睿达P5 PLUS 2TB | 2TB容量,PCIe4×4 M2NVME接口,R6600M/W5000M/RR720K/RW700K。 | 2 | 874.00 |
机械硬盘 | 西部数据HC320 8TB | 8TB容量,SATA3接口,7200RPM转速,CMR模式。 | 1 | 1349.00 |
电源 | 航嘉MVP P1200X | 80PLUS白金,12V100A。 | 2 | 1299.00 |
机箱 | PHANTEKS追风者PK620PTG | 支持EATX/ATX/MATX/ITX规格。 | 1 | 1079.00 |
机箱散热 | PHANTEKS追风者SK神光 | 3个12CM风扇套装。 | 4 | 99.00 |
键盘鼠标 | (暂无) | |||
显示器 | (暂无) | |||
其它 | (暂无) | |||
总计 | 90060.00 |
2. 软件
2.1. 小杯版:请参考之前的内容,“ 如何配置Windows和Ubuntu双系统?”和“如何在Ubuntu中配置基于显卡加速的强化学习环境?”。
2.2. 大杯版:
(1) 首先,依然与小杯版一样给服务器安装双系统:Windows系统主要留作备用,用来应付一些需要高性能显卡渲染的设计软件;Ubuntu系统则作为日常使用,主要进行基于高性能显卡的科学计算。这里需要注意的是,安装Ubuntu系统的时候需要使用板载的VGA视频输出,不要使用显卡的DP或HDMI视频输出,否则服务器无法从Ubuntu安装优盘启动并进行后续安装步骤,原因未知。
(2) 考虑到服务器硬件较新,为了防止出现驱动问题,选择安装Ubuntu 22.04。系统安装完成后,通过以下命令固定Linux内核版本,防止内核更新影响显卡驱动(据说显卡驱动安装时需要根据内核版本编译,内核版本一旦更新,显卡驱动可能需要重新编译):
$sudo apt-mark hold linux-image-generic linux-headers-generic
$sudo apt-mark showhold
(3) 【2024.04.09注:使用Network Repo取代Local Repo来安装CUDA可以自由选择CUDA的版本号,具体请参考下面链接里的安装说明。】
由于服务器显卡较新,尝试过安装CUDA 11.8,但并未成功,不知道是否当时操作不当。因此,选择CUDA 12.2和cuDNN 8.9.5.30,该组合是根据libcudnn8的版本信息得到,参考网址为:
https://developer.download.nvidia.cn/compute/cuda/repos/ubuntu2204/x86_64/
注意如果是其它系统版本则修改上述网址对应部分应该即可查看对应网页。最终,安装的显卡驱动版本为535.54.03,具体安装流程可参考“如何在Ubuntu中配置基于显卡加速的强化学习环境?”,在此不再赘述。
(4) 驱动安装完毕后,继续安装一些常用的程序包:
$sudo apt update
$sudo apt install python3-pip ssh net-tools bridge-utils zfsutils-linux
$sudo snap refresh
$sudo snap install nvtop
(4.5) 【2024.04.10】为了防止服务器被ssh暴力攻击(血泪教训),需要给ssh添加防止过多登录尝试的机制,通过PAM(Pluggable Authentication Module)实现,主要修改/etc/pam.d/common-auth和/etc/pam.d/common-account两个文件。
在/etc/pam.d/common-auth文件中,于pam_unix.so nullok一行前添加:
auth required pam_faillock.so preauth even_deny_root deny=3 fail_interval=3600 unlock_time=3600 audit silent
于pam_deny.so一行前添加:
auth [default=die] pam_faillock.so authfail even_deny_root deny=3 fail_interval=3600 unlock_time=3600 audit
auth sufficient pam_faillock.so authsucc even_deny_root deny=3 fail_interval=3600 unlock_time=3600 audit
在/etc/pam.d/common-account文件中,于文件末尾添加:
account required pam_faillock.so
上述脚本的含义可以查看pam_faillock指令的说明文档。一些有用的命令行管理指令:
查看所有用户的失败登录尝试
$faillock
查看指定用户的失败登录尝试
$faillock --user [username]
重置指定用户的失败登录尝试允许次数
$faillock --user [username] --reset
(5) 本服务器最终选择通过LXD方案来共享硬件,即在LXD环境下为每位用户分别建立个人专属的操作系统容器(container)来共享宿主机硬件。此外,LXD还支持建立操作系统虚拟机(VM),但是虚拟机不像容器一样直接使用宿主机的系统内核和设备,性能上会有一定的损失;因此除非是有特殊的需求,否则不推荐使用。LXD的官方文档可以在以下网址查看:
https://documentation.ubuntu.com/lxd/en/latest
该文档组织有点散乱,可能需要自行组建知识框架。
(6) 安装LXD:
$sudo snap install lxd
如果需要针对服务器集群(cluster)固定LXD版本,则:
$sudo snap refresh --hold lxd
单服务器暂时没发现有此需求。
(7) 创建存储池(Storage Pool):
由于本服务器的Windows和Ubuntu系统分别安装在两个独立SSD上,另配有一个独立HDD用来存储LXD的相关数据,包括镜像、容器、虚拟机等,因此需要将HDD创建成一个存储池,存储驱动选择ZFS。通过
$sudo fdisk -l
找出HDD所对应的磁盘。本服务器中,两块SSD分别为/dev/nvme0n1和/dev/nvme1n1,HDD则为/dev/sda;通过Ubuntu自带的disks图形程序也可以查到相关信息。确保HDD上用来创建存储池的空间处于未分配状态。使用
$zpool list
来查看当前已经存在的存储池,不出意外的话应该是空。再通过
$sudo zpool create weiZPool /dev/sda
来创建存储池,并再次通过
$zpool list
来查看创建好的存储池。weiZPool是给存储池起的名字,可以按需变换。
(8) 初始化LXD:
$lxd init
根据指引回答问题来一步一步完成初始化,本服务器的回答为:
$Would you like to use LXD clustering? (yes/no) [default=no]:
$Do you want to configure a new storage pool? (yes/no) [default=yes]:
$Name of the new storage pool [default=default]: weiStoragePool
$Create a new ZFS pool? (yes/no) [default=yes]: no
$Name of the existing ZFS pool or dataset: weiZPool
$Would you like to connect to a MAAS server? (yes/no) [default=no]:
$Would you like to create a new local network bridge? (yes/no) [default=yes]:
$What should the new bridge be called? [default=lxdbr0]: weiBridge
$What IPv4 address should be used? (CIDR subnet notation, "auto" or "none") [default=auto]:
$What IPv6 address should be used? (CIDR subnet notation, "auto" or "none") [default=auto]:
$Would you like the LXD server to be available over the network? (yes/no) [default=no]:
$Would you like the stale cached images to be updated automatically? (yes/no) [default=yes]:
$Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
初始化完毕后,可以通过如下一些简单命令来查看系统信息:
$lxc profile show default
$lxc storage list
$lxc network list
$lxc list
可以看到,默认(default)的概述(profile)里面包含了刚刚创建的weiStoragePool和weiBridge相关信息,它们也出现在了存储(storage)和网络(network)的列表里面,而最后一个命令的输出表格为空,那是因为目前还没有创建任何实例(instance),无论是容器(container)还是虚拟机(VM)。
(9) 配置LXD:
接下来配置一下LXD,方便后面为各用户批量创建实例(instance),包括修改默认概述(profile: default)和添加必要的设备(device),这些可以在后续创建实例的时候被继承到每个实例的配置中。
$lxc profile set default boot.autostart true
$lxc profile set default security.privileged false
$lxc profile set default security.nesting true
$lxc profile set default environment.DISPLAY :0
$lxc profile device add default weiGPU gpu
$lxc profile device add default cuda-12.2 disk source=/usr/local/cuda-12.2 path=/usr/local/cuda-12.2
$lxc profile device add default X0 proxy bind=container connect=unix:/tmp/.X11-unix/X1 listen=unix:/mnt/X0 security.gid="1000" security.uid="1000"
(10) 拷贝镜像(image):
系统镜像可以自己创建并导入,也可以从远端服务器拷贝。LXD官方提供了若干镜像服务器,可以通过
$lxc remote list
查看,其中:local服务器为本地,从其它服务器上拷贝而来的镜像将存放在这里;images服务器提供各种Linux发行版;ubuntu服务器则提供Ubuntu相关镜像。可以使用如下命令查看服务器内含镜像:
$lxc image list local:
$lxc image list images:
$lxc image list ubuntu:
通过如下命令将常用镜像拷贝到本地服务器:
$lxc image copy ubuntu:22.04 local:
$lxc image copy ubuntu:20.04 local:
$lxc image list
(11) 创建实例(instance):
$lxc launch ubuntu:22.04 weiUbuntu2204
由于该镜像已经保存在本地服务器(local:),所以省去了下载镜像的时间。上述命令中,launch可以换成init,效果一样;weiUbuntu2204为实例的名称,可以按需变换。创建好实例后,可以通过
$lxc list -c ns4umD
$lxc info weiUbuntu2204
来查看实例状态,也可以通过如下指令来查看实例的配置:
$lxc config show weiUbuntu2204 --expanded
此处,还需要给实例设置静态IP和端口转发,方便远程连接:
$lxc stop weiUbuntu2204
$lxc network show weiBridge
$lxc config device override weiUbuntu2204 eth0 ipv4.address=[containerIP]
$lxc config device add weiUbuntu2204 weiProxy proxy listen=tcp:[hostIP]:[hostPort] connect=tcp:[containerIP]:22 bind=host
$lxc start weiUbuntu2204
其中,[hostIP]可以通过ip addr或者ifconfig(需要安装net-tools)查看,[containerIP]可以设置为期望的静态IP,但是需要在weiBridge网关的网段内,而[hostPort]取值0到65535均可,注意0到1023为保留段,通常设置为6000往后的值避免冲突。
(12) 配置实例:
创建好实例后,在宿主机上可以通过如下命令进入实例:
$lxc exec weiUbuntu2204 bash
默认以root身份进入,先进行密码的设置:
$passwd root
$passwd ubuntu
其中ubuntu为另一个默认用户,后面通过ssh远程连接容器的时候即以该身份进入。
然后安装一些必要的程序包:
$sudo apt update
$sudo apt upgrade
$sudo apt install gcc g++ ssh net-tools build-essential python3-pip
再对ssh的相关配置进行修改:
$nano /etc/ssh/sshd_config
将PasswordAuthentication的赋值从no改为yes,然后快捷键ctrl+O写出,回车保存,然后快捷键ctrl+X退出。再通过命令行:
$/etc/init.d/ssh restart
来重启该容器的ssh服务。
【2024.04.10】巨坑的是,在当前LXD官方的22.04系统内,/etc/ssh/sshd_config.d/文件夹下有一个.conf文件将PasswordAuthentication设置成了no,并被包含在/etc/ssh/sshd_config文件中,需要解除包含关系;因为这个被卡ssh无法登录,花费了大半天时间测试寻找原因。所以注意检查如下两个文件夹:/etc/ssh/sshd_config.d/和/etc/ssh/ssh_config.d/。
【2024.04.10】这里同样需要给每个容器添加防止ssh过多登录尝试的机制,方法相同。
【2024.04.10】由于指纹变更,客户机需要清除旧的ssh指纹才能通过重新连接服务器(下面指令中方括号不可少):
$ssh-keygen -R [hostIP]:hostPort
(13) 配置实例内显卡驱动:
此时,理论上已经有两种方法可以进入容器,除了通过上述在宿主机运行
$lxc exec weiUbuntu2204 bash
这一指令以外,还可以通过另一台电脑ssh远程连接:
$ssh -X ubuntu@[hostIP] -p [hostPort]
继续以root身份在容器中执行如下命令:
$sudo apt install pkg-config libvulkan1 libegl1 libglvnd0 libglvnd-dev libglx0 libgl1
$cd ~
$mkdir Downloads
$cd Downloads
$wget https://us.download.nvidia.com/tesla/535.54.03/NVIDIA-Linux-x86_64-535.54.03.run
$sudo sh ./NVIDIA-Linux-x86_64-535.54.03.run --no-kernel-module
注意最后的--no-kernel-module一定不能丢,不然会无法调用宿主机的显卡驱动。安装过程会进入图形界面,除了当询问是否运行nvidia-xconfig来更新X配置文件时选择同意以外,其余全部回车选择默认选项即可。然后通过如下命令建立CUDA驱动的链接:
$sudo ln -s /usr/local/cuda-12.2 /usr/local/cuda
进一步,配置环境变量:
$nano /home/ubuntu/.bashrc
打开文件后,在文件末尾添加如下信息:
export PATH=/usr/local/cuda/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
export LIBRARY_PATH=/usr/local/cuda/lib64${LIBRARY_PATH:+:${LIBRARY_PATH}}
然后快捷键ctrl+O写出,回车保存,然后快捷键ctrl+X退出。退出后通过如下命令已经可以查看到显卡驱动信息了,和宿主机一模一样:
$nvidia-smi
最后,建立远程连接容器时的图形界面接口:
$sudo ln -s /mnt/X0 /tmp/.X11-unix/X0
由于/tmp文件夹下的内容会在容器重启后清空,但/mnt文件夹不会,因此还需要通过cron程序设置开机自启动命令:
$crontab -e
在打开的文件末尾添加如下代码:
@reboot ln -s /mnt/X0 /tmp/.X11-unix/X0
@reboot chmod a+wx /tmp/.X11-unix/X0
完成后,保存退出即可。此外,为了运行基于snap的图形化应用程序,还需要通过:
$nano /home/ubuntu/.bashrc
修改环境变量:
export XAUTHORITY=$HOME/.Xauthority
保存后退出即可。目前已知20.04不需要,但是22.04需要。
(14) 生成实例模板:
最后,若需要利用此容器生成实例模板,可以通过如下命令清理容器:
$sudo rm -rfv /var/lib/apt/lists/*
完成后退出容器:
$exit
进一步,在宿主机通过以下命令生成模板:
$lxc stop weiUbuntu2204
$lxc publish weiUbuntu2204 local: --alias templateUbuntu2204
若要使用模板建立新的实例,则执行以下命令:
$lxc launch local:templateUbuntu2204 xyzUbuntu2204
$lxc list
生成新的实例后前述大部分配置都已经继承,还需重新定义以下配置:
$lxc config device override xyzUbuntu2204 eth0 ipv4.address=[containerIP]
$lxc config device add xyzUbuntu2204 xyzProxy proxy listen=tcp:[hostIP]:[hostPort] connect=tcp:[containerIP]:22 bind=host
$lxc exec xyzUbuntu2204 bash
$passwd root
$passwd ubuntu
(15) 至此,所有操作完毕,服务器应该可以通过容器分享硬件了。
服务器端可以通过以下命令行来查看各容器的使用情况:
$lxc list -c ns4umD
其中,n表示容器名称,s表示容器状态,4表示容器的IPv4地址,u表示容器的CPU使用秒数,m表示内存的占用情况,D表示磁盘的占用情况。
还可以通过如下命令查看存储池的总使用情况:
$lxc storage list
$lxc storage info [poolName]
此外,远程客户端可以通过scp命令与服务器上的容器产生文件交互(上传和下载):
$scp -P [hostPort] [localFilePath] ubuntu@[hostIP]:[hostFilePath]
$scp -P [hostPort] ubuntu@[hostIP]:[hostFilePath] [localFilePath]
如果是上传或下载整个文件夹,还需要在scp和-P之间增加一个-r的旗子,表示recursively。
容器内如果pip3 install的下载速度太慢,可以考虑更换下载源,例如:
$pip3 install [packageName] -i https://mirrors.aliyun.com/pypi/simple/