Slurm + OpenMPI集群搭建

Slurm

系统: Ubuntu 22.04

四个虚拟机充当四台计算机

Slurm版本:24.5

主机名用途IP
node1管理节点/数据库服务节点192.168.1.101
node2存储节点/计算节点192.168.1.102
node3计算节点192.168.1.103
node4计算节点192.168.1.104

以下操作如果没有特别说明都是在四台机器中执行相同命令,Xshell可以在工具栏中的工具->发送键输入到->所有会话,这样就可以在一台机器上同时控制四台

没有特别说明的话,默认登录用户就是ROOT用户

前期准备

安装一些基础软件

$ apt install gcc g++ make bzip2 zlib1g-dev

bzip2:解压缩时候需要

zlib1g-dev: pmix 和 openmpi好像是用到了,不安装也不会报错,但是运行mpirun的时候会有个提示,说是建议安装zlib

NTP服务确保时钟同步

这个是配置时区

$ timedatectl set-timezone Asia/Shanghai

参考: Linux服务器时间同步chrony详解+案例

Chrony是网络时间协议(NTP)的实现。

  • 使系统时钟与NTP服务器同步,
  • 使系统时钟与参考时钟(例如GPS接收器)同步,要将系统时钟与手动时间输入同步,
  • 作为NTPv4(RFC 5905)服务器或对等方以向网络中的其他计算机提供时间服务。
  • Chrony在各种条件下都表现良好,包括间歇性网络连接,网络严重拥塞,温度变化(普通计算机时- - 钟对温度敏感)以及无法连续运行或在虚拟机上运行的系统。
$ apt install chrony

NTP服务端

将node1 作为NTP服务端,在 [/etc/chrony/chrony.conf] 配置文件中添加以下内容

$ vim /etc/chrony/chrony.conf
server ntp.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp1.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp2.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp3.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp4.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp5.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp6.aliyun.com minpoll 4 maxpoll 10 iburst
server 127.0.0.1  iburst
#允许所有网段网段
allow all
# 允许在外部时间同步服务器不可用时,使用服务器本地时间作为返回值
local stratum 10

# 重启服务
$ systemctl restart chrony

NTP客户端

在其它三个节点内的相应的配置文件中添加以下内容

$ vim /etc/chrony/chrony.conf
server node1  iburst

# 重启服务
$ systemctl restart chrony

如果有的网卡支持IPV6那么可能启动chrony服务时会报错,但是不影响启动

Could not open command socket on [::1]:323

要想消除这个错误需要修改以下脚本添加 -4 参数,表示只使用IPV4

$ vim /usr/lib/systemd/scripts/chronyd-starter.sh
${CMD} ${EFFECTIVE_DAEMON_OPTS} -4
# 重启服务
$ systemctl restart chrony

配置SSH免密登录

参考:SSH的免密登录详细步骤

配置主机名与IP的映射

$ vim /etc/hosts
192.168.1.101 node1
192.168.1.102 node2
192.168.1.103 node3
192.168.1.104 node4

生成公钥、私钥, 在管理节点中操作生成即可,其它节点不生成。
会提示三次输入,全部回车即可。

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:jFHBDC2mk3VNKDD+1/qy/0dUV7aM5yvbgXdrxUOHPnc root@node1
The key's randomart image is:
+---[RSA 3072]----+
|    o..=o=.     +|
|   . .=.* .   o.+|
|    .=.+     . *.|
|    +. + .    =..|
|     .o S .  o.o.|
|       . .    =.E|
|        .    + *=|
|        ..    *.+|
|        .+o..o.o |
+----[SHA256]-----+

生成公钥私钥后将公钥发送到其它节点上,公钥文件目录: ~/.ssh/id_rsa.pub,中间会让输入两次,第一次yes和第二次的node2节点的密码。
拷贝以后即可在其它节点上的~/.ssh/authorized_keys文件中看到公钥内容。

$ ssh-copy-id root@node2
ssh-copy-id root@node2
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host 'node2 (192.168.1.102)' can't be established.
ED25519 key fingerprint is SHA256:zqKqNGCCc+C5C7WmvcJxNYgp+Vt+58od/ShgU0PJPFA.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@node2's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@node2'"
and check to make sure that only the key(s) you wanted were added.
$ ssh-copy-id root@node3
$ ssh-copy-id root@node4

配置好以后可以通过ssh命令进行测试是否可以免密登录,如果不成功的话,注意目录和文件的权限问题

# 目录和文件权限如下 .ssh 目录权限为 700   authorized_keys文件权限是600
drwx------  2 root root  4096 Oct 25 10:59 .ssh
-rw------- 1 root root    0 Oct 22 11:53 authorized_keys
$ ssh node2
$ ssh node3
$ ssh node4

配置NFS共享目录

NFS服务端

NFS共享目录我打算在node2上安装,node2为共享服务端

$ apt install nfs-kernel-server

创建共享NFS目录

$ mkdir /opt/share

编辑配置文件

$ vim /etc/exports
# /etc/exports: the access control list for filesystems which may be exported
#               to NFS clients.  See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes       hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4        gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes  gss/krb5i(rw,sync,no_subtree_check)
#

/opt/share *(rw,sync,no_subtree_check,root_squash)

/opt/share:指定/opt/share为nfs服务器的共享目录
*:允许所有的网段访问,也可以使用具体的IP
rw:挂接此目录的客户端对该共享目录具有读写权限
sync:资料同步写入内存和硬盘
root_squash: 当客户端以root用户访问时,映射为匿名用户
no_root_squash:root用户具有对根目录的完全管理访问权限,映射为root用户
no_subtree_check:不检查父目录的权限

重启nfs服务

$ systemctl restart nfs-kernel-server
# 查看共享是否成功
$ showmount -e localhost
Export list for localhost:
/opt/share *

NFS客户端

也就是除了node2节点的其它节点进行操作

安装NFS 客户端

$ apt install nfs-common

创建共享挂载点

$ mkdir /opt/share

挂载共享目录

$ mount -t nfs -o nolock 192.168.1.102:/opt/share /opt/share
# 查看是否挂在成功
$ df -h
192.168.1.102:/opt/share            14G  8.3G  4.7G  64% /opt/share

-t:挂载的文件系统类型
-o nolock:不要文件锁
192.168.xxx.xxx:/opt/share:nfs服务器ip:服务器共享目录
/opt/share:客户端共享目录挂载点

设置开机自动挂载

$ vim /etc/fstab
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
192.168.1.102:/opt/share /opt/share nfs -nolock 0 0

源码编译MUNGE

MUNGE(MUNGE Uid ‘N’ Gid Emporium)是一个用于创建和验证用户凭证的身份验证服务。它专为高性能计算(HPC)集群环境设计,旨在提供高度可扩展的身份验证解决方案。MUNGE 允许在共享安全域内的主机之间进行用户身份验证,而无需使用 root 权限、保留端口或平台特定方法。

$ cd /opt/software
$ wget https://github.com/dun/munge/releases/download/munge-0.5.16/munge-0.5.16.tar.xz
$ tar -xvf munge-0.5.16.tar.xz
$ cd munge-0.5.16
# 安装软件依赖
$ apt install libssl-dev pkg-config
# 默认安装位置 /usr/local
$ ./configure
$ make -j
$ make install
# 将munge动态库添加到系统内
$ ldconfig -v

添加munge用户,添加munge用户主要是为了启动munge这个服务的,因为系统服务文件中明确规定了的用户就是munge,如果以其它用户去启动的话会报错。

所以我想是不是更改这个服务文件中的用户名就可以呢?

$ cat /usr/local/lib/systemd/system/munge.service
[Unit]
Description=MUNGE authentication service
Documentation=man:munged(8)
Wants=network-online.target
After=network-online.target
After=time-sync.target

[Service]
Type=forking
EnvironmentFile=-/usr/local/etc/default/munge
ExecStart=/usr/local/sbin/munged $OPTIONS
PIDFile=/usr/local/var/run/munge/munged.pid
RuntimeDirectory=munge
RuntimeDirectoryMode=0755
User=munge
Group=munge
Restart=on-abort

[Install]
WantedBy=multi-user.target

暂时先按着其它文章中的操作做一遍, 为了保持munge的uid和gid在所有的节点上一致,创建时指定固定uid和gid,确保指定的uid和gid不存在即可

# 添加munge用户组和用户
$ export MUNGEUSER=1120
$ groupadd -g $MUNGEUSER munge
$ useradd -u $MUNGEUSER -m -s /bin/bash -g munge -G sudo munge
$ passwd munge

管理节点生成munge.key文件并分发到其它节点,其它节点无需操作这一步。
确保每个节点的/etc/munge所属用户和组是munge就可以了。

# 赋值用户和组的这两个命令需要都执行
$ chown -R munge.munge /usr/local/etc/munge
# 哪个文件没有就创建哪个文件就可以了
$ chown -R munge.munge /usr/local/var/{lib,run,log}/munge

# 以下命令在管理节点上执行就可以
# 使用官方脚本生成
$ sudo -u munge mungekey --verbose
mungekey: Info: Created "/usr/local/etc/munge/munge.key" with 1024-bit key
# 分发key文件到其它节点上
$ scp /usr/local/etc/munge/munge.key munge@node2:/usr/local/etc/munge/munge.key
$ scp /usr/local/etc/munge/munge.key munge@node3:/usr/local/etc/munge/munge.key
$ scp /usr/local/etc/munge/munge.key munge@node4:/usr/local/etc/munge/munge.key

启动munge服务

# /var/run/munge 在我启动这个服务后就有了
$ sudo -u munge systemctl start munge
# 设置开机自启
$ systemctl enable munge
# 测试
$ munge -n | unmunge
STATUS:          Success (0)
ENCODE_HOST:     node1 (192.168.1.101)
ENCODE_TIME:     2024-10-25 16:36:33 +0800 (1729845393)
DECODE_TIME:     2024-10-25 16:36:33 +0800 (1729845393)
TTL:             300
CIPHER:          aes128 (4)
MAC:             sha256 (5)
ZIP:             none (0)
UID:             root (0)
GID:             root (0)
LENGTH:          0

# 验证远程解码
$ munge -n | ssh node2 unmunge

安装mysql

这个图省事就直接使用apt进行安装了,mysql只在运行 slurmdbd 服务的节点上安装即可,我选择了node1节点。

$ apt install mysql-server
# 这个是为了编译slurm时使用的库
$ apt install libmysql++-dev

后续启动 slurmdbd 服务时报错 slurmdbd: error: Database settings not recommended values: innodb_buffer_pool_size innodb_lock_wait_timeout

修改配置文件并添加以下内容,如果设置了1024M,查看 slurmdbd 服务还是报相关错误,则将值提高到 2048M

$ vim /etc/mysql/my.cnf
[mysqld]
innodb_buffer_pool_size=1024M
innodb_log_file_size=64M
innodb_lock_wait_timeout=900
$ systemctl restart mysql

创建数据库用户

# 进入mysql命令界面输入以下内容
$ mysql

# 创建slurm单独的mysql用户,只本地访问即可,所以密码12345678就可以
mysql> create user 'slurm'@'localhost' identified by '12345678';

# 创建基础数据库
mysql> create database slurm_acct_db;

# 允许slurm用户访问此数据库所有的表
mysql> grant all on slurm_acct_db.* TO 'slurm'@'localhost';

# 创建另一个,这个不强制,但是建议,如果不创建,后面slurm配置需要改,所以还是创建吧
mysql> create database slurm_job_db;

mysql> grant all on slurm_job_db.* TO 'slurm'@'localhost';

在mysql命令行界面查看数据库和用户是否成功

# 查看数据库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| slurm_acct_db      |
| slurm_job_db       |
| sys                |
+--------------------+
6 rows in set (0.00 sec)
# 查看用户
mysql> use mysql;
mysql> select user,host from user;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| debian-sys-maint | localhost |
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |
| slurm            | localhost |
+------------------+-----------+
6 rows in set (0.00 sec)
# 退出mysql命令行
mysql> exit;

OpenMPI

如果想在Slurm集群中使用OpenMPI需要提前构建,在指南中指出想使用 srun 命令直接启动MPI需要指定PMIx库

在没有安装PMIx库的情况下安装了Slurm,使用srun命令查看mpi插件时将无法得到PMIx的信息,srun命令需要在启动 slurmd服务以后运行才会有输出,否则会报错。

$ srun --mpi=list
MPI plugin types are...
	none
	cray_shasta
	pmi2

需要注意的是: 编译OpenMPI时如果使用了外部PMIx,则需要和PMIx使用相同的libeventhwloc库,正好Slrum的cgroup插件也需要hwloc库,

所以编译OpenMPI一共要安装的库以下四个:

  • hwloc
  • libevent
  • PMIx
  • UCX

UCX库好像是利用高速网络进行通信的,支持RDMA的网卡好像是可以使用相应的API什么的。不安装UCX后续也不会报错,所以安不安都可以。

安装目录都是默认的 [/usr/local],没有自定义,后面编译Slurm时也好配置,不需要特别指定安装目录

源码编译hwloc

$ wget https://download.open-mpi.org/release/hwloc/v2.11/hwloc-2.11.2.tar.bz2
$ tar -xaf hwloc-2.11.2.tar.bz2
$ cd hwloc-2.11.2
$ ./configure
$ make -j
$ make install
# 这条命令解决了 /usr/local/lib下明明有libhwloc.so.15这个动态库 但是报错 not found
$ ldconfig -n /usr/local/lib/ && ldconfig -v

安装libevent

$ wget https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz
$ tar -xaf libevent-2.1.12-stable.tar.gz
$ cd libevent-2.1.12-stable
$ ./configure
$ make -j
$ make install
# 可以查看是否安装成功libevent库
$ ldconfig -v

安装PMIx库

$ wget https://github.com/openpmix/openpmix/releases/download/v5.0.3/pmix-5.0.3.tar.bz2
$ tar -xaf pmix-5.0.3.tar.bz2
$ cd pmix-5.0.3
$ ./configure
$ make -j
$ make install
$ ldconfig -v

安装UCX库

这个库有的节点安装后可以使用,有的节点不能使用,调用命令 srun 时会报错以下类似的错误,所以我选择不安装这个库了。

node1 select omp obl , node2 select omp ucx

$ wget https://github.com/openucx/ucx/releases/download/v1.17.0/ucx-1.17.0.tar.gz
$ tar -xaf ucx-1.17.0.tar.gz
$ cd ucx-1.17.0
$ ./configure
$ make -j
$ make install
$ ldconfig -v

安装OpenMPI

下载编译安装

$ wget https://download.open-mpi.org/release/open-mpi/v5.0/openmpi-5.0.5.tar.bz2
$ tar -xaf openmpi-5.0.5.tar.bz2
$ cd openmpi-5.0.5
$ ./configure --with-hwloc --with-libevent --with-pmix
$ make -j
$ make install
$ ldconfig -v

在执行 ./configure 后,确保输出的以下内容中的值是 external就可以了,最起码保证咱们之前安装的库用上了

hwloc: external
libevent: external
pmix: external

如果上面几个库安装时没有特别指定目录安装的话,不用指定 –with-xx 的,会在默认安装目录中 [/usr/local/] 下进行搜索的

Slurm

Slurm中的cgroup 插件依赖于 dbus 和 hwloc 库,hwloc库在上面已经安装过了。

如果想源码编译dbus可以在 dbus 官网 中下载后进行安装

$ apt install libdbus-1-dev

源码编译Slurm

在上面网址中下载Slurm 源码包

安装pam开发库

$ apt install libpam0g-dev

Slurm编译源码

$ wget https://download.schedmd.com/slurm/slurm-24.05.4.tar.bz2
$ tar -xaf slurm-24.05.4.tar.bz2 
$ cd slurm-24.05.4
# 这里要注意,如果安装了pmix库,这里一定要写上 --with-pmix否则构建时是不会编译pmix库的
# --enable-pam 开启pam
$ ./configure --with-pmix --enable-pam
$ make -j
$ make install
# 不知道干嘛的,官方文档让执行的
# --help 解释 -n参数是  Only process directories specified on the command line.  Don't build cache
$ ldconfig -n /usr/local/lib/slurm/
$ ldconfig -v
# 查询pmix是否安装成功  srun 命令需要在启动 slurmd 服务以后运行才会有输出,否则会报错。
$ srun --mpi=list
MPI plugin types are...
	none
	pmix
	cray_shasta
	pmi2
specific pmix plugin versions available: pmix_v5

安装完成后拷贝源码目录 etc/ 中的Slurm相关服务到 /lib/systemd/system/ 目录

这些服务文件中有的默认的启动用户是slurm,可以直接修改服务文件内容为root用户,这样就不用新创建一个slurm用户了,确保所有节点使用的是同一个用户就可以了。

$ ls etc/*.service
-rw-r--r-- 1 root root 754 Oct 25 17:08 etc/sackd.service
-rw-r--r-- 1 root root 731 Oct 25 17:08 etc/slurmctld.service
-rw-r--r-- 1 root root 774 Oct 25 17:08 etc/slurmdbd.service
-rw-r--r-- 1 root root 760 Oct 25 17:08 etc/slurmd.service
-rw-r--r-- 1 root root 849 Oct 25 17:08 etc/slurmrestd.service
$ cp etc/*.service /lib/systemd/system/

slurmctld.service服务

此服务文件在主节点中存在即可

修改该服务文件内容,将User和Group改为root用户

$ vim /lib/systemd/system/slurmctld.service
[Unit]
Description=Slurm controller daemon
After=network-online.target remote-fs.target munge.service sssd.service
Wants=network-online.target
ConditionPathExists=/usr/local/etc/slurm.conf

[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/slurmctld
EnvironmentFile=-/etc/default/slurmctld
# 修改启动用户和组为root
User=root
Group=root
RuntimeDirectory=slurmctld
RuntimeDirectoryMode=0755
ExecStart=/usr/local/sbin/slurmctld --systemd $SLURMCTLD_OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
LimitNOFILE=65536
TasksMax=infinity

# Uncomment the following lines to disable logging through journald.
# NOTE: It may be preferable to set these through an override file instead.
#StandardOutput=null
#StandardError=null

[Install]
WantedBy=multi-user.target

slurm.conf 配置文件

24.05版本的Slurm是支持无配置模式的,所以,slurm.conf配置文件只需要在主节点中创建即可

slurm安装默认是没有配置文件的,所有的配置文件都需要自己创建。

生成slurm.conf配置文件内容有两种方式,选择其中一种

  • 1、可通过 Configurator tool 生成slurm.conf,在线生成的方式只适用于最新版本,如果安装的是其它版本应该使用源码中的doc/html/configurator.html构建
  • 2、在源码文件中的etc/下有个slurm.conf.example示例配置文件拷贝到slurmctld.service服务文件中指定的目录中。

比如在slurmctld.service中指定了slurm.conf文件的位置是 /usr/local/etc/slurm.conf 那么就可以在相应的目录中创建slurm.conf文件。

此配置文件为slurm24.05版本,如果版本不一致,需要自行找到源码中的doc/html/configurator.html 进行构建

其中注释部分网络上摘抄,具体含义还是需要试验进行验证,如果进行了make install操作,可以在系统内执行 man slurm.conf 命令查看所有配置的具体解释

$ vim /usr/local/etc/slurm.conf
# slurm.conf file generated by configurator.html.
# Put this file on all nodes of your cluster.
# See the slurm.conf man page for more information.
#

##################################################
# 			集群信息基础配置						 #
##################################################

ClusterName=lmCluster 		# 集群的名称。当使用单个数据库记录来自多个 Slurm 管理的集群的信息时,为每个集群使用不同的名称非常重要。
SlurmctldHost=node1 		# 启动slurmctld进程的节点名  也就是主节点/管理节点
#SlurmctldHost= 			# 冗余备份节点,可空着,以前版本中有的是  BackupController=
SlurmctldPort=6817 			# slurmctld服务端口,如不设置,默认为6817号端口
SlurmdPort=6818 			# slurmd服务端口 如不设置 默认 6818
SlurmUser=root 				# slurmd服务启动时的用户名
SlurmdUser=root 			# slurmctld服务启动时的用户名


##################################################
# 			LOG & OTHER PATH 日志配置		 	 #
##################################################

SlurmctldDebug=info 						# Slurmctld守护进程可以配置为采用不同级别的详细度记录,从0(不记录)到7(极度详细) 默认为info
SlurmctldLogFile=/var/log/slurmctld.log 	# 主节点记录文件位置 如是空白,则记录到syslog
SlurmdDebug=info 							# slurmd 守护进程可以配置为采用不同级别的详细度记录,从0(不记录)到7(极度详细) 默认为info
SlurmdLogFile=/var/log/slurmd.log 			# 子节点记录文件位置 如是空白,则记录到syslog
SlurmctldPidFile=/var/run/slurmctld.pid 	# 存储slurmctld(主节点)进程号PID的文件
SlurmdPidFile=/var/run/slurmd.pid 			# 存储slurmd(子节点)进程号PID的文件
SlurmdSpoolDir=/var/spool/slurmd 			# Slurmd 状态保存目录
StateSaveLocation=/var/spool/slurmctld 		# 存储slurmctld服务状态的目录,如有备份控制节点,则需要所有SlurmctldHost节点都能读写该目录


##################################################
# 			ACCOUNTING  作业记账配置 			 	 #
##################################################

AccountingStorageType=accounting_storage/slurmdbd 	# 将作业记帐写入 Slurm DBD(数据库守护进程),它可以安全地将来自许多 Slurm 管理集群的数据保存到一个公共数据库中
AccountingStorageHost=node1 						# 数据库主机
AccountingStoragePass=/usr/local/var/run/munge/munge.socket.2 # 使用munge认证
#AccountingStorageEnforce=0
#AccountingStoragePort= 							# 数据库服务slurmdbd的端口号,默认6819
#AccountingStorageUser=
#AccountingStoreFlags=

##################################################
# 			LOGGING  数据库配置 			 		 #
##################################################

JobCompType=jobcomp/mysql 		# 使用的数据库服务,除了mysql还支持MariaDB 
JobCompHost=localhost 			# 运行的数据库节点,因数据库服务和slurmctld运行在同一个节点上,所以写localhost就可以
JobCompUser=slurm 				# 数据库用户名
JobCompPass=12345678			# 数据库用户密码
JobCompPort=3306 				# 数据库的端口号
JobCompLoc=slurm_job_db 		# 要使用的数据库名称
#JobCompParams=
#JobAcctGatherType= 			# Slurm记录每个作业消耗的资源,JobAcctGatherType值可为以下之一: jobacct_gather/none jobacct_gather/cgroup jobacct_gather/linux
JobAcctGatherFrequency=30 		# 设定轮寻间隔,以秒为单位。若为-,则禁止周期性抽样


##################################################
# 			SCHEDULING & ALLOCATION              #
##################################################

SchedulerType=sched/backfill 	# 要使用的调度程序的类型。注意,slurmctld守护程序必须重新启动才能使调度程序类型的更改生效(重新配置正在运行的守护程序对此参数无效)。
SelectType=select/cons_tres 	# 资源选择,定义作业资源(节点)选择算法 单个的CPU核、内存、GPU及其它可追踪资源作为可消费资源(消费及分配),建议设置
#SelectTypeParameters=CR_Core

##################################################
# 			TIMERS 时间配置                		 #
##################################################

InactiveLimit=0 			# Slurm 控制器等待 srun 命令响应多少秒,然后才会认为作业或作业步骤处于非活动状态并终止它。零值表示无限等待
KillWait=30 				# 作业在达到时间限制后,在发送 SIGTERM 之前,有多少秒可以正常终止,然后再发送 SIGKILLL
MinJobAge=300 				# 作业终止后,Slurm 控制器等待多少秒才能清除其记录。作业记录将无限期地保留在作业完成和/或会计记录中,但在清除后将不再通过 squeue 命令可见
Waittime=0 					# 作业步骤的第一个任务终止后,等待多少秒才会终止所有剩余任务。零值表示无限等待
SlurmctldTimeout=120 		# 备份节点在成为主节点之前等待多少秒
SlurmdTimeout=300 			# Slurm控制器等待slurmd未响应请求多少秒后将该节点状态设置为DOWN

##################################################
# 			OTHER 其它配置                		 #
##################################################

MpiDefault=pmix 						# 默认使用的MPI插件
ProctrackType=proctrack/cgroup 			# 使用Linux cgroup创建作业容器并跟踪进程。需要一个cgroup.conf文件
ReturnToService=1 						# 设定当DOWN(失去响应)状态节点如何恢复服务 设定为1 当节点的资源大于等于配置计算节点的配置时变为有效
TaskPlugin=task/affinity,task/cgroup 	# 设定任务启动插件。可被用于提供节点内的资源管理(如绑定任务到特定处理器)
#SwitchType=switch/none
SlurmctldParameters=enable_configless 	# 采用无配置模式

##################################################
# 			COMPUTE NODES 节点配置                #
##################################################

# NodeName=node[2-4] 				计算节点名,node[2-4]表示为从node2、连续编号到node4
# NodeAddr=192.168.1.[102-104] 		计算节点IP
# CPUs=1 							节点内CPU核数
# RealMemory=3800  					节点内作业可用内存数(MB),一般不大于free -m的输出,当启用select/cons_res插件限制内存时使用
# Sockets=1 						节点内CPU颗数
# CoresPerSocket=2 					单个CPU插槽中的核心数。 CoresPerSocket 值描述的是物理核心数,而不是每个插槽的逻辑处理器数。
# ThreadsPerCore=1 					每核逻辑线程数,如开了超线程,则为2
# State=UNKNOWN 					状态
# 此配置可通过slurmd -C 输出进行配置
NodeName=node1 NodeAddr=192.168.1.101 CPUs=1 RealMemory=3800 Sockets=1 CoresPerSocket=1 ThreadsPerCore=1 State=UNKNOWN
NodeName=node[2-4] NodeAddr=192.168.1.[102-104] CPUs=1 RealMemory=3800 Sockets=1 CoresPerSocket=1 ThreadsPerCore=1 State=UNKNOWN

##################################################
# 			 PartitionName 分区配置        		 #
##################################################

# PartitionName=compute 			队列分区名
# Nodes=node[2-4] 					节点名或者全部(ALL)
# Default=Yes 						作为默认队列,运行作业不知明队列名时采用的队列
# MaxTime=INFINITE 					作业最大运行时间,以分钟为单位,INFINITE表示为无限制
# State=UP 							状态,是否启用
PartitionName=computer Nodes=node[2-4] Default=YES MaxTime=INFINITE State=UP
PartitionName=login Nodes=node1 Default=NO MaxTime=INFINITE State=UP

NodeName那一行的配置中,因为我配置的虚拟机分配的核心数比较少,根据slurmd -C 输出只能分配一个CPU核心给Slurm调度。

配置cgroup.conf, 与slurm.conf同一个目录, cgroup.conf官方解释

###
# Slurm cgroup 支持配置文件。
###
#如果配置为“yes”,则将允许的核心限制为已分配资源的子集。此功能使用 cpuset 子系统。由于 HWLOC 1.11.5 版中修复了一个错误,除了 task/cgroup 之外,可能还需要 task/affinity 插件才能正常运行。默认值为“no”。
ConstrainCores=yes
# 如果配置为“yes”,则根据 GRES 分配的资源限制作业允许的设备。它为此使用设备子系统。默认值为“no”。
ConstrainDevices=yes
# 如果配置为“yes”,则通过将内存软限制设置为分配的内存并将硬限制设置为分配的内存 
ConstrainRAMSpace=yes
# 如果配置为“yes”,则限制作业的交换空间使用量。默认值为“no”
ConstrainSwapSpace=yes

slurmd.service服务

此服务文件在计算节点和登录节点中存在即可,我的登陆节点就是主节点所以四个节点都需要此文件。

因为选择了无配置启动,不需要在本地创建slurm.conf文件,使用主节点的配置即可

slurmd 服务文件中需要添加远程配置服务的参数 –conf-server node1:6817,这样计算节点启动时会去主节点同步 slurm.conf 配置文件

$ vim /lib/systemd/system/slurmd.service
[Unit]
Description=Slurm node daemon
After=munge.service network-online.target remote-fs.target sssd.service
Wants=network-online.target
#ConditionPathExists=/usr/local/etc/slurm.conf

[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/slurmd
EnvironmentFile=-/etc/default/slurmd
RuntimeDirectory=slurm
RuntimeDirectoryMode=0755
ExecStart=/usr/local/sbin/slurmd --conf-server node1:6817 --systemd $SLURMD_OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
LimitNOFILE=131072
LimitMEMLOCK=infinity
LimitSTACK=infinity
Delegate=yes
TasksMax=infinity

# Uncomment the following lines to disable logging through journald.
# NOTE: It may be preferable to set these through an override file instead.
#StandardOutput=null
#StandardError=null

[Install]
WantedBy=multi-user.target

slurmdbd.service服务

此服务文件在node1中存在,其它计算节点不需要这个服务

修改 [/lib/systemd/system/slurmdbd.service] 中的 UserGrouproot

[Unit]
Description=Slurm DBD accounting daemon
After=network-online.target remote-fs.target munge.service mysql.service mysqld.service mariadb.service sssd.service
Wants=network-online.target
ConditionPathExists=/usr/local/etc/slurmdbd.conf

[Service]
Type=simple
EnvironmentFile=-/etc/sysconfig/slurmdbd
EnvironmentFile=-/etc/default/slurmdbd
User=root
Group=root
RuntimeDirectory=slurmdbd
RuntimeDirectoryMode=0755
ExecStart=/usr/local/sbin/slurmdbd -D -s $SLURMDBD_OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
LimitNOFILE=65536
TasksMax=infinity

# Uncomment the following lines to disable logging through journald.
# NOTE: It may be preferable to set these through an override file instead.
#StandardOutput=null
#StandardError=null

[Install]
WantedBy=multi-user.target

slurmdbd.conf配置文件

根据 [/lib/systemd/system/slurmdbd.service] 中指定的配置文件位置添加slurmdbd.conf

$ vim /usr/local/etc/slurmdbd.conf

#
# Example slurmdbd.conf file.
#
# See the slurmdbd.conf man page for more information.
#
# Archive info
#ArchiveJobs=yes
#ArchiveDir="/tmp"
#ArchiveSteps=yes
#ArchiveScript=
#JobPurge=12
#StepPurge=1
#
# Authentication info
AuthType=auth/munge 		# 认证的插件
AuthInfo=/usr/local/var/run/munge/munge.socket.2
#
# slurmDBD info
DbdAddr=localhost
DbdHost=localhost
#DbdPort=7031 				# 启动的端口号,默认6819 必须和slurm.conf中的AccountingStoragePort端口号一致
SlurmUser=root 				# slurmdbd.service中指定的用户
#MessageTimeout=300
DebugLevel=verbose
#DefaultQOS=normal,standby
LogFile=/var/log/slurmdbd.log
PidFile=/var/run/slurmdbd.pid
#PluginDir=/usr/lib/slurm
#PrivateData=accounts,users,usage,jobs
#TrackWCKey=yes
#
# Database info
StorageType=accounting_storage/mysql
StorageHost=localhost
StoragePort=3306 			# 数据库的端口号
StorageUser=slurm 			# 数据库中的用户
StoragePass=12345678 		# 用户名密码
StorageLoc=slurm_acct_db 	# 要使用的数据库名称

安装pam_slurm_adopt

$ cd slurm-24.05.4/contribs/pam_slurm_adopt
$ make && make install

后续还有很多配置,可以根据上方的链接进行配置。

启动

在这里插入图片描述
根据官网图片中所示

管理节点需要启动 slurmctldslurmdbdmunge 服务

计算节点需要启动 slurmdmunge服务

主节点启动

# 启动
$ systemctl start munge
$ systemctl start slurmdbd
$ systemctl start slurmctld

# 设置为开机自启动
$ systemctl enable munge
$ systemctl enable slurmctld
$ systemctl enable slurmdbd

如果以普通用户启动slurmctld服务时会提示你用什么用户进行验证,用root用户则不会提示。

==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to start 'slurmctld.service'.
Multiple identities can be used for authentication:
 1.  node1
 2.  munge
Choose identity to authenticate as (1-2): 2
Password: 
==== AUTHENTICATION COMPLETE ===

计算节点启动

因主节点中的 slurm.conf 配置文件中设置了无配置模式 SlurmctldParameters=enable_configless

所以计算节点不需要写配置文件了,启动计算节点服务后会同步到本机器内

$ systemctl start munge
$ systemctl start slurmd
# 设置为开机自启动
$ systemctl enable munge
$ systemctl enable slurmd

测试提交MPI作业

在共享目录中编写一个简单的MPI程序

#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define MAX_HOSTNAME_LENGTH 256

int main(int argc, char *argv[])
{
    int pid;
    char hostname[MAX_HOSTNAME_LENGTH];

    int numprocs;
    int rank;

    int rc;

    /* Initialize MPI. Pass reference to the command line to
     * allow MPI to take any arguments it needs
     */
    rc = MPI_Init(&argc, &argv);

    /* It's always good to check the return values on MPI calls */
    if (rc != MPI_SUCCESS)
    {
        fprintf(stderr, "MPI_Init failed\n");
        return 1;
    }

    /* Get the number of processes and the rank of this process */
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    /* let's see who we are to the "outside world" - what host and what PID */
    gethostname(hostname, MAX_HOSTNAME_LENGTH);
    pid = getpid();

    /* say who we are */
    printf("Rank %d of %d has pid %5d on %s\n", rank, numprocs, pid, hostname);
    fflush(stdout);

    /* allow MPI to clean up after itself */
    MPI_Finalize();
    return 0;
}

编译运行测试

$ mpicc mpihello.c -o mpihello
# mpirun 命令建议使用非root用户执行
$ su node2
$ mpirun ./mpihello
Rank 1 of 4 has pid 1015056 on node2
Rank 2 of 4 has pid 1015057 on node2
Rank 0 of 4 has pid 1015055 on node2
Rank 3 of 4 has pid 1015058 on node2

默认使用当前节点并且创建了4个进程

使用srun命令

-N:使用的节点数量,最大值3,因为只有三个计算节点

$ srun -N 3 ./mpihello
Rank 0 of 3 has pid 1015428 on node2
Rank 2 of 3 has pid 735838 on node4
Rank 1 of 3 has pid 727146 on node3

-n:要创建几个任务,一个任务就是一个进程,占据一个CPU核心

$ srun -n 3 ./mpihello
Rank 0 of 3 has pid 1015455 on node2
Rank 2 of 3 has pid 735855 on node4
Rank 1 of 3 has pid 727163 on node3

如果指定-N 1 不指定-n的数量时,会以当前计算节点的所有CPU核心数分配任务数量,也就是三个,但是要使用的节点数量为一个,一个计算节点内的CPU核心数是一个,此时会报错

$ srun -N 1 ./mpihello
srun: error: Unable to allocate resources: Requested node configuration is not available

也就是说任务数量不能超过: 要使用的节点的数量 X 分配好的CPU数量, 以下命令指定-n后成功运行

$ srun -N 1 -n 1 ./mpihello
Rank 0 of 1 has pid 1015487 on node2

-w: 指定计算节点运行

$ srun -N 1 -n 1 -w node4 ./mpihello
Rank 0 of 1 has pid 735883 on node4

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值