Skip to content
Back to skills

Gpu Cluster Provisioning

ASecurity

Use when creating or repairing a GPU Kubernetes cluster for npa — the managed-image vs GPU-Operator driver decision, why operator mode is unsafe on NVSwitch, the post-apply health gates (fabric, CUDA vectorAdd, stability window), and triage for nodes that come up without working GPUs.

  • 33 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 8, 2026
businesspythongobashnoderailskubernetesterraformdebuggingapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 22, 2026

npx -y skills add nebius/nebius-physical-ai --skill gpu-cluster-provisioning --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Gpu Cluster Provisioning?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Gpu Cluster Provisioning
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/nebius-gpu-cluster-provisioning/badge)](https://www.skillsdirectory.com/skills/nebius-gpu-cluster-provisioning)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: gpu-cluster-provisioning
description: Use when creating or repairing a GPU Kubernetes cluster for npa — the managed-image vs GPU-Operator driver decision, why operator mode is unsafe on NVSwitch, the post-apply health gates (fabric, CUDA vectorAdd, stability window), and triage for nodes that come up without working GPUs.
---

# GPU cluster provisioning and driver strategy

Getting GPU nodes is the easy part. Getting nodes whose GPUs actually work — and
knowing *before* you submit a job that they do — is what this skill covers. It
complements `skills/atomic/gpu-selection/SKILL.md` (which GPU to ask for) and
`skills/tools/nebius-infra/SKILL.md` (config, storage, teardown) with the driver
and readiness decisions made at provisioning time.

Source of record: `docs/workbench/mk8s-gpu-driver-strategy.md`.

## The driver decision: default to managed, do not reach for operator

One policy covers both direct `npa cluster` provisioning and `npa fleet`: **GPU
node groups use a Nebius managed-driver image by default**, and CPU-only node
groups get no GPU driver settings at all.

| `--gpu-driver-mode` | Behavior | Use when |
|---|---|---|
| `auto` (default) | Managed-driver image whenever the recipe/provider supports it | Almost always |
| `managed-image` | Explicitly require the managed-driver image | Pinning the operational contract |
| `operator` | In-cluster NVIDIA GPU Operator driver path | Supported diagnostics or a recipe that requires it |

```bash
npa cluster up --gpu-driver-mode auto --managed-driver-preset cuda13.0
```

The default managed preset is `cuda13.0`. The same values exist on
`npa provision-if-absent`, and in a fleet spec under `defaults` or a single
cluster (`gpu_driver_mode`, `managed_driver_preset`).

**Operator mode is unsafe on NVSwitch topologies.** Fabric Manager can start
before Network Operator/MOFED exposes the host InfiniBand management devices,
and the result is nodes that exist but cannot run CUDA. It presents as:

- `NebiusGPUError=True`
- Fabric status `In Progress` or `N/A`
- CUDA `system not yet initialized`
- Fabric Manager / NVLSM `umad_open_port()` or `IB_ERROR` failures

NPA identifies an NVSwitch-risk topology from an explicit GPU cluster or a
multi-GPU SXM/NVL preset and **rejects operator mode** unless you pass
`--allow-unsafe-nvswitch-operator`. That flag is a diagnostics acknowledgement,
not a workaround: if a deploy fails and the suggested fix is that flag, the fix
is almost always `auto` instead.

The policy is topology-independent — expected capacity is derived from the
requested node count and GPU preset, not from a GPU SKU or an assumption of
eight devices per node.

## RTX rendering profile

For Isaac/RTX rendering on RTX PRO 6000 Kubernetes, use the explicit profile:

```bash
npa cluster up --gpu-workload-profile rtx-rendering
```

The profile selects `gpu-rtx6000` (or preserves an exact zonal variant such as
`gpu-rtx6000-a`) and defaults to `1gpu-24vcpu-218gb`; an
explicit `8gpu-192vcpu-1744gb` RTX PCIe preset is also supported. Both use the
GPU Operator mounted-driver path and a mandatory graphics readiness gate. The
8-GPU RTX shape is not an SXM/NVL fabric topology, so it does not enable a GPU
cluster or the NVSwitch unsafe-operator exception. The
gate runs after stabilization and CUDA vectorAdd on every GPU node. Its pinned,
payload-clean RTX image must dynamically load operator-mounted GLX and EGL,
create a Vulkan instance, and enumerate an NVIDIA physical device. Do not
replace it with library filename or environment-variable inspection. The empty
profile preserves the managed-image default for every other workload, and the
NVSwitch operator rejection remains in force.

## Provision with the health gates on

The managed cluster recipe requires Terraform 1.12.0 or newer. Check the selected
binary before provisioning; `NPA_TERRAFORM_BIN` can select a compatible private
installation without replacing the operator's existing Terraform on `PATH`.

```bash
npa cluster up \
  --project <alias> \
  --gpu-nodes 2 --gpu-platform <platform> --gpu-preset <preset> \
  --cpu-nodes 1 --cpu-platform <platform> --cpu-preset <preset> \
  --gpu-driver-mode auto --managed-driver-preset cuda13.0 \
  --gpu-health-stabilization-seconds 120 \
  --validation-timeout 60 --timeout 120
```

Defaults are deliberately strict, and every one of them is on for a reason:

- `--validate` (default) checks stable nodes, GPU capacity, fabric, driver
  components, CUDA vectorAdd, and the default StorageClass.
- `--gpu-cuda-smoke` (default) runs NVIDIA's CUDA vectorAdd **on every requested
  GPU node**, which is the cheapest proof that drivers actually work.
- `--gpu-health-stabilization-seconds` (default 120) requires nodes, boot IDs,
  fabric, capacity, and components to stay healthy for that window. It exists
  because GPU nodes routinely look healthy for a few seconds during labelling.
- `--sky-smoke` (default) runs a SkyPilot Kubernetes GPU task and cleans it up.
- `--gpu-workload-profile rtx-rendering` additionally requires the per-node
  GLX/EGL/Vulkan renderer-facing gate; it has no skip/warn-only mode.

Do not reach for `--skip-validate` / `--skip-gpu-cuda-smoke` to make a deploy
"succeed" faster. Skipping them moves the failure to your first real job, where
it costs more and is harder to attribute. `-1` on `--gpu-nodes` / `--cpu-nodes`
keeps the configured value rather than meaning zero.

For reserved capacity, `--capacity-block-group` selects a private capacity
block for strict GPU node-group reservation. `--preemptible` is often the only
way to get several GPUs at once, but a reclaim stops nodes mid-run — keep CPU
stages on the CPU pool, and note that preemptibility changes the capacity pool
only, never the disk or IP quota requirements.

When a cluster enables a shared filestore (or attaches an existing one), set
`TF_VAR_filesystem_csi_chart_repository` to the operator-approved Shared
Filesystem CSI Helm repository. NPA intentionally has no provider-private
default and now fails before apply if the repository is absent; creating the
filesystem without its CSI driver leaves validation waiting for a StorageClass
that cannot appear.

## Node groups after the fact

```bash
npa cluster node-group list --project <alias>
npa cluster node-group status --project <alias>
npa cluster node-group add --project <alias> ...
npa cluster node-group add-cpu --project <alias> ...
npa cluster node-group remove --project <alias> ...
```

GPU additions accept the same `--gpu-driver-mode auto|managed-image|operator`
and `--managed-driver-preset` contract as initial provisioning. Use `operator`
only when the workload needs an operator-managed capability absent from the
managed image and the selected topology is not NVSwitch-class.

Add a CPU pool rather than running CPU stages on GPU nodes: it is cheaper and it
keeps preemptible GPU reclaims from killing coordination work.

## After provisioning: what the cluster calls its GPUs

A healthy cluster is not yet a submittable one. SkyPilot addresses accelerators
by the name the cluster advertises, which comes from node labels and **changes
while the GPU operator is still labelling** (`nebius.com/gpu-name` first,
`nvidia.com/gpu.product` after):

```bash
npa cluster status --project <alias>
npa workbench workflow gpus --cluster <name> --json
npa skypilot verify --cluster <name> --output-format json
```

Run `workflow gpus` once after provisioning and note the requestable quantity per
node. A name mismatch fails as `FAILED_PRECHECKS` or "cluster does not contain
any instances satisfying the request", which reads like a capacity shortage and
is not one.

Use `npa provision-if-absent --sky-smoke` with the selected topology, driver
settings, kubeconfig, and SkyPilot binary to prove actual GPU dispatch. Cluster
validation keeps checks, discovery, launch, and cleanup in one owned API session
with a durable working directory. Success requires workload removal before the
API stops. If removal is unverified, retain the reported session state and its
original environment for recovery; do not stop an unowned shared API or delete
its state to make the smoke pass.

## Triage: nodes exist but GPUs do not work

1. **`NebiusGPUError=True`, fabric not ready, CUDA "system not yet initialized"**
   → operator-mode/Fabric-Manager ordering on NVSwitch. Redeploy the GPU node
   group with `--gpu-driver-mode auto`. Do not paper over it with the unsafe
   acknowledgement flag.
2. **Nodes Ready but zero schedulable `nvidia.com/gpu`** → drivers or device
   plugin have not landed. Re-run validation rather than submitting; the
   stability window exists precisely for this state.
3. **Accelerator name not found by SkyPilot** → labelling is still in progress or
   the spec uses a different spelling. Use `workflow gpus`.
4. **CUDA vectorAdd fails on one node only** → that node is bad; remove and
   re-add the node group rather than debugging the whole cluster.
5. **Deploy succeeded but jobs stall in `ImagePullBackOff`** → not a GPU problem
   at all. See `skills/atomic/debug-failed-run/SKILL.md`.

An image can also be architecturally incapable of running on the GPU you
provisioned — `sm_120` (RTX PRO 6000) and `sm_100`/`sm_103` (B200/B300) binaries
are mutually incompatible across the CUDA major boundary. That is an image
question, not a cluster question: see `docs/workbench/image-gpu-compatibility-matrix.md`
and `skills/atomic/gpu-selection/SKILL.md`.

## Gotchas

- **`npa cluster` is not raw MK8s administration.** For edit, update, upgrade,
  operation inspection, version listing, and the compatibility matrix, use
  `nebius mk8s` directly.
- **`npa cluster down` going silent for minutes is expected** — it previews the
  PodDisruptionBudgets that hold up the node drain first.
- **Stale `NEBIUS_IAM_TOKEN` breaks Terraform and the provider** even when the
  `nebius` CLI works. `unset NEBIUS_IAM_TOKEN NPA_NEBIUS_IAM_TOKEN` first.
- **SkyPilot task pods run in `default`; deployed workbench services run in
  `workbench`.** A pull secret in the wrong namespace helps nothing.
- **Provisioning is additive, teardown is not.** `provision-if-absent` never
  replaces resources; `cluster down` destroys. See
  `skills/atomic/teardown-and-cost/SKILL.md` for the ordering.

## Verify

```bash
npa/.venv/bin/python -m pytest npa/tests/guardrails/test_skills_index.py -q
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.