slurmctld host) and reports workload lifecycle, requested against
used resources, GPU activity and source evidence. Workers run samplers without
compute credentials and send samples through a shared filesystem. Only the
controller connects to the control and data planes.
The console’s Add compute panel shows your short-lived install token,
control-plane and data-plane URLs, and pinned daemon version. Install the
controller on the actual slurmctld host, which may differ from the login node.
For AWS ParallelCluster, use the ParallelCluster guide.
Prefer to delegate? Copy this into an AI assistant with shell access on the controller and workers.
Prerequisites
- Console access with permission to register a compute in the intended organisation.
- Root or sudo on the controller and workers; systemd for managed services.
- SLURM running, with
scontrol,squeueand preferablysacctaccessible. - The
slurmOS account on every node, with consistent UID/GID across the shared mount. Use--userif your daemon account has another name. - A filesystem mounted at the same path on every node, such as
/srv/expanseon NFS or Lustre. Single-node clusters can use local disk. - Working NVIDIA drivers and
nvidia-smion GPU nodes. Baseline metrics need neither a CUDA toolkit nor CUPTI. - Controller HTTPS access to your control and data planes and, for online
installs,
releases.expanse.shor your release mirror.
EXPANSE_SEGMENT_UPLOAD_MODE=relay as described under
restricted networks.
Both planes must be operational before installation. An HTTP response proves
reachability; successful authentication and the first heartbeat prove enrolment.
1. Register the compute
Select the intended organisation in the console, open Compute → Add compute, choose SLURM, and generate an install token. Keep the panel open to check that this exact compute becomes active.2. Install the CLI on the controller
expanse compute install --help against the flag reference
when using an older CLI. CLI and daemon releases are versioned separately.
3. Install the controller daemon
Use the version and endpoints from Add compute. This Bash example keeps the token out of shell history and explicitly passes it through sudo:EXPANSE_INSTALL_TOKEN
takes precedence over that prompt.
The installer verifies the release’s signed manifest, archive checksum and
signature. It preflights paths, permissions, SLURM config and hook changes
before exchanging the token. It installs the daemon, bundled py-spy, hooks and
systemd unit, then waits for an authenticated heartbeat. A fresh install rolls
back its managed changes on failure.
--patch-slurm-conf=true authorises the planned Prolog, Epilog and TaskProlog
changes. Without it, SLURM-owned paths remain read-only; your configuration
management must apply the hook wiring. Foreign hooks may require explicit
chaining. Use --slurm-conf /absolute/path/slurm.conf if discovery fails.
The compute credential stays on the controller at
/var/lib/slurm/.expanse/config.json, or your --config override. The unit pins
that path through EXPANSE_DAEMON_CONFIG. Keep this file off the shared mount
and do not edit its compute ID to change registration.
4. Start worker samplers
By default, the installed Prolog starts or updates a worker’s sampler when a job starts. Autoscaled workers need the shared mount and the daemon OS account; no per-worker token is used. For static workers that need telemetry before their first job, install the CLI on each worker and run:Skip the sampler on the controller, including single-node clusters. Its daemon
already samples local GPUs. Running both roles on that node duplicates sampling.
5. Verify registration and telemetry
Check the services on their respective hosts:test -f /srv/expanse/.expanse-preflight-sentinel && echo shared
checks visibility of the controller’s preflight sentinel. Confirm it is the
same shared mount, not an independently created local directory.
In the console, check the intended organisation and compute ID, a fresh
heartbeat, and the expected nodes and GPUs. Submit a job with sbatch and
check its execution and metrics. An active heartbeat alone does not prove
optional CUPTI, DCGM or Python stack collection is working; inspect the daemon
diagnostics too. Idle GPUs can legitimately show zero utilisation.
Upgrade the existing compute
Reinstall with a new pinned daemon version and the same prefix/configuration:EXPANSE_INSTALL_TOKEN unset, because a set token
is exchanged as a replacement credential. Repeat any non-default install flags, such as
--user, --config, --slurm-conf or --profiling-agent=false.
Workers converge to the new shared binary at their next job start. Re-run the
sampler install on static workers to update immediately. Reinstall cleans the
old managed installation before installing the replacement; if replacement
fails, the identity remains but the old runtime is not automatically restored.
Replace a lost compute credential
If the controller is rebuilt or/var/lib/slurm/.expanse/config.json is lost,
the compute keeps its identity and history. On the compute’s console page
choose Re-issue install token. Then run the step 3 command on the controller
with --reinstall added. Supply the re-issued token the same way:
- Same flags as the original install. Repeat
--user,--config,--slurm-confand the prefix. On AWS ParallelCluster omit--shared-prefix. - Keep
--patch-slurm-conf=true. Reinstall cleanup removes the Expanse hook wiring and only that flag re-applies it. Without it the compute heartbeats but captures no jobs. - The token must match this compute. A token re-issued for a different compute is refused before anything on the node changes.
- A rebuilt controller needs the CLI first (step 2). The plane URLs are required only when no saved config remains.
- The previous credential stops at the exchange. A daemon still using it stops on its own. The token can be exchanged once.
Reset and register a different compute
Uninstall is the explicit identity reset. It stops collection, removes managed files and hooks, and deprovisions the old compute. Run this in a maintenance window after draining affected jobs so their hooks and queued captures are not removed mid-run. Keep the same--user, --config and prefix overrides as the
original installation.
--keep-identity for a registration
reset, and do not delete config or lock files by hand. Review any operator-owned
systemd drop-ins and /etc/expanse/daemon.env before reusing the host; uninstall
is not a reset of your own configuration management.
Return to step 1 in the intended organisation and perform a fresh install
without --reinstall. --force is an alias for --reinstall, so it also
preserves identity.
Optional: GPU performance counters with CUPTI
Baseline GPU metrics usenvidia-smi. CUPTI adds SM activity, tensor activity,
DRAM throughput and other hardware performance counters. SLURM attempts CUPTI
collection by default; its availability depends on the helper, driver and
profiling permissions.
Online controller installation selects a driver-compatible CUPTI variant from
the signed release manifest and installs its helper, capture agent and matched
libraries under <prefix>/lib/cupti-nodes/<hostname>/. Worker bootstrap selects
for each worker’s driver independently. The released matrix includes CUDA 12.8
and 13.0 for amd64; select only a variant compatible with that node’s driver.
Missing CUPTI does not block baseline telemetry or registration.
Allow restricted profiling counters
SLURM installs default to--cupti-mode=perfmon. The controller and sampler
units grant CAP_PERFMON in both their bounding and ambient sets, including
the unit distributed to new workers by the bootstrap. This requires Linux 5.8+
and NVIDIA R565+. Keep RmProfilingAdminOnly=1 on shared compute nodes.
Use explicit --cupti-mode=sysadmin for older hosts, or --cupti-mode=none
to grant neither capability. There is no automatic privilege fallback.
The Ansible role forwards the same choice as expanse_cupti_mode.
After installation, check the service on each GPU worker (use
service=expanse-daemon on a controller that also runs GPU jobs):
--profiling-agent=false when the deployment excludes in-job injection.
To disable CUPTI collection, set EXPANSE_CUPTI_ENABLE=0 in
/etc/expanse/daemon.env on the relevant nodes and restart their Expanse service.
The installer never changes the NVIDIA driver’s profiling policy.
Optional: DCGM enrichment
Expanse uses a DCGM host engine you already operate. It does not install DCGM or startnv-hostengine. Install your supported dcgmi client on GPU nodes
and make the existing engine reachable, by default at localhost:5555.
For a different engine or client location, add these runtime settings:
Optional: Python stacks and deep capture
The daemon release bundles py-spy, which installs to<prefix>/bin/py-spy by
default. You do not need to download it separately. Python stack attribution
needs ptrace access to workload processes; the generated units grant
CAP_SYS_PTRACE, but site security policy can still prevent collection.
--bundled-pyspy=false skips the bundled copy; an operator-managed py-spy can
still be selected through EXPANSE_PYSPY.
--profiling-agent=true installs TaskProlog wiring for the in-process CUPTI
capture agent when its library is available. This is separate from the CUPTI
hardware-counter helper. Set --profiling-agent=false to skip this wiring;
generated controller and sampler units also disable in-process capture and its
permission check. CUPTI counter sampling remains enabled. Containers must see the shared
prefix at the same path for the injected library to load.
Set EXPANSE_PROFILING_ENABLE=0 at runtime to disable adaptive escalation.
It does not disable baseline GPU metrics or the CUPTI Light counter set.
To disable only in-process capture and its permission check, set
EXPANSE_PROFILING_AGENT_ENABLE=0 in /etc/expanse/daemon.env on the controller
and workers, then restart their Expanse services. Older units did not record
--profiling-agent=false: preserve that opt-out when upgrading by reinstalling
with the flag, or applying this runtime setting before restarting.
The restarted service publishes a node-local disable marker that TaskProlog
checks before exporting injection variables. This applies to newly launched
tasks; running jobs retain their loaded library. Existing site TaskProlog output
and operator-managed opt-outs are preserved. Older TaskProlog scripts need a
reinstall with agent wiring enabled to gain this gate, or use their existing
<control-dir>/disabled file on each worker. Jobs never read daemon.env.
If the service cannot publish the disable marker, startup fails with the control
path and error. Repair the path and restart to apply the opt-out. A failed
Expanse service alone does not stop TaskProlog injection.
With agent injection enabled, each running daemon or sampler checks the control
directory and its ancestors, plus the shared-prefix root and spool, every
30 seconds. Missing other-execute (o+x) permission degrades
profiling_permissions health with the exact path. The daemon restores only
that bit in directories it owns inside /var/lib/expanse, the configured
control root or the shared spool tree. The shared-prefix root and customer
ancestors require operator repair. Worker failures reach
the console through the controller’s heartbeat. Worker reports expire after
two minutes, so an unavailable shared spool can prevent that relay.
Optional: restricted networks and air-gapped installs
Use--releases-url https://releases.internal.example to change the release
manifest lookup host. Current manifests contain absolute archive URLs, which
this flag does not rewrite: copying a manifest to an internal host alone does
not keep downloads inside that mirror. For a site without release-host access,
use the staged archive path below. Keep signatures with the archives; a mirror
does not change the pinned verification key.
For a staged install, replace --daemon-version with
--daemon-binary /path/to/expanse-daemon_linux_amd64.tar.gz and keep its .sig
beside it. Stage compatible CUPTI release archives and their .sig files
beside the daemon archive for offline selection. Both planes must still be
reachable at your deployment’s internal URLs.
For workers without outbound access, make signed CUPTI archives available in
<prefix>/lib/cupti-artifacts/ and configure the workers with:
HTTPS_PROXY, NO_PROXY and
SSL_CERT_FILE explicitly through sudo during installation. The installer
seeds /etc/expanse/daemon.env with the network settings for the service.
Preserve existing entries when adding runtime settings, and restart the
relevant service after editing the file. Never store the install token there.
Troubleshooting
Install flag reference
SLURM is configured with CLI flags and node-local systemd settings. It has no Helmvalues.yaml. These are the controller/sampler install flags; use
expanse compute install --help for the CLI version installed on your host.
Runtime configuration reference
Add settings to the existing/etc/expanse/daemon.env on each affected node,
preserving proxy/CA entries. Restart that node’s Expanse service to apply them.
An export in your interactive shell does not configure a systemd service.
Reusable controller install script
Save this asinstall-expanse.sh, replace the four deployment values, and run
bash install-expanse.sh for a fresh registration. It contains no credential.
Use the upgrade command for an existing compute.
Apply optional runtime settings and capability drop-ins separately on each node.