跳到主要内容

弹性容器集群使用Slurm

概述

高度可扩展的集群资源管理和作业调度

Slurm 是一个容错、高度可扩展的集群资源管理和作业调度系统,致力于实现可移植性和互连无关性。Slurm 是全球超级计算中心、政府实验室、大学和公司中大型 HPC 作业的事实上的调度程序。它为 TOP500 列表中最快的 10 个系统中超过一半的系统执行工作负载管理。

本篇主要介绍如何在弹性容器集群上使用Slurm,如果您还没有开通弹性容器集群,请先开通弹性容器集群。

前置条件

部署和配置

安装Slurm

解压

解压下载的Slurm Cluster Helm Chart

tar -zxvf slurm-cluster-0.1.0.tar.gz

安装

弹性容器集群中的 Slurm 集群采用 helm 进行管理。使用如下命令可以创建一个 Slurm 集群:

cd slurm-cluster

helm install --set slurm.worker.replicas.current=3 --set storage.workspace.enabled=true slurm .

其中的slurm 是本次安装的名称。

正常情形应输出:

NAME: slurm
LAST DEPLOYED: Tue Nov 26 15:49:02 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Slurm cluster run in Kubernetes.

表示 Slurm 集群已经启动成功了。等所有节点正常运行后,用 kubectl get pod 查询,可以得到类似以下输出:

NAME                                 READY   STATUS      RESTARTS   AGE
slurm-client-8549c7576f-99vg9 1/1 Running 0 3m55s
slurm-controller-5c99fcf564-4v9gs 1/1 Running 0 3m55s
slurm-db-57b6bddb94-8w9lg 1/1 Running 0 3m55s
slurm-dbd-796dfddf5c-68txk 1/1 Running 0 3m55s
slurm-worker-0 1/1 Running 0 3m55s
slurm-worker-1 1/1 Running 0 3m55s
slurm-worker-2 1/1 Running 0 3m55s

这表明启动的 Slurm 集群包含 1 个控制节点、3 个计算节点、1 个客户端节点等。

Slurm 集群的 helm chart 有以下可配置参数:

参数作用说明默认值
image.repository映像仓库的地址/前缀即映像 URL 去掉其名称的前面部分registry.hd-01.alayanew.com:8443/vc-huangxs/slurm
image.pullPolicy拉取映像的策略IfNotPresent
image.dockerConfigJson从私有仓库拉取映像时的凭据将 docker config Base64 编码即可
slurm.cluster.name集群名称查询集群名称会转换为小写字母。建议不多于 10 个字符,否则会在默认输出中被截断slurm
slurm.cluster.maxJobCount最大作业数slurmctld 保存在内存的作业记录的最大个数,包括正在排队,正在运行以及运行完毕尚未清理的作业。当保存在内存的作业记录数达到最大值时,不能提交新作业10000
slurm.cluster.minJobAge最小作业寿命作业完成后,其记录被 slrumctld 保留在内存的最短时间,超过此时间则可能被清理。单位是秒300
slurm.cluster.partition.name分区名称建议不多于 10 个字符,否则会在默认输出中被截断workspace
slurm.worker.replicas.current工作节点的个数可以在不重启集群的情况下增加3
slurm.worker.replicas.max工作节点的最大个数slurmctld 能够接受的工作节点个数的最大值。修改此参数必须重启集群才能生效100
slurm.worker.gpu.label工作节点需要的 GPU 的名称nvidia.com/gpu
slurm.worker.gpu.count工作节点需要的 GPU 的个数1
slurm.worker.memory工作节点需要的内存大小16Gi
slurm.worker.storage工作节点需要的本地存储容量32Gi
slurm.worker.rdma工作节点需要的 RDMA 个数1
slurm.dbd.enabled使能 slurm-dbd 节点启用 slurm-dbd 节点将同时启用 slurm-db 节点true
storage.workspace.enabled使能挂载工作空间 卷true
storage.workspace.storageClassName要挂载的工作空间的 sc名称通过kubectl get sc 查看xxx

登录Slurm集群

用以下命令登录客户端节点:

kubectl exec -it slurm-client-8549c7576f-99vg9 -- su - user

注意这里我们切换到了 user 用户,因为工作空间被挂载到了 user 的家目录下。如无特殊说明,以后各节所述的操作均以 user 用户登录客户端节点进行。

使用Slurm

查看 Slurm 集群状态

登录 slurm-client 控制台,输入以下命令查看 Slurm 集群信息:

sinfo

示例输出如下:

PARTITION  AVAIL  TIMELIMIT  NODES  STATE NODELIST
workspace* up infinite 3 idle slurm-worker-[0-2]

以上输出表明集群包含 3 个节点,有一个默认的分区 workspace.

可以改变 sinfo 命令的输出格式,将节点作为主要元素显示。输入以下命令:

sinfo -N

示例输出如下:

NODELIST        NODES  PARTITION STATE 
slurm-worker-0 1 workspace* idle
slurm-worker-1 1 workspace* idle
slurm-worker-2 1 workspace* idle

还可以自定义 sinfo 命令的输出格式,例如

sinfo -o "%20N %10c %10m %25f %G"

示例输出如下:

NODELIST             CPUS       MEMORY     AVAIL_FEATURES            GRES
slurm-worker-[0-2] 32 98217 (null) gpu:1

注意使用 %G 可以显示 Gres 资源,包括 GPU 等。

使用 sinfo 命令还可以查询状态不正常的节点及原因。假如由于某种原因所有 slurm-worker 节点掉线,使用不带参数的 sinfo 命令将得到输出:

PARTITION  AVAIL  TIMELIMIT  NODES  STATE NODELIST
workspace* up infinite 3 down* slurm-worker-[0-2]

注意 STATE 一列的值变为 down. 输入以下命令:

sinfo -R

示例输出如下:

REASON               USER      TIMESTAMP           NODELIST
Not responding slurm 2024-10-28T08:13:19 slurm-worker-[0-2]

从输出中可以看到故障的原因以及发现故障的时间。

如果需要持续监控状态,可以使用 -i 参数指定查询的间隔,单位为秒:

sinfo -i 5

将以 5 秒为间隔持续输出结果。

使用 srun 提交 Slurm 作业

使用 srun 命令可以向 Slurm 集群提交作业。例如,输入以下命令:

srun -N3 hostname

其中 -N 参数指定运行命令需要的节点数。示例输出如下:

slurm-worker-2
slurm-worker-0
slurm-worker-1

srun 提交运行的命令必须在每个使用的节点上都可执行,不能是 shell 的内置命令或函数。注意:像 echo 这样的命令既是内置命令又是可执行文件,因此可以使用 srun 运行。

srun 在解析可执行文件时遵循以下顺序:

  1. 如果以 . 开头,则在当前工作目录下查找可执行文件
  2. 如果以 / 开头,则视为绝对路径
  3. 在 PATH 环境变量所指定的路径查找。注意 Slurm 在运行命令时,将以当前用户的身份登录,因此 PATH 变量的设置受用户 profile 的控制
  4. 在当前工作目录中查找

srun 提交作业为同步方式。作业提交成功后,srun 命令不结束,直到作业的所有任务结束后才退出。在以上例子中,如果指定的节点数大于任务所在分区中的可用节点数,作业将进入 PENDING 状态,srun 命令输出以下信息后进入等待状态:

srun: Requested partition configuration not available now
srun: job 15 queued and waiting for resources

可以看到作业的 ID 为 15. 此时打开另外一个控制台,输入:

squeue

这个命令可以查询队列中的作业。示例输出如下:

             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
15 workspace hostname user PD 0:00 4 (PartitionNodeLimit)

其中显示作业 15 的状态为 PD, 即 PENDING. 输入以下命令可以取消这个作业:

scancel 15

作业被取消后,原控制台中的 srun 退出,完整的输出如下:

srun: Requested partition configuration not available now
srun: job 15 queued and waiting for resources
srun: Job has been cancelled
srun: error: Unable to allocate resources: Job/step already completing or completed

如果以其他方法(比如输入 Ctrl+C)结束原控制台中的 srun 命令,同样会取消作业的运行,输出信息如下:

srun: Requested partition configuration not available now
srun: job 16 queued and waiting for resources
srun: Job allocation 16 has been revoked

srun 命令的其他常用参数见下表。

参数作用说明
-p {分区名}指定作业运行的分区默认分区不需要指定
-n {数字}指定作业中的并行任务个数任务可能在同一个节点上运行。如果没有其他参数限制,则一个任务占用一个 CPU 资源
-c {数字}指定作业中每个任务需要使用的 CPU 数任务需要在一个节点内运行,因此 CPU 数不够运行一个任务的节点将被排除
-w {节点列表}指定作业使用的节点列表列表可以使用逗号分隔或缩写以及两者混合的形式,例如 slurm-worker-0,slurm-worker-[1-2]
--mem {内存字节数}指定作业需要分配的内存可以超过单个节点的内存。字节数可以用数字加 k, m, G, T 来指定
-G {类型}:{数量}指定总共所需的 GPU 类型和个数类型可以省略

使用 sbatch 命令提交作业

使用 sbatch 命令提交作业前需要有一个 Slurm 脚本,示例如下:

#!/bin/bash

#SBATCH --job-name=Sleep
#SBATCH --output=%x-%j.out

## Resource Request
#SBATCH --ntasks=3
#SBATCH --nodes=3
#SBATCH --cpus-per-task=1
#SBATCH --mem-per-cpu=16k

## Job Steps
srun echo "Start Job ${SLURM_JOB_ID}: ${SLURM_JOB_NAME}..."
srun hostname
srun sleep 10
srun echo "End Job"

注意其中 #SBATCH 开头的行,形式上为注释,实际是向 sbatch 传递参数的一种方式。

将上述内容编辑好,上传到用户的工作空间,或者直接用控制台中的 vi 编辑保存。假设文件名是 test.slurm, 提交这个作业:

sbatch test.slurm

Slurm 对脚本的扩展名并无特别要求,也无需是可执行文件。成功提交后的输出示例如下:

Submitted batch job 62

可以看到提交的作业 ID 是 62. 不同于 srun, sbatch 提交作业是异步方式,提交成功后马上返回。

在作业运行完成之前用 squeue 命令可以看到作业的状态如下:

             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
62 workspace Sleep user R 0:07 3 slurm-worker-[0-2]

作业运行的输出放在了由脚本中 --output 参数指定的文件(%x 替换为作业名称,%j 替换为作业 ID)中。运行结束后查看其内容:

Start Job 62: Sleep...
Start Job 62: Sleep...
Start Job 62: Sleep...
slurm-worker-1
slurm-worker-2
slurm-worker-0
End Job
End Job
End Job

如果不指定输出文件名,则默认的文件名是 slurm-[作业 ID].out.

使用 sbatch 提交作业时需要注意以下几点:

  • 不需要将脚本复制到每一个计算节点,Slurm 自动将脚本复制到某个计算节点上并运行
  • 脚本中的一般 shell 命令(非以 srun 或 mpirun 提交的命令)直接执行,不作为作业的一个步骤,因此不分配资源,也不受并行参数的控制
  • 由于输出要写到文件,所在的目录必须有可写权限,否则任务将失败。

查看作业信息

使用 scontrol show job 命令可以查看作业信息,可以指定作业 ID 以查看某个作业的信息。

查看作业历史

Slurm 作业完成或失败后,其状态在内存中只保存有限的时间就会被清空,此后无法使用 scontrol show job 查看作业信息。配置了簿记服务后,作业信息会定期转存到一个外部数据库,因此可以保留完整历史。输入以下命令查看作业历史信息:

sacct

示例输出如下:

JobID           JobName  Partition    Account  AllocCPUS      State ExitCode 
------------ ---------- ---------- ---------- ---------- ---------- --------
1 hostname workspace 3 COMPLETED 0:0
1.0 hostname 3 COMPLETED 0:0