Skip to content

Commit fe764f3

Browse files
committed
feat(recipes): gpuStack profile for the OKE family
Convert OKE to the ADR-015 gpuStack configuration profile with three values, declared on oke-ol.yaml and inherited by every OL and Ubuntu leaf: - oci-default (default): the stock OKE cluster — Oracle's GPU node image supplies the driver and toolkit, and OKE's auto-installed device plugin is the nvidia.com/gpu advertiser (advertiser: external). The GPU Operator's plugin is disabled, correcting today's double-advertisement: the previous values-oke.yaml left the operator's plugin enabled while OKE's plugin also advertises on every default cluster. - operator-plugin: image-supplied driver, OKE's plugin disabled (the oci.oraclecloud.com/disable-gpu-device-plugin=true node label, or the NvidiaGpuPlugin add-on removed), the operator's plugin advertises. - operator-managed: bring-your-own driverless image — the operator installs driver, toolkit, and plugin, and the DRA driver root moves to /run/nvidia/driver in lockstep (issue #1087). The values are distinguished by deployed ClusterPolicy state via readinessConstraints (K8s.policy.driver.enabled and K8s.policy.devicePlugin.enabled — existing open-keyed readings, evaluated by the validate pre-flight). A generation-time gate on the disable-gpu-device-plugin node label is follow-up work: the gpu-nodes label constraint universe is GKE-specific today, and provisioning that removes the add-on leaves no on-node marker. Also absorbed into the profile or the family values: - nvsentinel.labeler.assumeDriverInstalled moves from the overlay into the per-value fragments, fixing the polarity under operator-managed (the operator's driver pod is the labeler's evidence; assuming a preinstalled driver would label GPU nodes before the driver is ready). - values-oke.yaml gains the universal OKE bare-metal device-plugin env (DEVICE_LIST_STRATEGY=cdi-annotations,cdi-cri,volume-mounts and MOFED_ENABLED=false — consequences of cri-o + CDI + host MOFED, which every OKE image carries). - nodewright-operator registry default bumps to v0.18.0: OKE's cri-o enforces short-name resolution and rejects the v0.17.1 chart's alpine/kubectl maintenance-hook image (NVIDIA/nodewright#481). operator.defaultRuntime is deliberately NOT set: production OKE cri-o clusters run the operator without it (runtime auto-detection), verified against live cluster state. Catalog and stock-render parity goldens regenerated (all OKE leaf digests move — the family-wide re-qualification event; nodewright bump moves the rest). BOM and recipe-health docs regenerated. Signed-off-by: Atif Mahmood <atif1996@users.noreply.github.com>
1 parent 6de8196 commit fe764f3

15 files changed

Lines changed: 658 additions & 173 deletions

File tree

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ For pipelines and platforms that call AICR programmatically or host
4646
| Add or modify recipe metadata | [Recipe Development](integrator/recipe-development.md) |
4747
| Verify artifacts (SLSA, SBOM, attestations) | [Supply Chain Verification](integrator/supply-chain-verification.md) |
4848
| Ship custom validators via `--data` | [Validator Extension](integrator/validator-extension.md) |
49-
| Cloud-specific GPU setup | [AKS](integrator/aks-gpu-setup.md), [GKE](integrator/gke-gpu-setup.md), [EKS networking](integrator/eks-dynamo-networking.md), [GKE networking](integrator/gke-tcpxo-networking.md), [Talos](integrator/talos-integration.md) |
49+
| Cloud-specific GPU setup | [AKS](integrator/aks-gpu-setup.md), [GKE](integrator/gke-gpu-setup.md), [OKE](integrator/oke-gpu-setup.md), [EKS networking](integrator/eks-dynamo-networking.md), [GKE networking](integrator/gke-tcpxo-networking.md), [Talos](integrator/talos-integration.md) |
5050

5151
### Contributor Guide
5252

docs/integrator/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ This section is for integrators who:
2424
| [GKE TCPXO Networking](gke-tcpxo-networking.md) | GPUDirect TCPXO prerequisites for GKE training overlays |
2525
| [AKS GPU Setup](aks-gpu-setup.md) | AKS prerequisites: Kubernetes 1.34+ (DRA GA), GPU driver setup, DRA configuration |
2626
| [GKE GPU Setup](gke-gpu-setup.md) | GKE device-plugin ownership: the `gpuStack` profile, node-pool setup for both values, verification, and troubleshooting |
27+
| [OKE GPU Setup](oke-gpu-setup.md) | OKE GPU stack ownership: the `gpuStack` profile (three values), the device-plugin add-on / disable label, and bring-your-own-image pools |
2728
| [Talos Integration](talos-integration.md) | Running AICR on Talos Linux |
2829
| [OpenShift Deployment](openshift.md) | OpenShift/OCP-specific Helm and OLM integration and two-phase operator deployment |
2930
| [Recipe Development](recipe-development.md) | Creating and modifying recipe metadata for custom environments |

docs/integrator/oke-gpu-setup.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# OKE GPU Setup
2+
3+
## GPU Stack Ownership
4+
5+
OKE installs NVIDIA's device plugin automatically on every cluster, and
6+
Oracle's GPU node images preinstall the NVIDIA driver, container toolkit, and
7+
host MOFED. Which of those a GPU node pool actually has depends on how it was
8+
provisioned, and the AICR recipe must match it — the `gpuStack` configuration
9+
profile on the OKE family names the three qualified combinations:
10+
11+
| Value | Driver / toolkit | `nvidia.com/gpu` advertiser | Pool shape |
12+
|---|---|---|---|
13+
| `oci-default` (default) | Oracle GPU node image | OKE's auto-installed device plugin | stock OKE with Oracle GPU images |
14+
| `operator-plugin` | Oracle GPU node image | GPU Operator's device plugin | OKE plugin disabled (node label or add-on removed) |
15+
| `operator-managed` | GPU Operator installs both | GPU Operator's device plugin | bring-your-own driverless image |
16+
17+
MOFED is host-supplied in every value — Oracle's GPU images and the common
18+
bring-your-own images alike carry it, so `network-operator` never deploys
19+
`ofedDriver` on OKE, and the device plugin runs with `MOFED_ENABLED=false`
20+
(without it, k8s-device-plugin >= 0.19.0 with CDI floods every host RDMA
21+
uverb into every GPU pod and breaks NCCL).
22+
23+
Select the mode at recipe generation; the paths it owns are locked at every
24+
output boundary:
25+
26+
```shell
27+
# Stock OKE cluster (the default) — no flag needed
28+
aicr recipe --service oke --accelerator l40s --os ol --intent training -o recipe.yaml
29+
30+
# OKE plugin disabled, image-supplied driver
31+
aicr recipe --service oke --accelerator l40s --os ol --intent training \
32+
--profile gpuStack=operator-plugin -o recipe.yaml
33+
34+
# Bring-your-own driverless image (e.g. a custom Ubuntu image)
35+
aicr recipe --service oke --accelerator gb200 --os ubuntu --intent training \
36+
--profile gpuStack=operator-managed -o recipe.yaml
37+
```
38+
39+
## Default: Stock OKE (`oci-default`)
40+
41+
A default-provisioned OKE cluster with Oracle GPU images needs zero setup:
42+
the image supplies the driver and toolkit, and OKE's device plugin advertises
43+
`nvidia.com/gpu`. The GPU Operator manages the rest of the stack with its own
44+
plugin disabled — running both plugins double-advertises the same GPUs, which
45+
the #1327 exactly-one-advertiser policy forbids.
46+
47+
## Alternative: Let the GPU Operator's Plugin Advertise (`operator-plugin`)
48+
49+
If you prefer the GPU Operator's device plugin (feature discovery, MIG, CDI
50+
control), disable OKE's plugin on the GPU pools and select the value:
51+
52+
- **Per node pool (recommended, snapshot-visible):** add the node label
53+
`oci.oraclecloud.com/disable-gpu-device-plugin=true` to the pool's initial
54+
node labels at creation.
55+
- **Per cluster:** remove the `NvidiaGpuPlugin` cluster add-on
56+
(Terraform `addons = { NvidiaGpuPlugin = { remove = true } }`, or the
57+
add-on lifecycle API). Note this leaves no on-node marker.
58+
59+
The driver still comes from the Oracle image — the GPU Operator installs
60+
nothing under this value.
61+
62+
## Alternative: Bring-Your-Own Image (`operator-managed`)
63+
64+
Custom images (OKE Ubuntu pools are always custom images) may ship no NVIDIA
65+
stack at all. Under `operator-managed` the GPU Operator installs the driver
66+
and toolkit, its device plugin advertises, and the DRA kubelet plugin reads
67+
the driver userspace from the operator install path
68+
(`/run/nvidia/driver` — the profile moves `nvidiaDriverRoot` in lockstep;
69+
see the driver-ownership coherence rules). Disable OKE's device plugin on
70+
these pools exactly as under `operator-plugin`.
71+
72+
If your custom image DOES bake a driver (Oracle publishes downloadable
73+
Ubuntu GPU images with driver + CUDA + DOCA-OFED), use `operator-plugin`
74+
instead — a second, operator-installed driver on top of an image driver is
75+
an unqualified hybrid.
76+
77+
## Validation
78+
79+
The three values deploy differently, so `aicr validate` distinguishes them by
80+
**deployed ClusterPolicy state** (readiness pre-flight, fail closed):
81+
`K8s.policy.driver.enabled` and `K8s.policy.devicePlugin.enabled` must match
82+
the selected value. A recipe generated with the wrong mode for the cluster
83+
fails the pre-flight with remediation text before any check Jobs deploy.
84+
There is no generation-time gate yet: the snapshot cannot see a removed
85+
add-on, and pools disabled via the add-on (rather than the node label) leave
86+
no on-node marker.
87+
88+
## Oracle Add-on Interactions
89+
90+
Do **not** enable Oracle's `NvidiaGpuOperator` or `NvidiaNetworkOperator`
91+
managed add-ons alongside AICR bundles — the bundle deploys both operators
92+
itself, and two lifecycle managers fight over the same releases. The only
93+
Oracle GPU add-on compatible with AICR bundles is the device plugin
94+
(`NvidiaGpuPlugin`), and only under `oci-default`.
95+
96+
## References
97+
98+
- [OKE: Running GPU Workloads](https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengrunninggpunodes.htm)
99+
- [OKE cluster add-ons](https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengintroducingclusteraddons.htm)
100+
- [oci-hpc-oke quickstart](https://github.com/oracle-quickstart/oci-hpc-oke) — worker images, RDMA manifests
101+
- [AKS GPU Setup](aks-gpu-setup.md), [GKE GPU Setup](gke-gpu-setup.md) — the sibling `gpuStack` families

docs/user/cli-reference.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,14 @@ values govern advertisement, the #1327 allocation-policy paths are
358358
closure-locked in addition to the declared owned paths — see
359359
[GKE GPU setup](../integrator/gke-gpu-setup.md#gpu-device-plugin-ownership) and
360360
[Component Catalog › GKE Device-Plugin Ownership](component-catalog.md#gke-device-plugin-ownership).
361+
The OKE family declares `gpuStack` with values `oci-default` (default;
362+
Oracle's GPU node image supplies the driver and OKE's auto-installed device
363+
plugin advertises — `advertiser: external`), `operator-plugin` (image driver,
364+
GPU Operator's plugin advertises; OKE's plugin disabled via the
365+
`oci.oraclecloud.com/disable-gpu-device-plugin=true` node label or add-on
366+
removal), and `operator-managed` (bring-your-own driverless image; the
367+
operator installs driver, toolkit, and plugin, with the DRA driver root in
368+
lockstep) — see [OKE GPU setup](../integrator/oke-gpu-setup.md).
361369
Profiles can also be exercised through a versioned external overlay.
362370

363371
Selection and verification are independent: `--profile` (or the default)
@@ -457,7 +465,7 @@ Generate recipes using direct system parameters:
457465
| `--intent` | | string | Workload intent: training, inference |
458466
| `--os` | | string | OS family: ubuntu, rhel, cos, amazonlinux, ol, talos |
459467
| `--platform` | | string | Platform/framework type: dynamo, kubeflow, nim, runai, slurm |
460-
| `--profile` | | string | Profile selection in exact `name=value` form (e.g. `gpuStack=operator-managed` on AKS or `gpuStack=driver-installer` on GKE); omit to use the declaration's default (`gpuStack=azure-managed` on AKS, `gpuStack=gke-default` on GKE) |
468+
| `--profile` | | string | Profile selection in exact `name=value` form (e.g. `gpuStack=operator-managed` on AKS/OKE or `gpuStack=driver-installer` on GKE); omit to use the declaration's default (`gpuStack=azure-managed` on AKS, `gpuStack=gke-default` on GKE, `gpuStack=oci-default` on OKE) |
461469
| `--slurm-accounting-mode` | | string | Slurm accounting ownership: disabled (default), customer-managed, aicr-provided |
462470
| `--runtime-inventory` | | string | Runtime AI inventory (`k8s-aibom`) selection: `enabled`, `disabled`. Recorded in the generated recipe |
463471
| `--nodes` | | int | Number of GPU nodes in the cluster |

docs/user/component-catalog.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,17 @@ The recipes now carry that value wherever it is needed ([#2181](https://github.c
149149
| AKS `gpuStack=operator-managed` | the operator's driver pod | `false` | the `gpuStack` profile |
150150
| GKE COS `gpuStack=gke-default` (default) | none the labeler can observe — the driver is finalized by an init container of GKE's kube-system DaemonSet | `true` | the `gpuStack` profile |
151151
| GKE COS `gpuStack=driver-installer` | Google's standalone `nvidia-driver-installer` DaemonSet | `false` | the `gpuStack` profile |
152-
| OKE | none — driver is in the node image | `true` | the overlay (OKE has no profile) |
152+
| OKE `gpuStack=oci-default` (default) | none — driver is in the node image; OKE's auto plugin advertises | `true` | the `gpuStack` profile |
153+
| OKE `gpuStack=operator-plugin` | none — driver is in the node image (OKE plugin disabled; operator plugin advertises) | `true` | the `gpuStack` profile |
154+
| OKE `gpuStack=operator-managed` | the operator's driver pod | `false` | the `gpuStack` profile |
153155
| EKS | the operator's driver pod | unset (chart default `false`) ||
154156
| Kind (nvkind) | none — driver is host-installed | `true` | the overlay (Kind has no profile) |
155157

156158
The explicit `false` on the operator-managed variants is deliberate rather than redundant: it keeps the path profile-owned, so it cannot be flipped into an unsafe hybrid later. Do **not** assume a preinstalled driver where the GPU Operator installs one — skipping detection there would keep the label applied across an unloaded or unhealthy driver.
157159

158-
**NVSentinel is mandatory on the profiled families.** Because the AKS and GKE-COS `gpuStack` profiles name nvsentinel, its presence is profile-owned: `--set nv-sentinel:enabled=false` and a `bundlers=` list that omits it are both rejected on those platforms. That is intended — NVSentinel is a required component for these deployments. It remains optional on platforms with no `gpuStack` profile, such as OKE and EKS.
160+
**NVSentinel is mandatory on the profiled families.** Because the AKS, GKE-COS, and OKE `gpuStack` profiles name nvsentinel, its presence is profile-owned: `--set nv-sentinel:enabled=false` and a `bundlers=` list that omits it are both rejected on those platforms. That is intended — NVSentinel is a required component for these deployments. It remains optional on platforms with no `gpuStack` profile, such as EKS.
159161

160-
Only AKS and GKE-COS get the install-time profile lock; OKE and Kind set the value at overlay level, so a bundle-time or declared-dynamic change is still rejected by the gate below, but a manual post-generation edit to the rendered Helm values is not.
162+
AKS, GKE-COS, and OKE get the install-time profile lock; Kind sets the value at overlay level, so a bundle-time or declared-dynamic change is still rejected by the gate below, but a manual post-generation edit to the rendered Helm values is not.
161163

162164
If you do need to set it yourself on an unlisted platform, it is an ordinary override:
163165

docs/user/container-images.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ A machine-readable **CycloneDX 1.6 JSON** companion to this page is produced by
2020
## Summary
2121

2222
- Components: **43**
23-
- Unique images: **98**
23+
- Unique images: **97**
2424
- Distinct registries: **11**
2525

2626
Registries: `602401143452.dkr.ecr.us-west-2.amazonaws.com`, `cr.agentgateway.dev`, `docker.io`, `gcr.io`, `ghcr.io`, `gke.gcr.io`, `nvcr.io`, `public.ecr.aws`, `quay.io`, `registry.k8s.io`, `us-docker.pkg.dev`
@@ -62,7 +62,7 @@ _Rendering fidelity:_ `catalog-parity: charts are rendered with the shared recip
6262
| nfd-ocp | manifest ||| 0 |
6363
| nfd-ocp-olm | manifest ||| 0 |
6464
| nodewright-customizations | manifest ||| 5 |
65-
| nodewright-operator | helm | nodewright | v0.17.1 | 3 |
65+
| nodewright-operator | helm | nodewright | v0.18.0 | 2 |
6666
| nvidia-dra-driver-gpu | helm | dra-driver-nvidia-gpu | 0.4.1 | 1 |
6767
| nvidia-dra-driver-gpu-ocp | helm | dra-driver-nvidia-gpu | 0.4.1 | 1 |
6868
| nvsentinel | helm | nvsentinel | v1.9.0 | 6 |
@@ -268,9 +268,8 @@ _No images extracted._
268268

269269
### nodewright-operator
270270

271-
- `alpine/kubectl:1.36.2@sha256:01d138ce994b684abc62d9cfdff44de42a4c8996dcc12626dd0193afc3fb5a95`
272-
- `ghcr.io/nvidia/nodewright/operator:v0.17.0@sha256:1511449bf51f2844b6bb3a03bde3d5590caf2ca283e3e39c0745a8016af2132f`
273-
- `quay.io/brancz/kube-rbac-proxy:v0.15.0@sha256:2c7b120590cbe9f634f5099f2cbb91d0b668569023a81505ca124a5c437e7663`
271+
- `docker.io/alpine/kubectl:1.36.2@sha256:01d138ce994b684abc62d9cfdff44de42a4c8996dcc12626dd0193afc3fb5a95`
272+
- `ghcr.io/nvidia/nodewright/operator:v0.18.0@sha256:49ace92de35703f6da84c75147e2f93803d8b70f4f48dc9ae5213f7a6788ddfb`
274273

275274
### nvidia-dra-driver-gpu
276275

docs/user/recipe-health.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,14 @@ The deep-link is the current Evidence rendering. It is distinct from — and coe
7878
| b200-gke-cos-inference-dynamo | gke | b200 | cos | inference | dynamo | pass | R:0 D:4 P:0 C:11 | pending |
7979
| b200-gke-cos-training-kubeflow | gke | b200 | cos | training | kubeflow | pass | R:0 D:4 P:0 C:10 | pending |
8080
| h100-gke-cos-inference-dynamo | gke | h100 | cos | inference | dynamo | pass | R:0 D:4 P:1 C:11 | pending |
81-
| h100-gke-cos-training-kubeflow | gke | h100 | cos | training | kubeflow | pass | R:0 D:4 P:1 C:10 | pending |
82-
| h100-gke-cos-training-slurm | gke | h100 | cos | training | slurm | pass | R:0 D:4 P:0 C:11 | pending |
81+
| h100-gke-cos-training-kubeflow | gke | h100 | cos | training | kubeflow | pass | R:0 D:5 P:1 C:10 | pending |
82+
| h100-gke-cos-training-slurm | gke | h100 | cos | training | slurm | pass | R:0 D:5 P:0 C:11 | pending |
8383
| h100-kind-inference-dynamo | kind | h100 || inference | dynamo | pass | R:0 D:4 P:0 C:11 | pending |
8484
| h100-kind-training-kubeflow | kind | h100 || training | kubeflow | pass | R:0 D:4 P:0 C:10 | pending |
8585
| h100-kind-training-slurm | kind | h100 || training | slurm | pass | R:0 D:4 P:0 C:10 | pending |
8686
| rtx-pro-6000-lke-ubuntu-inference | lke | rtx-pro-6000 | ubuntu | inference || pass | R:0 D:4 P:0 C:8 | pending |
8787
| rtx-pro-6000-lke-ubuntu-training | lke | rtx-pro-6000 | ubuntu | training || pass | R:0 D:4 P:0 C:8 | pending |
88-
| ocp-inference | ocp ||| inference | | pass | R:0 D:3 P:0 C:1 | pending |
88+
| ocp-inference-nim | ocp ||| inference | nim | pass | R:0 D:3 P:0 C:11 | pending |
8989
| ocp-training | ocp ||| training || pass | R:0 D:3 P:0 C:1 | pending |
9090
| a100-oke-ubuntu-training-kubeflow | oke | a100 | ubuntu | training | kubeflow | pass | R:0 D:4 P:0 C:8 | pending |
9191
| gb200-oke-ubuntu-inference-dynamo | oke | gb200 | ubuntu | inference | dynamo | pass | R:0 D:4 P:1 C:10 | pending |

0 commit comments

Comments
 (0)