Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions compute-domain/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Managed ComputeDomain (GB200/GB300)

Helm chart for the **AKS-managed NVIDIA ComputeDomain controller** — the cluster-scoped
piece of the Grace-Blackwell cross-node NVLink (MNNVL / IMEX) stack. It is delivered as an
AKS core extension (`microsoft.managedcomputedomain`), analogous to how managed DRANET
(`microsoft.manageddranet`) is delivered.

## What this chart deploys

| Object | Purpose |
|---|---|
| `Deployment/compute-domain-controller` | cluster-scoped controller: reconciles `ComputeDomain` CRs, creates the workload `ResourceClaimTemplate`, and (driverManaged) spawns a per-ComputeDomain `compute-domain-daemon` DaemonSet |
| `ServiceAccount` + `ClusterRole` + `ClusterRoleBinding` | controller identity + RBAC, bound to the SA (blast radius = the controller pod, **not** `system:nodes`) |
| `DeviceClass/compute-domain-default-channel.nvidia.com` | the IMEX channel device workloads claim |
| `DeviceClass/compute-domain-daemon.nvidia.com` | the daemon device (driverManaged) |

## What this chart does NOT deliver

- **`compute-domain-daemon`** — not a static object; the controller creates it as a
per-ComputeDomain DaemonSet at runtime, from the controller's **own image** (so the image
must carry both `compute-domain-controller` and `compute-domain-daemon`).
- **`compute-domain-kubelet-plugin`** — runs as a host **systemd** service (delivered via the
`dra-driver-nvidia-gpu` deb), not by this chart. Its node-identity RBAC (2 read-only
`resource.nvidia.com` reads bound to `system:nodes`) is delivered separately.
- **`nvidia-imex`** — the host binary, installed by **aks-gpu** at boot; the daemon pod execs
it via CDI. The host `nvidia-imex.service` stays **off** in driverManaged.

## IMEX mode: driverManaged (only)

This chart hard-defaults to `imex.mode: driverManaged`. `hostManaged` is intentionally not
offered: it would require AKS to own the host IMEX topology (`nodes_config.cfg` = the rack
peer set), which cannot be built at node bootstrap (the peer set is cluster-scoped and
converging) and would just re-implement what the driverManaged DaemonSet does automatically
(via pod DNS names).

## Image

The controller image (`compute-domain-controller` + `compute-domain-daemon`) is onboarded via
dalec/MCR; set `image.repository` / `image.tag` in `values.yaml`.

## Upstream

Chart wraps [`kubernetes-sigs/dra-driver-nvidia-gpu`](https://github.com/kubernetes-sigs/dra-driver-nvidia-gpu)
`v0.5.0` (controller + DeviceClasses + RBAC derived from its `deployments/helm` templates).
20 changes: 20 additions & 0 deletions compute-domain/chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: v2
name: microsoft.managedcomputedomain
description: |
AKS-managed NVIDIA ComputeDomain controller for Grace-Blackwell (GB200/GB300).
Deploys the cluster-scoped compute-domain-controller (and its RBAC + DeviceClasses)
that binds GB nodes into cross-node NVLink (MNNVL) IMEX domains. The controller
dynamically creates a per-ComputeDomain compute-domain-daemon DaemonSet from its
own image (driverManaged IMEX). The node-local compute-domain kubelet-plugin and
the host nvidia-imex binary are delivered separately (deb / aks-gpu), not by this chart.
type: application
version: 0.0.1
appVersion: "0.5.0"
keywords:
- nvidia
- dra
- compute-domain
- imex
- mnnvl
- gb200
- gb300
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.17.1
name: computedomaincliques.resource.nvidia.com
spec:
group: resource.nvidia.com
names:
kind: ComputeDomainClique
listKind: ComputeDomainCliqueList
plural: computedomaincliques
singular: computedomainclique
scope: Namespaced
versions:
- name: v1beta1
schema:
openAPIV3Schema:
description: |-
ComputeDomainClique holds information about a specific clique within a ComputeDomain.
It is created in the driver namespace and named as "<computeDomainUID>.<cliqueID>".
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
daemons:
items:
description: ComputeDomainDaemonInfo provides information about each
daemon in a ComputeDomainClique.
properties:
cliqueID:
type: string
index:
description: |-
The Index field is used to ensure a consistent IP-to-DNS name
mapping across all machines within an IMEX domain. Each node's index
directly determines its DNS name within a given NVLink partition
(i.e. clique). In other words, the 2-tuple of (CliqueID, Index) will
always be unique. This field is marked as optional (but not
omitempty) in order to support downgrades and avoid an API bump.
type: integer
ipAddress:
type: string
nodeName:
type: string
status:
default: NotReady
description: |-
The Status field tracks the readiness of the IMEX daemon running on
this node. It gets switched to Ready whenever the IMEX daemon is
ready to broker GPU memory exchanges and switches to NotReady when
it is not. It is marked as optional in order to support downgrades
and avoid an API bump.
enum:
- Ready
- NotReady
type: string
required:
- cliqueID
- ipAddress
- nodeName
type: object
type: array
x-kubernetes-list-map-keys:
- nodeName
x-kubernetes-list-type: map
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
type: object
served: true
storage: true
163 changes: 163 additions & 0 deletions compute-domain/chart/crds/resource.nvidia.com_computedomains.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.17.1
name: computedomains.resource.nvidia.com
spec:
group: resource.nvidia.com
names:
kind: ComputeDomain
listKind: ComputeDomainList
plural: computedomains
singular: computedomain
scope: Namespaced
versions:
- name: v1beta1
schema:
openAPIV3Schema:
description: ComputeDomain prepares a set of nodes to run a multi-node workload
in.
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: ComputeDomainSpec provides the spec for a ComputeDomain.
properties:
channel:
description: ComputeDomainChannelSpec provides the spec for a channel
used to run a workload inside a ComputeDomain.
properties:
allocationMode:
default: Single
description: |-
Allows for requesting all IMEX channels (the maximum per IMEX domain) or
precisely one.
enum:
- All
- Single
type: string
resourceClaimTemplate:
description: ComputeDomainResourceClaimTemplate provides the details
of the ResourceClaimTemplate to generate.
properties:
name:
type: string
required:
- name
type: object
required:
- resourceClaimTemplate
type: object
numNodes:
default: 0
description: |-
Intended number of IMEX daemons (i.e., individual compute nodes) in the
ComputeDomain. Must be zero or greater.

With `featureGates.IMEXDaemonsWithDNSNames=true` (the default), this is
recommended to be set to zero (default). Workload must implement and consult its
own source of truth for the number of workers online before trying to
share GPU memory (and hence triggering IMEX interaction). When non-zero,
`numNodes` is used only for automatically updating the global
ComputeDomain `Status` (indicating `Ready` when the number of ready IMEX
daemons equals `numNodes`). In this mode, a `numNodes` value greater than
zero in particular does not gate the startup of IMEX daemons: individual
IMEX daemons are started immediately without waiting for its peers, and
any workload pod gets released right after its local IMEX daemon has
started.

With `featureGates.IMEXDaemonsWithDNSNames=false`, `numNodes` must be set
to the expected number of worker nodes joining the ComputeDomain. In that
mode, all workload pods are held back (with containers in state
`ContainerCreating`) until the underlying IMEX domain has been joined by
`numNodes` IMEX daemons. Pods from more than `numNodes` nodes trying to
join the ComputeDomain may lead to unexpected behavior.

The `numNodes` parameter is deprecated and will be removed in the next
API version.
minimum: 0
type: integer
required:
- channel
type: object
x-kubernetes-validations:
- message: A computeDomain.spec is immutable
rule: self == oldSelf
status:
description: |-
Global ComputeDomain status. Can be used to guide debugging efforts.
Workload however should not rely on inspecting this field at any point
during its lifecycle.
properties:
nodes:
items:
description: ComputeDomainNode provides information about each node
added to a ComputeDomain.
properties:
cliqueID:
type: string
index:
description: |-
The Index field is used to ensure a consistent IP-to-DNS name
mapping across all machines within an IMEX domain. Each node's index
directly determines its DNS name within a given NVLink partition
(i.e. clique). In other words, the 2-tuple of (CliqueID, Index) will
always be unique. This field is marked as optional (but not
omitempty) in order to support downgrades and avoid an API bump.
type: integer
ipAddress:
type: string
name:
type: string
status:
default: NotReady
description: |-
The Status field tracks the readiness of the IMEX daemon running on
this node. It gets switched to Ready whenever the IMEX daemon is
ready to broker GPU memory exchanges and switches to NotReady when
it is not. It is marked as optional in order to support downgrades
and avoid an API bump.
enum:
- Ready
- NotReady
type: string
required:
- cliqueID
- ipAddress
- name
type: object
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
status:
default: NotReady
enum:
- Ready
- NotReady
type: string
required:
- status
type: object
type: object
served: true
storage: true
subresources:
status: {}
40 changes: 40 additions & 0 deletions compute-domain/chart/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{{- define "computedomain.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{- define "computedomain.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}

{{- define "computedomain.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{- define "computedomain.labels" -}}
helm.sh/chart: {{ include "computedomain.chart" . }}
app.kubernetes.io/name: {{ include "computedomain.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}

{{- define "computedomain.selectorLabels" -}}
app: {{ include "computedomain.name" . }}
{{- end -}}

{{- define "computedomain.serviceAccountName" -}}
{{- include "computedomain.fullname" . -}}
{{- end -}}

{{- define "computedomain.image" -}}
{{- printf "%s:%s" .Values.image.repository .Values.image.tag -}}
{{- end -}}
Loading
Loading