Upgrade from NVCF 1.0.2 or 1.0.3 to NVCF 1.0.4
Use this procedure for NVCF 1.0.2 or the docs-only 1.0.3 edition.
Single-replica Cassandra is not recommended. With one replica, the control-plane API is unavailable for ~1-2 minute while Cassandra restarts during the dependencies stage. A 10-15 minute user maintenance window is recommended for this upgrade procedure, due to required NATS, gRPC proxy and Invocation Service rollovers, which can impact in-flight invocations. HA-enabled service defaults are planned in the 1.1.0 and 1.2.0 NVCF releases which will improve upgrades.
Prerequisites
- Python 3, Helm 3.21.4, Helmfile 1.1.9,
kubectl,jq,curl, Mike Farah’syqv4, and the helm-diff plugin. - The Python
cryptographypackage, to verify JWT canary signatures against the mount’s JWKS. nvcf-cli1.16.8 or later from the NGC download instructions.- Download the NVCF 1.0.4 packaged release and manifest. Mirror the required
artifacts to your configured registry; see image mirroring.
Include both task worker images if you use tasks and the compute-plane Samba
image. The upstream supporting images
(NATS server/reloader/box and account-bootstrap/receipt helpers) need their own
mirror settings; they do not inherit
global.image. - cert-manager images default to
quay.io/jetstackand also do not inheritglobal.image. For a private mirror, set each component’simage.repository; see upstream cert-manager images. - Extract the stacks under
deploy/stacks/self-managed,deploy/stacks/nvcf-compute-planeanddeploy/stacks/observabilityin a new bundle directory.
Known issues in 1.0.2
- NVCA 3.10.0 can skip new deployments after a NATS restart. Fixed in Compute Plane 1.0.5.
- Tasks select unpublished worker images. Fixed in Self-Managed 1.0.10.
Before starting
- Back up configuration, databases and persistent volumes.
- Prepare the target environment and secrets files.
Transfer deployment settings and secrets from
environments/<name>.yamlandsecrets/<name>-secrets.yaml; keep the target chart/image versions. - Retain the compute-plane registration file and account ID. Do not run
register-clusteragain. - Locate the kubeconfig for each control-plane and compute cluster. Step 1
exports them as
CONTROL_KUBECONFIGandCOMPUTE_KUBECONFIG, and every later step uses those variables. In a new shell, export the step 1 values again before continuing. - Schedule a maintenance window based on a rehearsal of this procedure.
For older source stacks, complete the staged upgrade to Self-Managed 1.0.1 first, including its schema and data-backfill stops.
1. Set deployment values
Download these read-only scripts into one directory:
Workload readiness check Receipt check JWT mount preservation checkUse Bash with set -euo pipefail so a failed command stops the procedure.
Fill in your existing deployment values below. Each kubeconfig must already
select its intended context. For separate clusters, replace the two COMPUTE_*
values; for a single cluster, keep them equal to the control plane.
REGISTRATION_VALUES_DIR contains <cluster-name>-register-values.yaml.
Set the stack paths and define the helper used below:
2. Refresh the hostname policy
Apply this before the core stage changes the admin issuer route. Stop if the policy check fails; keep admission enabled.
Require deployed ingress and accepted routes before continuing.
Routes for disabled optional add-ons are expected to report
ResolvedRefs=False with reason BackendNotFound. For example,
llm-api-gateway reports this when the LLM add-on is disabled. This does not
block the upgrade if the route still reports Accepted=True.
3. Upgrade the existing compute plane
Apply Compute Plane 1.0.5 on each GPU cluster with its retained registration and account ID. Use a separate output directory from the registration file:
Wait for ready operator/agent pods and a healthy backend. Keep the existing Observability 1.0.0 configuration on separate compute clusters.
4. Drain pending work
Pause new production requests and task submissions. Check every affected function/version before rolling NATS or dependent services.
The checks in this step take under one minute, even for large clusters. The total drain time depends on your longest in-flight request or running task. Plan the maintenance window around that duration.
Configure CLI authentication: NVCF_API_KEY needs queue_details;
NVCF_NVCT_API_KEY needs list_tasks. Point base_nvct_url and nvct_host
at this control plane’s Tasks endpoint.
Require queue size zero for every affected queue; a missing response blocks progress. Let running tasks finish; do not discard work to clear queues.
Check single-replica memory streams on every NATS server too. Choose an unused local port for monitoring port 8222 and keep submissions paused. The temporary directory holds working files for this check and the OpenBao transition:
Require all single-replica memory streams to be present and empty. Failed reads, missing streams or nonzero counts block the rollout. If responses are paginated, retrieve every account/stream page before accepting the result. Use your configured monitoring endpoint if it differs.
Keep NATS running while work drains. For stuck deployments or retained creation
messages, follow the read-only recovery steps.
For a retry, use a new nats-drain directory; keep the OpenBao baseline.
5. Apply control-plane stages in order
Keep submissions paused. Review each Helmfile diff before confirming the apply. Wait for each stage to succeed before continuing.
OpenBao bridge before dependency migrations
The target uses chart 0.32.9, server/agent 2.6.3-nv-1.3.9 and migrations
0.19.11. The bridge retains JWT plugin v1.3.7 alongside v1.4.1.
Existing mounts keep their plugin selection; new mounts use v1.4.1.
Existing mounts receive its fixes through a separate plugin migration.
Before changing OpenBao:
- Complete the snapshot and health checks
and define
check_openbao. Require three healthy, unsealed members on the same architecture, the original Raft cluster ID and retained unseal material. The active member is the pod whosecheck_openbaooutput reportsis_self: true. - Follow the JWT preflight
to define
bao_admin. SetBAO_PODto the active member from the previous item. Use the control-planeKUBECONFIGand verify a working JWT canary. For the preflightBRIDGE_IMAGE, use the target server image from your configured registry, for examplenvcr.io/nvidia/nvcf/nvcf-openbao:2.6.3-nv-1.3.9. - Pause external mount creation and tuning. Capture the baseline once:
Stop on missing metadata or an incomplete plugin transition. The bridge hook must match the retained binary to the stored catalog SHA. On mismatch, obtain a qualified bridge with the matching binary; do not rewrite the SHA or bypass hooks.
Set bridge mode and apply only OpenBao, leaving NATS running:
Bridge mode pauses migrations and catalog refresh. OnDelete leaves server
pods on the old image until you replace them.
Follow the standby replacement and leadership transfer
for every member, one at a time. Before the next replacement, verify unsealed
health, the original cluster ID, the selected bridge digest and JWT issuance.
Update BAO_POD after leadership changes.
With OnDelete, the StatefulSet can keep reporting the old currentRevision
after every member is replaced. Confirm the rollout with updatedReplicas
equal to replicas instead:
Once all members run the bridge, check retained mount versions/SHAs and enable migrations. New mounts must use the target catalog entry:
Keep versioned mode for subsequent applies. It enables migrations and new
mounts without retuning existing ones. Verify existing and new secret consumers,
including JWT issuance and signature checks after normal failover. Retain both
binaries and catalog entries.
After a shell failure, redefine check_openbao, bao_admin and
check_upgrade_jwt_mounts, then reselect BAO_POD. Keep the original baseline.
Dependencies and migrations
Proceed only after the OpenBao checks pass. Use this staged apply instead of
the patch runbook’s whole-stack make apply:
Require successful dependency releases and migration jobs before continuing.
Core services
Require deployed releases, ready workloads and accepted routes, including any additional enabled addon namespaces.
Upgrade receipt
After all stages pass, write and check the receipt:
Require the receipt to match the selected Self-Managed version. The ConfigMap persists after the hook job expires. To correct a stale receipt, verify the installed package and workloads, then rerun that package’s receipt stage; do not patch the ConfigMap.
6. Resume workloads
Invoke an existing function with its known request and expected response:
For LLM functions, use the LLM invocation options. Check secret access, then resume submissions and monitor queue progress. Existing workers keep their images until redeployed; stack defaults apply to new workers unless their deployment specifies an image override.
Rollback boundary
Stop on failure and follow your reviewed recovery plan:
- Retain patched NVCA, target Tasks and the corrected hostname policy. Do not apply an old bundle unchanged.
- For an old core apply, exclude
ingressandnvct-apiwith--selector 'name!=ingress,name!=nvct-api' --skip-needs. Old Tasks settings restore unpublished worker images. - Keep the OpenBao bridge image and both plugins. New mounts may reference commands absent from old images; plugin rollback/cleanup belongs to the separate plugin migration procedure.
- Verify original identities, existing workloads and durable data after recovery. If you run tasks, launch a new task before ending recovery.
Application recovery does not validate server/agent downgrades or reverse stored data. Use the OpenBao recovery boundary and your datastore recovery plan for restores.