slurm单机最简安装全球最详细教程
2021年1月27日本文指导你在Ubuntu 20.04下安装slurm 19.05。你只需要一台机器。本文不安装数据库。除了安装,本文还负责验证安装,并提供提交作业的范例。
安装
{{sudoText}}apt install -y slurm-wlm{{sudoText}}apt install -y slurm-wlm-doc
slurm-wlm-doc提供了相关文档,比如/usr/share/doc/slurm-wlm/html/configurator.html。如果你按照本slurm single machine minimal installation guide,你不需要用configurator来生成配置文件。
有的文章要求安装munge[1]——Authentication plugins identifies the user originating a message[2],官方网站说munge是一个plugin,对于到底单机模式要不要plug in说得不明不白。我这里并不告诉你是否要安装,你只要跟着本教程走就行了!apt install slurm-wlm的时候自动安装了munge,你就不用考虑要不要装了,反正已经装上了!
下载https://gist.github.com/gqqnbig/8a1e5082ec1c974a84fdd8abd1a4fbf6,注意检查开头三行的路径是否正确。运行结束后,不要运行systemctl相关的命令!
截至目前,slurm已经安装并配置完毕了,但到底能不能用还是个问号。不用systemctl是因为systemctl多加了一层包装,出错可能是systemctl出错,也可能是slurm出错,不易区分。所以,下面我们手动运行slurm。
按照官方文档,slurmctld运行在master节点,负责监视资源和作业;slurmd运行在计算节点(slave节点),负责执行作业。所以,因为我们只有一台机器,必须既运行slurmctld,又运行slurmd。注意,slurm软件本身并没有slurm命令。
验证
运行slurmctld
$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
normal* up infinite 1 unk* localhost
发现state是unknown*。unknown表示控制节点不知道节点localhost的状态。这是正常的,因为你还没有启动slurmctld。*表示节点localhost无法联通。[3]这是正常的,因为你还没有启动slurmd。
$ sudo slurmctld -c -D slurmctld: error: Unable to open pidfile `/var/run/slurm/slurmctld.pid': No such file or directory slurmctld: error: Configured MailProg is invalid slurmctld: slurmctld version 19.05.5 started on cluster 35adae022fc4478592f75c3b4c97bce1 slurmctld: No memory enforcing mechanism configured. slurmctld: layouts: no layout to initialize slurmctld: layouts: loading entities/relations information slurmctld: Recovered state of 0 reservations slurmctld: _preserve_plugins: backup_controller not specified slurmctld: Running as primary controller slurmctld: No parameter for mcs plugin, default values set
发现第一行就报错。打开/etc/slurm-llnl/slurm.conf,发现该路径由SlurmctldPidFile指定,而/var/run里没有slurm目录。按照经验,slurm不会创建目录。于是,在/etc/slurm-llnl/slurm.conf修改为
SlurmctldPidFile=/var/run/slurmctld.pid SlurmdPidFile=/var/run/slurmd.pid
再运行
$ sudo slurmctld -c -D slurmctld: error: Configured MailProg is invalid slurmctld: slurmctld version 19.05.5 started on cluster 35adae022fc4478592f75c3b4c97bce1 slurmctld: No memory enforcing mechanism configured. slurmctld: layouts: no layout to initialize slurmctld: layouts: loading entities/relations information slurmctld: Recovered state of 0 reservations slurmctld: _preserve_plugins: backup_controller not specified slurmctld: Running as primary controller slurmctld: No parameter for mcs plugin, default values set
发现pidfile的错误不见了。”error: Configured MailProg is invalid”问题不大,可以以后再修。slurm可以在job完成后发电子邮件通知,这个错误的意思是没有配置好邮件服务。
$ sinfo PARTITION AVAIL TIMELIMIT NODES STATE NODELIST normal* up infinite 1 down* localhost
发现控制节点已经知道节点localhost的状态为down。
接下来运行slurmd。
运行slurmd
$ sudo slurmd -D slurmd: Message aggregation disabled slurmd: WARNING: A line in gres.conf for GRES gpu has 1 more configured than expected in slurm.conf. Ignoring extra GRES. slurmd: slurmd version 19.05.5 started slurmd: slurmd started on Thu, 28 Jan 2021 02:59:20 +0000 slurmd: CPUs=48 Boards=1 Sockets=2 Cores=12 Threads=2 Memory=128573 TmpDisk=111654 Uptime=2860 CPUSpecList=(null) FeaturesAvail=(null) FeaturesActive=(null)
同时发现slurmctld的日志已经输出”slurmctld: Node localhost now responding”,运行sinfo发现
$ sinfo PARTITION AVAIL TIMELIMIT NODES STATE NODELIST normal* up infinite 1 down localhost
到目前为止,控制节点和计算节点的通信已经正常。但是第二行有警告“WARNING: A line in gres.conf for GRES gpu has 1 more configured than expected in slurm.conf. Ignoring extra GRES.”
打开/etc/slurm-llnl/gres.conf,发现有Name=gpu File=/dev/nvidia[0-1]
,说明刚才的自动脚本已经正确识别到了本机有两个GPU。打开/etc/slurm-llnl/slurm.conf,发现有NodeName=localhost Gres=gpu CPUs=8 Boards=1 SocketsPerBoard=2 ...
。这是不对的。根据slurm.conf – Slurm configuration file,Gres的参数必须有number项,所以要修改为
NodeName=localhost Gres=gpu:2 CPUs=8 Boards=1 SocketsPerBoard=2 ...
重启slurmctld和slurmd,发现该错误消失了。
接下来测试提交作业。
提交作业
$ sinfo PARTITION AVAIL TIMELIMIT NODES STATE NODELIST normal* up infinite 1 idle localhost $ squeue JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON) $ scontrol show job No jobs in the system
以上代码显示slurm单机集群正常,目前没有任何job(作业),队列为空。
下面提交一个作业,要求运行名为hostname的程序。hostname是Linux的内置程序,用来打印当前机器的名称。-N1表示hostname程序要在1个节点运行。
$ srun -N1 hostname gqqnbig
如果该命令迟迟不返回,可能是防火墙问题。
下面提交一个作业,要求运行名为hostname的程序。–nodes=2-3表示该程序要在2到3个节点运行。显然,本文只配置单机集群,没有这么多计算节点,本命令会陷入无限等待。
$ srun --nodes=2-3 hostname srun: Requested partition configuration not available now srun: job 17 queued and waiting for resources
在另一个命令行窗口运行
$ squeue JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON) 17 normal hostname gqqnb PD 0:00 2 (PartitionNodeLimit)
发现job 17正在等待。回到原来的命令行窗口,按ctrl+c终止job 17。至于--nodes
还可以接受什么样的参数,请参见man srun。
测试资源限制
使用《浅谈Linux Cgroups机制》()的C++代码。
#include <unistd.h>
#include <stdio.h>
#include <cstring>
#include <thread>
void test_cpu() {
printf("thread: test_cpu start\n");
int total = 0;
while (1) {
++total;
}
}
void test_mem() {
printf("thread: test_mem start\n");
int step = 20;
int size = 10 * 1024 * 1024; // 10Mb
for (int i = 0; i < step; ++i) {
char* tmp = new char[size];
memset(tmp, i, size);
sleep(1);
}
printf("thread: test_mem done\n");
}
int main(int argc, char** argv) {
std::thread t1(test_cpu);
std::thread t2(test_mem);
t1.join();
t2.join();
return 0;
}
编译并运行
$ g++ -o test test.cc --std=c++11 -lpthread $ ./test
htop
发现CPU占用为100%,内存慢慢涨到约400MB。(如果htop显示三个test,按H切换到进程模式,就只会显示一个了。)运行srun ./test
,内存占用相同。
限制内存
现在实现内存限制。在/etc/slurm-lnl/cgroup.conf写入
CgroupAutomount=yes MaxRAMPercent=0.1 ConstrainRAMSpace=yes
在/etc/slurm-llnl/slurm.conf写入或修改
ProctrackType=proctrack/cgroup TaskPlugin=task/cgroup
重启slurmctld和slurmd,确保没报任何异常。这时再运行srun ./test
,发现RES被限制在12MB,VIRT则很大,说明内存限制成功。(但我们没有限制虚拟内存)
限制CPU
创建文件test-cpu.py,运行它。test-cpu.py输出CPU的数量,并且创建该数量的线程。
#!/usr/bin/env python3
import threading, multiprocessing
import time
print(multiprocessing.cpu_count())
def loop():
x = 0
while True:
x = x ^ 1
for i in range(multiprocessing.cpu_count()):
t = threading.Thread(target=loop)
print(f'create a thread {i}...', flush=True)
t.start()
ps -eLF | grep test-cpu | sort -n -k9
第9列显示的是test-cpu的线程所在的CPU,发现test-cpu.py运行在数个CPU上。
现在用slurm限制,运行srun -c4 ./test-cpu.py
,再运行ps,发现test-cpu.py运行在4个CPU上。
这说明,向slurm申请CPU,slurm就只分配那么多个CPU。虽然multiprocessing.cpu_count()
能获取到真实的CPU数量,但无法全部使用。
另外也可以通过scontrol show job
来检查-c的设置是否生效。
注意,一个slurm job仍然可以看到所有用户或slurm job的进程。 你可以设置hidepid=2令用户只能看到自己的进程。[4]mount -o ...,hidepid=2 /proc
这个技术跟slurm无关。
申请GPU
运行tf-GPU-test.py并申请4个GPU。
srun --gres=gpu:4 python tf-GPU-test.py
import time
if __name__ == '__main__':
# 大概需要300MB内存
arr = [None] * 10000000
time.sleep(10)
for i in range(len(arr)):
arr[i] = i
time.sleep(10)
print('done')
https://stackoverflow.com/questions/52421171/slurm-exceeded-job-memory-limit-with-python-multiprocessing
$ srun --mem=100G hostname srun: error: Memory specification can not be satisfied srun: error: Unable to allocate resources: Requested node configuration is not available
我们的机器内存没有100G,所以该任务无法运行。把命令改为srun --mem=10M hostname
就可以运行。同时也发现,--mem
并不限制任务本身的内存占用。
但不允许存在于百度旗下网站
参考资料
neurokernel. gpu-cluster-config/slurm.conf. . 2016-03-13 [2021-01-28].
参考资料
- . SLURM single node install. . [2021-01-27].↑
- . Download Slurm. Slurm. [2021-01-27].↑
- . sinfo - View information about Slurm nodes and partitions.. . [2021-01-28]. “NODE STATE CODES”↑
- Vivek Gite. Linux hide processes from other users and ps command. . 2021-06-13 [2022-09-04].↑
你好我按照你的的方法运行了instant-slurm.sh之后,输入sinfo
给出的结果是slurm_load_partitions:unable to contact slurm controller(connect failure)
请问这是怎么回事呢
希望能得到你的帮助
按照字面意思,应该是你没有运行slurm controller,即slurmctld。本文运行的slurm版本是19.05.5,它的sinfo不依赖slurmctld。其他版本的slurm的行为可能不一样。