Set Up Slurm¶
Deploy and configure Slurm 25.05 on cluster nodes using Omnia. This guide covers input configuration, deployment, and Slurm configuration customization.
Caution
Omnia is validated for Slurm version 25.05. Other versions may have compatibility issues.
Overview¶
Omnia deploys Slurm on designated nodes via cloud-init during provisioning. The setup includes Slurm controller, compute, login, and login/compiler nodes with DOCA-OFED support configured automatically.
Functional Groups¶
| Functional Group | Architecture | Role |
|---|---|---|
slurm_control_node_x86_64 |
x86_64 only | Slurm controller (runs slurmctld and slurmdbd) |
slurm_node_x86_64 |
x86_64 | Compute nodes (runs slurmd) |
slurm_node_aarch64 |
aarch64 | Compute nodes (runs slurmd) |
login_node_x86_64 |
x86_64 | Login nodes for user access |
login_node_aarch64 |
aarch64 | Login nodes for user access |
login_compiler_node_x86_64 |
x86_64 | Login/compile nodes with compilation tools |
login_compiler_node_aarch64 |
aarch64 | Login/compile nodes with compilation tools |
Note
The Slurm controller (slurm_control_node_x86_64) is supported on
x86_64 architecture only.
Prerequisites¶
- The OIM is prepared and the
omnia_corecontainer is accessible (see Prepare OIM). - A user-built Slurm 25.05 RPM repository is available (see Build Slurm Repo).
- For Slurm-only deployments (no service K8s), set
idrac_telemetry_supporttofalseintelemetry_config.yml.
InfiniBand Requirements¶
If any Slurm nodes have an InfiniBand interface and ib_network is
defined in network_spec.yml:
- The Slurm user repository must not include
ucx,ucx-devel,openmpi, oropenmpi-develpackages. - Slurm itself must be compiled without UCX and OpenMPI support.
- DOCA-OFED provides its own UCX and OpenMPI stack that is configured automatically during provisioning.
Tip
For InfiniBand network configuration details, see Configure InfiniBand.
Procedure¶
Step 1: Create the PXE Mapping File¶
Omnia supports two methods for creating the PXE mapping file:
- Manual -- Collect PXE NIC information and fill in the
pxe_mapping_file.csvmanually. - OME-based discovery (recommended) -- Use OpenManage Enterprise (OME)
to discover cluster nodes and auto-generate the mapping file using
discovery.yml.
Option A: Fill the PXE mapping file manually
Create a pxe_mapping_file.csv in
/opt/omnia/input/project_default/ and set the pxe_mapping_file_path
variable in provision_config.yml to point to it.
FUNCTIONAL_GROUP_NAME,GROUP_NAME,SERVICE_TAG,PARENT_SERVICE_TAG,HOSTNAME,ADMIN_MAC,ADMIN_IP,BMC_MAC,BMC_IP,IB_NIC_NAME,IB_IP
slurm_control_node_x86_64,grp0,SVCTAG01,,head01,a1:b2:c3:d4:e5:f6,172.16.107.52,a2:b3:c4:d5:e6:f7,172.17.107.52,,
slurm_node_x86_64,grp1,SVCTAG02,,compute01,b1:c2:d3:e4:f5:a6,172.16.107.43,b2:c3:d4:e5:f6:a7,172.17.107.43,,
login_node_x86_64,grp2,SVCTAG03,,login01,c1:d2:e3:f4:a5:b6,172.16.107.44,c2:d3:e4:f5:a6:b7,172.17.107.44,,
login_compiler_node_x86_64,grp3,SVCTAG04,,login-compiler01,d1:e2:f3:a4:b5:c6,172.16.107.45,d2:e3:f4:a5:b6:c7,172.17.107.45,,
Warning
Replace all placeholder values (SVCTAG*, MAC addresses, IPs) with
your actual hardware data.
Note
- All header fields are case-sensitive.
- Leave the
PARENT_SERVICE_TAGcolumn empty for Slurm-only deployments (without K8s). IB_NIC_NAMEandIB_IPare optional. Leave them empty if InfiniBand is not used.- The
ADMIN_MACandBMC_MACaddresses should refer to the PXE NIC and BMC NIC on the target nodes respectively. - Target servers should be configured to boot in PXE mode with the appropriate NIC as the first boot device.
- Hostnames should not contain the domain name of the nodes.
For detailed information on PXE mapping file format and parameters, see PXE Mapping File.
Option B: Create PXE file using OME
Use the discovery.yml playbook to auto-generate the mapping file from
an OME inventory. For detailed instructions including OME prerequisites,
static group setup, and iDRAC hostname conventions, see
Discover Nodes Using OME.
cd /omnia/discovery
ansible-playbook discovery.yml -e "discovery_mechanism=ome"
The playbook generates a bmc_pxe_mapping_file_<timestamp>.csv in
/opt/omnia/input/project_default/. Verify and edit the file as needed.
Step 2: Provide Inputs¶
For Slurm deployment, update the following input files in
/opt/omnia/input/project_default/:
Key files for this deployment:
| Input File | Purpose |
|---|---|
network_spec.yml |
Network CIDRs, interfaces, and IP ranges |
provision_config.yml |
OS provisioning and PXE settings |
software_config.json |
Software stack selections |
omnia_config.yml |
Slurm cluster configuration |
storage_config.yml |
NFS storage mount configuration |
local_repo_config.yml |
Repository mirror settings |
telemetry_config.yml |
Telemetry and monitoring settings |
security_config.yml |
OpenLDAP authentication settings |
Edit omnia_config.yml¶
Edit omnia_config.yml and configure the
slurm_cluster section:
slurm_cluster:
- cluster_name: slurm_cluster
nfs_storage_name: nfs_slurm
# vast_storage_name: vast_storage # Optional: omit if not using VAST storage
| Parameter | Description |
|---|---|
cluster_name |
Name of the Slurm cluster (required) |
nfs_storage_name |
Must match a name in storage_config.yml mounts |
vast_storage_name |
VAST storage name for HPC tools (/hpc_tools). Must match a name in storage_config.yml mounts. Optional; if omitted, defaults to nfs_storage_name |
Note
Only specify vast_storage_name if you have a separate VAST storage
appliance for HPC tools and benchmarks. If you are using a single NFS
share for all Slurm data, omit this parameter.
Edit storage_config.yml¶
Edit storage_config.yml and define the
NFS mount entries referenced by nfs_storage_name and
vast_storage_name in omnia_config.yml.
mounts:
- name: "nfs_slurm"
source: "172.16.107.168:/mnt/share/omnia"
mount_point: "/share_omnia"
fs_type: "nfs"
mnt_opts: "nosuid,rw,sync,hard,intr"
mount_on_oim: true
functional_group_prefix: ["slurm", "login"]
- name: "vast_storage"
source: "172.16.107.77:/share/vast"
mount_point: "/mnt/vast"
mount_params: "vast_rdma"
mount_on_oim: true
functional_group_prefix: ["slurm_node", "login"]
| Parameter | Description |
|---|---|
name |
Unique identifier; must match nfs_storage_name or vast_storage_name in omnia_config.yml |
source |
NFS server IP and export path (e.g., 192.168.1.100:/export/share) |
mount_point |
Absolute path where the share is mounted on nodes |
fs_type |
Filesystem type (nfs, nfs4, etc.). Can be omitted when using mount_params |
mnt_opts |
Mount options string. Can be omitted when using mount_params |
mount_on_oim |
Set to true so the OIM can write Slurm config and HPC tools to the share during provisioning |
mount_params |
Named profile from the mount_params section (e.g., vast_rdma for RDMA-optimized NFS) |
functional_group_prefix |
List of prefixes to target nodes (e.g., ["slurm"] matches all Slurm functional groups) |
Note
The nfs_storage_name value in omnia_config.yml must exactly match
the name field of a mount entry in storage_config.yml. Omnia uses
this mount to store Slurm configuration files, munge keys, and shared
directories.
Important
Set mount_on_oim: true for both NFS and VAST mounts used by Slurm.
The OIM must access these shares during provisioning to populate Slurm
configuration, munge keys, and HPC tools.
Edit software_config.json¶
Edit software_config.json and add
slurm_custom to the softwares list with the required subgroups:
{
"cluster_os_type": "rhel",
"cluster_os_version": "10.0",
"repo_config": "partial",
"softwares": [
{"name": "default_packages", "arch": ["x86_64", "aarch64"]},
{"name": "slurm_custom", "arch": ["x86_64", "aarch64"]}
],
"slurm_custom": [
{"name": "slurm_control_node"},
{"name": "slurm_node"},
{"name": "login_node"},
{"name": "login_compiler_node"}
]
}
The slurm_custom subgroups map to the Slurm RPM packages installed on
each functional group:
| Subgroup | Packages installed |
|---|---|
slurm_control_node |
slurm-slurmctld, slurm-slurmdbd, mariadb-server, python3-PyMySQL |
slurm_node |
slurm-slurmd, slurm-pam_slurm, kernel-devel, kernel-headers |
login_node |
slurm, slurm-slurmd |
login_compiler_node |
slurm, slurm-slurmd |
Edit local_repo_config.yml¶
Edit local_repo_config.yml and add
your Slurm RPM repository URL under user_repo_url_x86_64 (and
user_repo_url_aarch64 for ARM nodes):
user_repo_url_x86_64:
- { url: "http://<your-slurm-repo>/x86_64/", gpgkey: "", name: "slurm_custom" }
Tip
If you need to build custom Slurm RPMs from source or host them on a local server, complete these steps first:
Important
The repository name must be slurm_custom to match the
software_config.json entry.
Edit telemetry_config.yml (optional)¶
Edit telemetry_config.yml to control
DCGM installation on GPU nodes:
telemetry_sources:
dcgm:
metrics_enabled: true
- When
metrics_enabledistrue(default), DCGM is installed on GPU-capable Slurm compute nodes during provisioning. - When
metrics_enabledisfalse, DCGM installation is skipped.
Note
For Slurm-only deployments, disable all telemetry metrics in
telemetry_config.yml except DCGM, which can be enabled if GPU
telemetry is required.
For more information related to DCGM, see DCGM.
Step 3: Configure Slurm¶
Default Configuration¶
Omnia applies a default Slurm configuration optimized for HPC clusters:
- Default partition: A partition named
normalis created with all compute nodes from the PXE mapping file - Scheduler:
sched/backfillwithselect/cons_tresandCR_Core_Memory - GPU support:
GresTypes=gpuwithAutoDetect=nvml - Configless mode: Compute nodes use
--conf-serverto fetch configuration from the controller
Note
The parameters ClusterName, SlurmctldHost, and
AccountingStorageHost are managed by Omnia and cannot be overridden.
Custom Configuration¶
For detailed information on custom Slurm configuration, merge control, node discovery modes, and configuration validation, see Configure Slurm.
Step 4 -- Prepare the OIM¶
Deploys the OIM infrastructure: OpenCHAMI provisioning stack, Pulp local repository, container registry, MinIO S3 storage, OpenLDAP authentication, and step-ca certificate authority.
For details, see Prepare OIM.
cd /omnia/prepare_oim
ansible-playbook prepare_oim.yml
Verification -- OIM Infrastructure
After prepare_oim.yml completes, verify the OIM services on the
OIM host (not inside the container):
-
Check
omnia.targetstatus:Run on: OIM hostsystemctl is-active omnia.targetExpected output:
active -
Verify all service dependencies:
Run on: OIM hostsystemctl list-dependencies omnia.targetExpected output:
Expected outputomnia.target ● ├─minio.service ● ├─omnia_auth.service ● ├─omnia_core.service ● ├─pulp.service ● ├─registry.service ● ├─network-online.target ● │ └─NetworkManager-wait-online.service ● └─openchami.target ● ├─acme-deploy.service ● ├─acme-register.service ● ├─bss-init.service ● ├─bss.service ● ├─cloud-init-server.service ● ├─coresmd-coredhcp.service ● ├─coresmd-coredns.service ● ├─haproxy.service ● ├─hydra-gen-jwks.service ● ├─hydra-migrate.service ● ├─hydra.service ● ├─opaal-idp.service ● ├─opaal.service ● ├─openchami-cert-trust.service ● ├─postgres.service ● ├─smd-init.service ● ├─smd.service ● └─step-ca.service -
Verify all containers are running:
Run on: OIM hostpodman ps --format "table {{.Names}}\t{{.Status}}"Expected output:
Expected outputNAMES STATUS bss Up 1 day cloud-init-server Up 1 day coresmd-coredhcp Up 1 day coresmd-coredns Up 1 day haproxy Up 1 day hydra Up 1 day minio-server Up 1 day omnia_auth Up 1 day omnia_core Up 1 day opaal Up 1 day opaal-idp Up 1 day postgres Up 1 day pulp Up 1 day registry Up 1 day smd Up 1 day step-ca Up 1 day
Note
- The
minio-servercontainer will not be present if you configured PowerScale as the S3 endpoint (s3_configurations.provider: "powerscale") instorage_config.yml. In that case, Omnia uses the external PowerScale S3 service instead of deploying a local MinIO container. - The
omnia_authcontainer will not be present ifopenldapis not included insoftware_config.json.
For detailed OIM verification procedures, see Verify OIM Services.
Step 5 -- Create Local Repositories¶
Downloads all required RPM packages, container images, and tarballs
into Pulp based on software_config.json for air-gapped provisioning.
For details, see Create Local Repos.
cd /omnia/local_repo
ansible-playbook local_repo.yml
Note
Expect 45--90 minutes depending on network speed. Total download size is typically 20--40 GB.
Verification -- Local Repository Status
After local_repo.yml completes, verify that all software components
were downloaded successfully by checking the software.csv status file.
The components listed in this file correspond directly to the software
entries configured in software_config.json.
-
Verify x86_64 package status:
Run on: omnia_core containercat /opt/omnia/log/local_repo/rhel/10.0/x86_64/software.csvExpected output:
Expected outputname,status default_packages,success openldap,success slurm_custom,success -
Verify aarch64 package status (if aarch64 is included in
software_config.json):Run on: omnia_core containercat /opt/omnia/log/local_repo/rhel/10.0/aarch64/software.csvExpected output:
Expected outputname,status default_packages,success openldap,success slurm_custom,success
Note
The software.csv output reflects the software components configured
in software_config.json. Each component with "arch": ["x86_64"]
appears in the x86_64 status file, and each component with
"arch": ["aarch64"] appears in the aarch64 status file. All entries
must show success status before proceeding.
Step 6 -- Build Node Images¶
Builds diskless OS images for each functional group in the PXE mapping file and uploads them to MinIO (S3) for PXE boot delivery.
For details, see Build Cluster Images.
Build x86_64 Images
cd /omnia/build_image_x86_64
ansible-playbook build_image_x86_64.yml
Build aarch64 Images
If your PXE mapping file contains aarch64 functional groups, you must first prepare an aarch64 build node. See Prepare aarch64 Node for the complete procedure (manual RHEL 10 installation, inventory file creation, etc.).
cd /omnia/build_image_aarch64
ansible-playbook build_image_aarch64.yml -i inventory
[admin_aarch64]
10.0.0.1
Verification -- Boot Images in S3
After the build playbooks complete, verify the images are uploaded to
MinIO (S3). Each functional group produces 3 image artifacts:
rootfs (full OS root filesystem), vmlinuz (Linux kernel), and
initramfs (initial RAM filesystem for PXE boot).
-
List all boot images in S3:
Run on: OIM hosts3cmd ls s3://boot-images/Expected output (one directory per functional group plus
efi-images):Expected outputDIR s3://boot-images/efi-images/ DIR s3://boot-images/login_compiler_node_x86_64/ DIR s3://boot-images/slurm_control_node_x86_64/ DIR s3://boot-images/slurm_node_x86_64/ -
Verify individual image artifacts for a specific functional group:
Run on: OIM hosts3cmd ls -Hr s3://boot-images/slurm_control_node_x86_64/ s3cmd ls -Hr s3://boot-images/efi-images/slurm_control_node_x86_64/Expected output:
Expected output2026-06-26 11:42 1449M s3://boot-images/slurm_control_node_x86_64/rhel-slurm_control_node_x86_64_omnia_2.2.0.0/rhel10.0-rhel-slurm_control_node_x86_64_omnia_2.2.0.0-10.0 2026-06-26 11:42 78M s3://boot-images/efi-images/slurm_control_node_x86_64/rhel-slurm_control_node_x86_64_omnia_2.2.0.0/initramfs-6.12.0-55.82.1.el10_0.x86_64.img 2026-06-26 11:42 15M s3://boot-images/efi-images/slurm_control_node_x86_64/rhel-slurm_control_node_x86_64_omnia_2.2.0.0/vmlinuz-6.12.0-55.82.1.el10_0.x86_64
Note
The directories listed in s3://boot-images/ correspond to the
functional groups defined in your PXE mapping file. Each functional
group will have exactly 3 image artifacts (rootfs, vmlinuz,
initramfs). The efi-images/ directory contains the initramfs
and vmlinuz boot files used during PXE network boot, while the root
filesystem is stored directly under each functional group directory.
If any artifacts are missing, re-run the corresponding build playbook.
Step 7 -- Provision Nodes¶
The provision.yml playbook provisions the cluster nodes. It configures
boot scripts, cloud-init, and prepares nodes for Slurm deployment.
cd /omnia/provision
ansible-playbook provision.yml
Verification -- nodes.yaml
After provision.yml completes, verify that all nodes from your PXE
mapping file are present in the generated nodes.yaml file. Every
node defined in pxe_mapping_file.csv should have a corresponding
entry with its hostname, functional group, MAC address, and IP address.
cat /opt/omnia/openchami/workdir/nodes/nodes.yaml
Expected output (one entry per node in the PXE mapping file):
nodes:
- name: head01
xname: x1000c0s0b0n0
description: SVCTAG01
nid: 1
group: slurm_control_node_x86_64
bmc_mac: a2:b3:c4:d5:e6:f7
bmc_ip: 10.3.0.XXX
interfaces:
- mac_addr: a1:b2:c3:d4:e5:f6
ip_addrs:
- name: management
ip_addr: 10.5.0.XXX
- name: compute01
xname: x1000c0s0b1n0
description: SVCTAG02
nid: 2
group: slurm_node_x86_64
bmc_mac: b2:c3:d4:e5:f6:a7
bmc_ip: 10.3.0.XXX
interfaces:
- mac_addr: b1:c2:d3:e4:f5:a6
ip_addrs:
- name: management
ip_addr: 10.5.0.XXX
...
Note
Post execution of provision.yml, IPs and hostnames cannot be
re-assigned by changing the mapping file.
Caution
- Do not run
ssh-keygenpost execution ofprovision.ymlto avoid breaking the password-less SSH channel on the OIM. - Do not delete the Omnia shared path or the NFS directory.
For troubleshooting boot issues, IP route conflicts, and cloud-init failures, see Provisioning Issues.
Step 8 -- PXE Boot Nodes¶
After provision.yml completes, PXE boot all Slurm-related nodes.
Option 1: Manual PXE Boot
Configure each node to boot from the network via iDRAC or BIOS settings.
Option 2: Automated PXE Boot
Sets PXE boot order on all nodes via iDRAC Redfish and reboots them. Nodes boot from the network, load their OS image from S3, and execute cloud-init to complete provisioning.
cd /omnia/utils
ansible-playbook set_pxe_boot.yml
Warning
This playbook will restart your servers and power them on if they are off. Any unsaved data will be lost.
Verification -- Cloud-Init Provisioning Status
After the nodes PXE boot, verify that cloud-init has completed on all
nodes. SSH from omnia_core into each node using its hostname from the
PXE mapping file (HOSTNAME column):
ssh head01 'cloud-init status'
ssh compute01 'cloud-init status'
Expected output on each node:
status: done
Note
Check every node in your cluster. Open your PXE mapping file
and run
ssh <HOSTNAME> 'cloud-init status' for each entry. All nodes must
report status: done before proceeding.
Verification¶
-
Check Slurm controller status:
Run on: Slurm controller nodesystemctl status slurmctldExpected output:
Expected output● slurmctld.service - Slurm controller daemon Loaded: loaded (/usr/lib/systemd/system/slurmctld.service; enabled; preset: disabled) Active: active (running) since ... -
Check Slurm cluster status:
Run on: Slurm controller nodesinfoExpected output:
Expected outputPARTITION AVAIL TIMELIMIT NODES STATE NODELIST normal* up infinite 2 idle compute-node[1-2] -
Run a test job:
Run on: Slurm controller nodesrun -N 1 hostname sbatch --wrap="echo Hello from \$(hostname)" --output=/tmp/hello.out cat /tmp/hello.outExpected output:
Expected output<node_name> Hello from <node_name> -
Verify from login node:
Run on: login/login_compiler nodesrun -N 1 hostnameExpected output:
Expected output<node_name> -
Check Slurm accounting:
Run on: Slurm controller nodesacctmgr show clusterExpected output:
Expected outputCluster ControlHost ControlPort RPC Share GrpJobs GrpNodes GrpSubmit GrpWall GrpTRES MaxJobs MaxNodes MaxSubmit MaxWall MaxTRES QOS Default QOS slurm head01 6817 6817 1 1 1 1 1 1 1 1 1 1 normal
Next Steps¶
- Slurm with GPU -- Configure GPU support for Slurm nodes
- NVIDIA HPC SDK Setup -- Install NVIDIA HPC SDK on compiler and compute nodes
- Add Slurm Nodes -- Add more compute nodes to the cluster
- Config Backup -- Back up Slurm configuration
- Run HPC Benchmarks -- Validate cluster performance
Troubleshooting¶
slurmctld not starting
Check the slurmctld log and verify munge is running:
tail -100 /var/log/slurm/slurmctld.log
systemctl status munge
Validate the configuration and fix spool directory permissions:
slurmd -C
chown -R slurm:slurm /var/spool/slurmctld/
chmod 755 /var/spool/slurmctld/
Nodes Entering DRAINED State Fix the epilog script permissions and reconfigure Slurm:
chmod 0755 /etc/slurm/epilog.d/logout_user.sh
scontrol reconfigure
Nodes stuck in DOWN state
Check the reason and verify slurmd is running on the compute node:
scontrol show node <nodename> | grep -i reason
ssh <nodename> systemctl status slurmd
Resume the node after fixing the underlying issue:
scontrol update NodeName=<nodename> State=RESUME
Job submission failures Check available partitions and resources:
sinfo
sinfo -N -l
squeue
slurmdbd connection issues
Check slurmdbd and MariaDB status:
systemctl status slurmdbd
systemctl status mariadb
Test database connectivity and restart if needed:
mysql -u slurm -p -h localhost slurm_acct_db -e "SELECT 1;"
systemctl restart slurmdbd
systemctl restart slurmctld
Munge authentication failure Verify Munge is running and keys are identical across all nodes:
ansible slurm_cluster -m shell -a "systemctl status munge"
ansible slurm_cluster -m shell -a "md5sum /etc/munge/munge.key"
MariaDB connection error Check MariaDB and restart Slurm services:
systemctl status mariadb
systemctl start mariadb
systemctl restart slurmdbd
systemctl restart slurmctld
sacct erroring out or returning empty results
Check slurmdbd service and port:
systemctl status slurmdbd
ss -tlnp | grep 6819
Restart the services:
systemctl restart slurmdbd
systemctl restart mariadb
For the complete list, see Slurm Issues.