弹性容器集群使用Slurm
概述
高度可扩展的集群资源管理和作业调度
Slurm 是一个容错、高度可扩展的集群资源管理和作业调度系统,致力于实现可移植性和互连无关性。Slurm 是全球超级计算中心、政府实验室、大学和公司中大型 HPC 作业的事实上的调度程序。它为 TOP500 列表中最快的 10 个系统中超过一半的系统执行工作负载管理。
本篇主要介绍如何在弹性容器集群上使用Slurm,如果您还没有开通弹性容器集群,请先开通弹性容器集群。
前置条件
- 已安装Helm,若未安装,请参考Helm使用
- 已下载Slurm Cluster Helm Chart,若未下载,请参考 下载 Slurm Cluster Helm Chart
部署和配置
安装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 在解析可执行文件时遵循以下顺序:
- 如果以 . 开头,则在当前工作目录下查找可执行文件
- 如果以 / 开头,则视为绝对路径
- 在 PATH 环境变量所指定的路径查找。注意 Slurm 在运行命令时,将以当前用户的身份登录,因此 PATH 变量的设置受用户 profile 的控制
- 在当前工作目录中查找
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