Automatic ComputeDomain Management (NVIDIA MNNVL)
Multi-node GPU systems connected by Multi-Node NVLink (MNNVL), such as NVIDIA
GB200 and GB300 NVL72 racks, require pods sharing GPU memory (cuda_ipc,
NCCL/NVSHMEM collectives, or NIXL NVLink KV-cache transfer) to join a shared
IMEX domain backed by an NVIDIA DRA ComputeDomain (resource.nvidia.com/v1beta1).
When the AutoComputeDomain feature gate is enabled (Alpha), LWS automatically
creates, isolates across revisions and replica restarts, injects pod DRA claims
for, and garbage-collects ComputeDomain resources at two scopes:
- Per
LeaderWorkerSetreplica (leaderworkerset.sigs.k8s.io/auto-compute-domain: "enabled"): oneComputeDomainper leader Pod, shared by the replica’s leader and worker GPU containers. A restarted or replaced group gets a newComputeDomain. - Per
DisaggregatedSetslice (disaggregatedset.x-k8s.io/auto-compute-domain: "enabled"): oneComputeDomainper active(slice, revision), shared across enrolled roles (such asprefillanddecode) within the same slice.
Prerequisites and Installation
- Kubernetes and NVIDIA DRA driver: A cluster with Dynamic Resource
Allocation (DRA) enabled and
k8s-dra-driver-gpurunning in its defaultdriverManagedIMEX mode withIMEXDaemonsWithDNSNamesenabled and servingcomputedomains.resource.nvidia.com/v1beta1. The controller manager exits at startup if the gate is enabled and this API is not served. - Helm RBAC and Feature Gate: Enable the
AutoComputeDomainfeature gate when installing LWS. The chart grants the ComputeDomain RBAC rules when either the gate orcomputeDomainManagement.enabledis set:
helm upgrade --install lws oci://registry.k8s.io/lws/charts/lws \
--namespace lws-system --create-namespace \
--set featureGates.AutoComputeDomain=true
When deploying from kustomize manifests instead of Helm, enable AutoComputeDomain: true
in the controller manager Configuration:
apiVersion: config.lws.x-k8s.io/v1
kind: Configuration
featureGates:
AutoComputeDomain: true
The default kustomize manifests do not grant ComputeDomain permissions, and
without them the ComputeDomain informer cannot sync and the controller manager
fails to start. Uncomment the config/components/computedomain component in
config/default/kustomization.yaml (or include ../components/computedomain
in your kustomization overlay) to patch manager-role with the required
resource.nvidia.com permissions:
components:
- ../components/computedomain
Note: An IMEX channel only connects GPUs within the same physical NVLink clique (typically labeled
nvidia.com/gpu.clique), andk8s-dra-driver-gpuenforces at most one activeComputeDomainper node indriverManagedmode even when a node has free GPUs. Pairauto-compute-domainwith placement constraints (such asleaderworkerset.sigs.k8s.io/exclusive-topologyorDisaggregatedSet.spec.placementPolicy) so pods sharing aComputeDomainco-locate on the same NVLink clique while separate domains (replicas, role-scoped domains, or surging revisions) land on distinct nodes. Rolling updates withmaxSurge > 0and in-place group restarts require spare clique nodes, ormaxSurge: 0drain-before-reuse when all clique nodes are occupied.
Option 1: Per-Replica ComputeDomain (LeaderWorkerSet)
Set leaderworkerset.sigs.k8s.io/auto-compute-domain: "enabled" on a
LeaderWorkerSet to allocate one isolated ComputeDomain per replica:
apiVersion: leaderworkerset.x-k8s.io/v1
kind: LeaderWorkerSet
metadata:
name: deepseek-r1
annotations:
leaderworkerset.sigs.k8s.io/auto-compute-domain: "enabled"
leaderworkerset.sigs.k8s.io/exclusive-topology: nvidia.com/gpu.clique
spec:
replicas: 2
leaderWorkerTemplate:
size: 4
workerTemplate:
spec:
containers:
- name: vllm
image: nvcr.io/nvidia/vllm:latest
resources:
limits:
nvidia.com/gpu: "4"
- name: routing-proxy
image: envoyproxy/envoy:v1.31-latest
LWS creates a dedicated ComputeDomain (numNodes: 0) for each replica and
injects the lws-compute-domain-channel ResourceClaim only into containers
requesting nvidia.com/gpu (automatically skipping CPU-only sidecars such as
routing-proxy and CPU-only leaderTemplates).
Option 2: Per-Slice ComputeDomain (DisaggregatedSet)
Set disaggregatedset.x-k8s.io/auto-compute-domain: "enabled" on a
DisaggregatedSet when roles within each slice transfer KV cache directly over
NVLink:
apiVersion: disaggregatedset.x-k8s.io/v1
kind: DisaggregatedSet
metadata:
name: llm-serving
annotations:
disaggregatedset.x-k8s.io/auto-compute-domain: "enabled"
spec:
slices: 2
placementPolicy:
type: ExclusiveSlice
topology: nvidia.com/gpu.clique
roles:
- name: prefill
spec:
replicas: 2
leaderWorkerTemplate:
size: 2
workerTemplate:
spec:
containers:
- name: prefill
image: nvcr.io/nvidia/vllm:latest
resources:
limits:
nvidia.com/gpu: "4"
- name: decode
spec:
replicas: 1
leaderWorkerTemplate:
size: 4
workerTemplate:
spec:
containers:
- name: decode
image: nvcr.io/nvidia/vllm:latest
resources:
limits:
nvidia.com/gpu: "4"
- name: encoder
metadata:
annotations:
# Opt this role out of the slice ComputeDomain
disaggregatedset.x-k8s.io/auto-compute-domain: "disabled"
spec:
replicas: 1
leaderWorkerTemplate:
size: 1
workerTemplate:
spec:
containers:
- name: encoder
image: nvcr.io/nvidia/vllm:latest
resources:
limits:
nvidia.com/gpu: "1"
Per-Role Scope Matrix in DisaggregatedSet
- Intra-role MNNVL with RDMA KV transfer: Leave
disaggregatedset.x-k8s.io/auto-compute-domainunset on theDisaggregatedSetand setleaderworkerset.sigs.k8s.io/auto-compute-domain: "enabled"on individual roles inspec.roles[i].metadata.annotations. Each role replica receives its ownComputeDomain. - Opting a role out of a slice domain: Set
disaggregatedset.x-k8s.io/auto-compute-domain: "disabled"on that role’smetadata.annotations(optionally pairing it withleaderworkerset.sigs.k8s.io/auto-compute-domain: "enabled"if the role needs its own per-replica domain instead).
Explicit Container Targeting for DRA-Allocated GPUs
By default, LWS targets containers (and restartable initContainers with
restartPolicy: Always) requesting nvidia.com/gpu > 0. When GPUs themselves
are allocated via DRA ResourceClaims rather than nvidia.com/gpu extended
resources, annotate the PodTemplateSpec with
leaderworkerset.sigs.k8s.io/compute-domain-containers:
workerTemplate:
metadata:
annotations:
leaderworkerset.sigs.k8s.io/compute-domain-containers: "vllm"
spec:
containers:
- name: vllm
image: nvcr.io/nvidia/vllm:latest
Lifecycle and Operational Behavior
- Rollouts: Setting or removing either
auto-compute-domainannotation changes the workload revision, so it triggers a rolling update of all groups. Unset and"disabled"produce the same revision, so upgrading LWS does not restart existing workloads. - Ownership and cleanup: The NVIDIA
ComputeDomaincontroller tears down the IMEXDaemonSetas soon as aComputeDomainis marked for deletion, so LWS never deletes one while a Pod references itsResourceClaimTemplate. ManagedComputeDomains therefore carry no owner reference, which would let garbage collection delete them while Pods drain. The managing workload’s UID is recorded in theleaderworkerset.sigs.k8s.io/compute-domain-owner-uidlabel instead. TheLeaderWorkerSetdeletes an obsolete replicaComputeDomainonce its leader Pod is gone and no Pod references it (group restart, rolling update, or scale-down). TheDisaggregatedSetdeletes a sliceComputeDomainonce no childLeaderWorkerSetremains for its(slice, revision)and no Pod references it. When theLeaderWorkerSetorDisaggregatedSetitself is deleted, LWS deletes itsComputeDomains once their last Pod exits. - Protection finalizer: Each managed
ComputeDomaincarries theleaderworkerset.sigs.k8s.io/compute-domain-protectionfinalizer. When aComputeDomainis deleted directly, LWS removes the finalizer only once no Pod references itsResourceClaimTemplate. - Name collisions: If a
ComputeDomainwith the generated name exists and is not managed by the same workload, LWS does not adopt it. It emits anUnexpectedComputeDomainOwnerWarning event and keeps the leader gated or the slice unscaled. - Reserved names: The
lws-compute-domain-channelclaim name and theleaderworkerset.sigs.k8s.io/compute-domain-prefixandleaderworkerset.sigs.k8s.io/compute-domain-nametemplate annotations are managed by LWS. The admission webhook rejects them in user templates. - Admission: Opting in is rejected while the feature gate is disabled or
while the
ComputeDomainAPI is not served. Objects that opted in earlier remain updatable.
Disabling the Feature Gate
With the gate disabled, LWS stops creating ComputeDomains and injecting
claims, and it no longer deletes ComputeDomains or releases the protection
finalizer. Pod templates do not change when the gate is toggled, so running
groups are not restarted.
- New Pods of opted-in
LeaderWorkerSets start without aComputeDomainclaim. - A
DisaggregatedSetenrolled in sliceComputeDomains does not create new childLeaderWorkerSets for enrolled roles (for example on scale-up or a new revision), because they would lack the claim that existing slices carry. Reconciliation reports an error until the gate is re-enabled or the annotation is removed.
Before disabling the gate, remove the auto-compute-domain annotations and wait
for the managed ComputeDomains to be deleted. Because managed ComputeDomains
have no owner reference, those of a workload deleted while the gate is disabled
are not garbage collected; delete them by hand after their Pods are gone. A
ComputeDomain that is deleted while the gate is disabled stays in
Terminating until the leaderworkerset.sigs.k8s.io/compute-domain-protection
finalizer is removed by re-enabling the gate or by hand, after its Pods are gone.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.