Self-Managed Clusters
Self-Managed Clusters
GPU clusters are registered with the NVCF control plane and managed by the NVCA
Operator. Use the compute-plane Makefile in
deploy/stacks/nvcf-compute-plane for this workflow. It registers one GPU
cluster at a time with nvcf-cli, then installs the operator with the cluster
identity returned by registration. The operator reads that identity from a
local ConfigMap and authenticates through the local OpenBao (Vault) instance.
A running NVCF control plane (SIS, OpenBao, NATS, Cassandra, and all core services) is required. The Quickstart can install the control plane and register a GPU cluster in one flow. Use this page when you need to install or operate the NVCA Operator after using the Helmfile installation path.
Clone the public repository and run the compute-plane commands from its root:
Prerequisites
Before installing the NVCA Operator, ensure the following prerequisites are met:
-
The control plane is installed and all core services are running.
-
The NVIDIA GPU Operator is installed on the GPU cluster. The GPU Operator manages the NVIDIA drivers, device plugin, and GPU feature discovery required for workload scheduling. For development or testing environments without physical GPUs, see fake-gpu-operator.
-
(Optional) The KAI Scheduler can be installed on the GPU cluster for optimized AI workload scheduling and bin-packing of GPU resources. It is required only when you enable the
KAISchedulerfeature flag. See NVCA Configuration. -
GPU Workload Componentsmust be available in a user-managed registry that your Kubernetes cluster can access. SeeGPU Workload Componentsunder self-hosted-artifact-manifest for necessary artifacts and self-hosted-image-mirroring for mirroring instructions. -
nvcf-cliis available on the deployment machine. The compute-plane Makefile calls it during cluster registration. See self-hosted-cli for CLI installation and configuration. -
The SMB CSI driver (
smb.csi.k8s.io) must be installed on the GPU cluster. It is required for NVCA shared model cache storage (samba sidecar). Install it with:
How It Works
In self-managed mode, the cluster identity comes from the CLI registration step, and the operator consumes it:
- You configure the compute-plane Helmfile environment with registry settings and control-plane service URLs.
- From the repository root, you run
make -C deploy/stacks/nvcf-compute-plane register-cluster(see Register the cluster). The target runsnvcf-cli init, thennvcf-cli cluster register. The CLI discovers the GPU cluster’s OIDC issuer and public JWKS, records them with the control plane (ICMS), and writes theclusterID,clusterGroupID, identity source, and service URLs to a registration values file. - From the repository root, you run
make -C deploy/stacks/nvcf-compute-plane install. Helmfile installshelm-nvca-operatorwith the compute-plane environment and registration values for that cluster. - The Helm chart renders a local ConfigMap (
nvcfbackend-self-managed) holding the cluster identity and the SIS, ReVal, and NATS endpoints (plus any host-header overrides). The operator reads that ConfigMap and creates the NVCFBackend resource. - The operator creates the NVCA agent pod. The agent authenticates to the control plane with a projected service account token (PSAT), which the control plane validates against the issuer and JWKS registered in step 1, and begins managing GPU workloads.
- Runtime secrets are injected by the OpenBao vault-agent sidecar, which authenticates using Kubernetes service account JWT tokens against the local OpenBao instance. Kubernetes image pull secrets are configured separately in the compute-plane environment and namespaces.
Configure the compute plane
Create the environment file from the repository root. It provides the chart registry, image registry, image pull secret name, and control-plane service URLs used by the NVCA operator.
Use service URLs that are reachable from the GPU cluster. For a single load-balancer-fronted Gateway with hostname-based routing, the agent should dial the load balancer address and send route-matching host headers:
If your GPU cluster can resolve per-service DNS names directly, set the service URLs to those names and omit the host-header override fields.
Host-header overrides require helm-nvca-operator 1.12.0 or later. With proper
per-service DNS and TLS (see gateway-routing), the
service hostnames resolve directly and no host-header overrides are needed.
Register the cluster
Register the GPU cluster with the control plane before installing the operator.
The nvcf-cli discovers the cluster’s OIDC issuer and JWKS and records them
with the control plane, then returns the Helm values the operator needs. See
self-hosted-cli for CLI installation and configuration, and the
Cluster Registration reference for full flag
and output details.
The control plane must expose its issuer for the CLI to discover. The Helmfile
installation path enables this with
openbao.migrations.issuerDiscovery.enabled: true.
Create a CLI config that can reach the control-plane gateway. The
register-cluster target runs nvcf-cli init before cluster register, so the
config must include the API Keys endpoint and host-header overrides:
Run registration against the GPU cluster kubeconfig. This is required for multi-cluster installs because the CLI discovers the OIDC issuer and JWKS from the target Kubernetes cluster.
The target writes
registration/<gpu-cluster-name>-register-values.yaml. It carries the cluster
identity and endpoints:
The template, install, and apply targets copy this file into out/ before
running Helmfile.
Installing the NVCA Operator
The compute-plane Helmfile passes these values to the chart:
Use global.nvcaOperator.nodeSelector, global.nvcaOperator.tolerations, and
global.nvcaOperator.agent.* in the compute-plane environment when you need to
place the operator, agent, or workloads on specific nodes.
The KAIScheduler feature flag is optional. Enable it only if the
KAI Scheduler is installed on the GPU cluster. The flag has no effect,
and GPU workload scheduling will not work as expected, if KAI Scheduler is not present. Omit
KAIScheduler from featureGateValues when KAI Scheduler is not installed.
For the full list of available feature flags and how to set or modify them, see managing-feature-flags.
Node inotify limits
The NVCA operator and agent use file watchers for ConfigMap and Secret reconciliation.
Some node images set fs.inotify.max_user_instances to 128, which can be too low for
nodes running the full NVCF stack. When the node exhausts inotify instances, NVCA logs
errors such as failed to create watcher and too many open files. Function creation
or deployment requests that wait for NVCA reconciliation can then return HTTP 500 or
time out.
Before installing the operator, set higher inotify limits on every node. The following DaemonSet sets the values on current nodes and on nodes added later:
Apply the DaemonSet and wait for it to run on every node:
If your cluster cannot pull public images, mirror busybox:1.36 and
registry.k8s.io/pause:3.9 to your registry and update the image fields before applying
the DaemonSet.
Image Pull Secrets
The NVCA operator, NVCA agent, samba sidecar, and image-credential-helper all pull container images from the registry configured in your compute-plane environment file. If that registry is private, create the Kubernetes pull secret before installing the operator.
Use a pre-existing pull secret through global.imagePullSecrets. Do not use
generateImagePullSecret; it does not work in self-managed mode.
Create the secret in the GPU cluster namespaces used by the operator and its managed resources:
Replace ${REGISTRY} with your container registry (e.g., nvcr.io). For non-NGC
registries, replace --docker-username and --docker-password with your registry
credentials. For NGC (nvcr.io), $REGISTRY_PASSWORD is your NGC Personal Key or
API Key.
Reference the secret in your compute-plane environment:
Helmfile passes this value to the operator chart. The operator adds the pull
secret reference to the pods it manages. Pre-creating the secret in
nvca-system and nvcf-backend prevents startup races for operator-managed
resources that pull private images.
Install
Install with the compute-plane Makefile. The command copies
registration/<gpu-cluster-name>-register-values.yaml into out/, then runs
Helmfile against the GPU cluster kubeconfig:
During installation, Helmfile will:
- Create the operator deployment with vault agent annotations for OpenBao auth.
- Render the
nvcfbackend-self-managedConfigMap from the register values (cluster identity, SIS/ReVal/NATS endpoints, and any host-header overrides). - Start the operator, which reads the ConfigMap and creates the NVCFBackend and NVCA agent deployment.
Verify
Check the operator pod is running. The pod runs the operator, the nvca-mirror sidecar, and
the OpenBao vault-agent sidecar (and a cluster-validator init container when network
validation is enabled):
Check the cluster identity ConfigMap was rendered from the register values:
Check the NVCFBackend resource was created:
Check the NVCA agent pod is running (the operator creates this automatically):
The NVCA agent pod has 3 containers: the agent, the admission webhook, and the OpenBao vault agent sidecar.
Both should show Running. If the vault agent sidecar is in CrashLoopBackOff, verify
that OpenBao is healthy and the migration jobs completed successfully.
Verify GPU discovery:
Verify Workload Scheduling
Use this check only when worker pods on the GPU cluster can reach the
control-plane worker endpoints used by NVCF. For multi-cluster EKS installs,
first validate the GPU cluster by checking nvca-operator rollout and
NVCFBackend agent health. Function deployment and invocation are valid
acceptance checks only after the worker endpoints are reachable from the GPU
cluster.
- Set up environment variables:
- Generate an admin token:
- Create, deploy, and invoke a test function:
The backend value should match the cluster group name registered by the NVCA operator.
The instanceType and gpu values depend on the GPU types available in your cluster.
For invocation, the Host header uses wildcard subdomain routing: <function-id>.invocation.<gateway-addr>.
The URL path should match the function’s inferenceUrl (e.g., /echo).
For full HTTP invocation behavior, streaming, and errors, see
Generic HTTP Function Invocation.
You can also use the NVCF CLI for easier function management:
- Create, deploy, and invoke functions with simple commands
- Create or update registry credentials without manual API calls
See self-hosted-cli for installation and usage instructions.
Re-registering a cluster
Registration is performed by the CLI, not by the operator. To re-register (for example, after a failed install, or to refresh the recorded issuer and JWKS), re-run the compute-plane registration target and then re-apply the operator with the refreshed values:
The registration target rewrites
registration/<gpu-cluster-name>-register-values.yaml. The install target
copies that file into out/ before running Helmfile. The operator reads the
cluster identity at startup, so re-running the install restarts it with the new
values.
Uninstalling
To fully remove the NVCA Operator and all associated resources:
If functions are currently deployed on the cluster (pods in the nvcf-backend namespace),
undeploy them through the NVCF API or CLI before uninstalling the operator. Attempting
to delete NVCA while function pods are running can cause finalizers to block namespace
deletion. If you encounter stuck resources, see [Handling Stuck Resources] below.
-
Delete the NVCFBackend resource. This triggers operator-managed cleanup of the agent deployment, NVCA system pods, and related resources:
-
Verify the agent namespace is clean before proceeding:
-
Destroy the compute-plane Helmfile release:
The cluster identity (
clusterIDandclusterGroupID) persists in the control plane (ICMS) and in your registration values file. A reinstall reuses it by re-applying that file. Pass--ignore-existingtocluster registerif you re-register. -
Delete CRDs. This removes all NVCFBackend, MiniService, and StorageRequest custom resources cluster-wide:
-
Delete namespaces:
Handling Stuck Resources
If step 1 times out and namespaces remain stuck in Terminating state, or function pods in
nvcf-backend prevent cleanup, use the force-cleanup-script. This script removes
finalizers on stuck NVCA resources, force-deletes function pods, and cleans up all NVCA
namespaces.
The force cleanup script bypasses normal cleanup procedures by removing finalizers. Always attempt the ordered uninstall steps above first.
For the full script, download link, and detailed usage instructions, see the NVCA Force Cleanup Script appendix in the self-hosted troubleshooting guide.
Troubleshooting
-
Cluster IDs empty in the ConfigMap after install: The registration values were not applied. Confirm
registration/<gpu-cluster-name>-register-values.yamlexists and that itsclusterIDandclusterGroupIDare populated, then re-runmake install: -
Operator pod not starting: Check the operator logs:
-
Operator or agent logs show
failed to create watcherwithtoo many open files: Increase the node inotify limits with thenode-inotify-tunerDaemonSet in Node inotify limits, then restart the affected pod. -
NVCA agent pod not created: The operator creates the agent pod via the NVCFBackend resource. Check the operator logs for reconciliation errors:
-
Agent fails to register with SIS (HTTP 401): The control plane could not validate the agent’s PSAT against the recorded issuer and JWKS. Re-run
make register-clusterfor the cluster (see Re-registering a cluster) so ICMS has the current issuer and JWKS. Also verify the vault agent sidecar on the agent pod is running and rendering the secrets file: -
Vault agent sidecar failing: The agent pod needs to authenticate with OpenBao. Verify the vault system is healthy:
-
No GPUs discovered: Ensure the GPU Operator is installed and GPU nodes have the
nvidia.com/gpuresource advertised: