SunkCluster custom resource (CR) to an existing CoreWeave Kubernetes Service (CKS) cluster. You start from a CKS cluster, which ships with the SunkCluster CRD. From there, provision the user access that Slurm requires and apply a single manifest. Finish by connecting to a login pod over SSH and running a Slurm command.
The SunkCluster CR path is the declarative alternative to the Cloud Console form. It gives you direct control over the manifest and fits GitOps workflows, though it requires a few extra setup steps that the Console otherwise performs for you. For a side-by-side comparison of the two paths, see Create a SUNK cluster. For a full description of every field you can set, see the SunkCluster reference.
By the end of this tutorial, you have a running SUNK cluster that your users can connect to over SSH and submit Slurm jobs against.
In this tutorial
This tutorial covers the following steps:- Confirm the
SunkClusterCRD is present and create thetenant-slurmnamespace. - Create the user groups that have access to the cluster.
- Enable the SCIM API and SUNK User Provisioning, and create a SCIM token.
- Store the SCIM token as a Kubernetes secret.
- Author and apply the
SunkClustermanifest. - Verify the cluster is ready.
- Connect to a login pod over SSH.
Prerequisites
Before you begin, make sure you have the following:- An existing CKS cluster you can apply manifests against. See Create a CKS cluster.
kubectlaccess to that cluster, with a kubeconfig downloaded from the Cloud Console. See Manage API access tokens and kubeconfig files.- The
SunkClusterCRD, which CKS clusters include by default. You confirm this in the first step. If it’s missing, contact your CoreWeave Solutions Architect. - Sufficient compute and CPU quota for the compute nodes and the Slurm control plane.
- Administrator access to CoreWeave IAM so you can enable the SCIM API, create a token, and manage groups.
- An SSH public key on your CoreWeave profile. Without a key attached to your profile, a user added to a Slurm group can’t connect to the login pod over SSH. Add one on your Profile page under Update Slurm attributes.
Step 1: Confirm the CRD and create the namespace
When you apply aSunkCluster resource, the SUNK operator reconciles it into the underlying NodePools, NodeSets, and SlurmCluster resources that make up a running cluster. It watches all namespaces. This tutorial uses tenant-slurm by convention, which keeps Slurm resources together and matches the rest of the SUNK documentation.
First, confirm the SunkCluster CRD is present:
Error from server (NotFound), the CRD isn’t present on your cluster. Contact your CoreWeave Solutions Architect before continuing.
Next, create the tenant-slurm namespace:
SunkCluster resource you apply later and the SCIM secret you create in Step 4 in tenant-slurm, so they live together.
Step 2: Create the user groups
SUNK provisions cluster access to groups of users, not individual users. CoreWeave creates two groups for you in the Cloud Console, which this tutorial uses:slurm-usersfor standard access.sudo-usersfor users who can run privileged commands.
SunkCluster manifest in Step 5. If you federate users from an identity provider (IdP) with Automated User Provisioning (AUP), create the groups there and let AUP sync them into CoreWeave IAM. Otherwise, create them directly in the Console:
- On the Groups page, select Create Group, enter the group name, and select Create.
- Repeat for each additional group.
When you add a user to a group, SUNK provisions their Slurm account, but the login pod only permits SSH from a key attached to the user’s CoreWeave profile. Each user must add their own SSH public key on their Profile page under Update Slurm attributes.
Step 3: Enable the SCIM API and create a token
SUNK User Provisioning (SUP) uses a SCIM token to read user and group data from CoreWeave IAM and provision matching POSIX and Slurm identities on the cluster. Enable the API and create a token:- In the Cloud Console, go to the SCIM Configuration page.
- Enable Enable SCIM API and Enable SUNK User Provisioning. If you federate users from an IdP with AUP, also enable Enable Automated User Provisioning.
- Create a SCIM token with a name of your choice, and copy the token value. You use it in the next step.
Step 4: Store the SCIM token as a Kubernetes secret
The SUNK operator finds the SCIM token by looking for a secret in thetenant-slurm namespace whose name follows a convention. As a result, you don’t reference the secret from the SunkCluster manifest. Name the secret [CLUSTER-NAME]-nsscache-scim-secret, where [CLUSTER-NAME] is the name you give the SunkCluster in Step 5. Decide that name now so you can reuse it in both steps. Inside the secret, store the token under the key nsscache-scim-auth-token.
Create the secret, replacing [CLUSTER-NAME] with your cluster name and [SCIM-TOKEN] with the token value you copied in the previous step:
kubectl create secret generic base64-encodes the value for you, so paste the token in plain text. Confirm the secret exists:
The SCIM secret is optional at creation time, and the SUNK operator brings the cluster up without it. User provisioning over SCIM works once the secret is present, so create it before users need to connect. You can create or update it after you apply the manifest in Step 5, and the SUNK operator picks it up.
Step 5: Author and apply the SunkCluster manifest
With access provisioned, declare the cluster. Save the following manifest assunkcluster.yaml, replacing the bracketed placeholders. For supported sunkVersion and slurmVersion combinations, see SUNK and Slurm versions. For instance types, see the available instances page.
SUNK supports one
SunkCluster per CKS cluster. If more than one exists, the operator reconciles only a single active cluster.nodes: Each entry becomes one managedNodePooland oneNodeSet. ThenameandinstanceTypefields are immutable after creation.countis mutable and scales the underlyingNodePool. The entry withcontrolPlane: truehosts the Slurm control plane.storage.homeDir: The shared home directory mount, sized at the2Tidefault here. Shared storage is pooled across all users in the cluster.login.groups: The groups whose members can access the cluster, matching the groups from Step 2.userPodsgives each member their own login pod, andgroupPodcreates one pod shared by the group. Thesudo-usersentry adds users to the sudoers list. List sudo-enabled groups undersudoGroups.login.userPods.accessandlogin.groupPods.access: The load balancer annotations that expose login pods on a public address for SSH.coreweave-load-balancer-type: publicrequests an external IP,coreweave-load-balancer-ip-families: ipv4selects the address family, and the optionalexternal-hostnameannotation assigns a stable hostname. The two classes are configured separately so you can expose them independently.
External IPs are billable and are off by default. Because a cluster typically has many more user pods than group pods, you can expose only the group pods to limit external-IP cost. This approach still gives every user a way to connect. Omit the
access annotations entirely to keep login pods internal, then reach them with kubectl port-forward as described in Connect to a Slurm login node.cw-sunk namespace, begins reconciling it into the NodePools, NodeSets, and SlurmCluster that make up a running cluster. For GitOps, commit the manifest and point your continuous-delivery tool at the tenant-slurm namespace. See Manage deployments with CI and GitOps.
Step 6: Verify the cluster is ready
The SUNK operator provisions the cluster asynchronously. A new SUNK cluster typically takes around 40 minutes to come up, with node provisioning accounting for most of that time. Check theSunkCluster resource to track progress:
reason and message details, add -o yaml:
Ready condition is True. That condition is only True when each of its dependent conditions is True. While the cluster comes up for the first time, the Ready condition reports reason: Bootstrapping and a message that lists the dependent conditions still pending. For example, the message might read Waiting for conditions: NodePoolsAvailable, NodeSetsAvailable, SlurmClusterAvailable. Each dependent condition reports reason: InProgress while it works, reason: Ready when satisfied, or reason: Error when it fails.
You can also inspect the underlying resources directly:
reason values, see the SunkCluster reference. If the cluster is stuck with Ready: False, the most common cause is insufficient quota holding NodePoolsAvailable in reason: InProgress. For more, see Troubleshoot.
Step 7: Connect to a login pod over SSH
Once the cluster is ready, find the login service’s external address and connect over SSH. This address exists because thelogin access annotations in Step 5 requested a public load balancer. Look up the address:
EXTERNAL-IP field in the output is the target address for SSH access:
[USERNAME] with your Slurm username and [EXTERNAL-IP] with the address from the previous command:
SunkCluster manifest, with user access provisioned and a verified SSH login.
Next steps
Continue with the following resources:SunkClusterreference for every supported field.- Provision users in SUNK to add more users and groups.
- Connect to a Slurm login node for more ways to reach the cluster and run jobs.
- Train on SUNK to run an end-to-end training workload on your new cluster.