https://skarnet.org/software/s6-rc/. This guide explains how to set up and run two types of scripts: longrun for continuous processes and oneshot for tasks that execute and terminate.
This guide is for cluster administrators who need to automate custom scripts on Compute and Login nodes within a SUNK cluster. Whether you install packages or keep services running, this method provides a straightforward way to manage processes.
Define scripts in values.yaml
Define scripts in the appropriate sections of the Slurm chart’s values.yaml file. Define Compute node scripts in the compute.s6 section, and Login node scripts in the login.s6 section. Each script needs a name, type, and the script itself. The following example shows a script definition within a Compute node:
install-nginx: Thisoneshotscript installsnginxusing the package manager.nginx: Alongrunscript that starts thenginxprocess and keeps it running.
timeoutUp in milliseconds: the install has up to 5 minutes to finish, and nginx has up to 30 seconds to start.
Define and schedule different script types
The following sections explain how to choose the right script type for your task and how to avoid scheduling conflicts that can occur when scripts extend node startup time.Determine the appropriate script type
Decide whether the script is alongrun or a oneshot based on its purpose:
- Use
longrunfor scripts that should run continuously, like a web server. - Use
oneshotfor scripts that run once to perform a setup task, like installing software.
Avoid scheduling conflicts
If youroneshot job installs many packages or performs tasks that otherwise extend startup time, you must account for this by modifying the value of the orphanedPodDelay parameter in the syncer configuration section of the Slurm values.yaml chart.
The full path for this parameter is syncer.config.syncer.orphanedPodDelay. By default, the value of orphanedPodDelay is 120s, or 120 seconds.
If the time required for a oneshot job to run exceeds the value set in orphanedPodDelay, increase the value to avoid scheduling conflicts.
Set timeouts for scripts
Timeouts prevent scripts from hanging indefinitely and help keep nodes healthy. ThetimeoutUp parameter sets the time allowed for the script to start, and timeoutDown sets the time allowed for it to stop. Both are in milliseconds.
Every script-based oneshot must set timeoutUp, and every longrun must set timeoutUp, timeoutDown, or both. A service that omits its timeout is rejected with timeoutUp is required for oneshot scripts unless installing packages. A oneshot that installs packages through the packages key is exempt, because the controller derives a minimum timeout from the package count.
- For
oneshotscripts, onlytimeoutUpis relevant as it’s the maximum completion time for the script. - For
longrunscripts, bothtimeoutUpandtimeoutDowncontrol how long the process has to start and stop.
Define behavior for failed scripts
When a user-defined script fails, the container can continue running silently, provide an error message, or stop. In SUNK, containers stop on script failure by default. You can control this behavior with theS6_BEHAVIOUR_IF_STAGE2_FAILS parameter in the appropriate env section of the values.yaml file.
- For Login nodes, change the value of the parameter in the
login.envsection of thevalues.yamlfile. - For Compute nodes, change the value of the parameter in the
compute.nodes.[TARGET-NODE].envsections of thevalues.yamlfile.
S6_BEHAVIOUR_IF_STAGE2_FAILS parameter can contain the following values:
For more information about the values for
S6_BEHAVIOUR_IF_STAGE2_FAILS, see the s6-overlay customization options.
Raise the open-file limit cluster-wide
A common use of aoneshot script is to raise the open-file descriptor limit (nofile) for every job on the cluster. SUNK container images set the soft limit to 16384 in /etc/bash.bashrc:
-S flag sets only the soft limit, so a non-root user can raise it up to the hard limit. To raise the limit for a single job without administrator help, set it at the top of the sbatch script before srun:
oneshot script in the compute.s6 section that removes the hardcoded line and raises the limit:
values.yaml
16384 soft cap no longer applies, shells inherit the container’s own limits, which are typically 1048576. Don’t add ulimit commands to the script itself: a ulimit call changes only the process that runs it, so it has no effect on the shells and job steps that start later.
Nodes pick up the change when their Pods are replaced. Adding a new s6 block changes the Pod spec, so the NodeSet rolls the compute Pods on its own. Editing the script inside an existing block only updates a ConfigMap, which leaves the Pod spec untouched and doesn’t roll anything, so you have to replace the Pods yourself. If you need to know how running jobs are handled, coordinate the rollout with your cluster administrator. Verify on a compute node:
ulimit commands should report the container default, typically 1048576, rather than 16384. Confirm that a non-root user can now raise the limit by running ulimit -n 65536 and checking ulimit -Sn again.
Raising the limit isn’t a fix for a descriptor leak. If a job’s open-file count grows without bound, the application leaks descriptors, and a higher limit only delays the failure.