Repository navigation
Release v0.4.0
NVCRE v0.4.0
The NVIDIA Cluster Readiness Engine (NVCRE) is a Kubernetes controller that certifies GPU clusters before production use. It runs real training and communication workloads across topology-aware node groups, measures goodput and bandwidth, detects hardware failures, and reports every failed node with a reason. See the README for the full feature list.
Highlights
This release makes nvcrectl setup safe alongside an existing JobSet installation, closes a release-identity gap in the signing pipeline, and ships admission-policy samples for verifying the controller image at deploy time. Nothing changed in the catalog, the controllers, or the CRD schemas.
Setup coexists with your JobSet controller (#346). nvcrectl setup init now detects who owns the JobSet CRD before touching Kubeflow Trainer. A verified external JobSet controller is reused and Trainer installs without its bundled one; a retained CRD with no controller gets the bundled controller without a schema refresh; anything ambiguous stops before any Helm mutation and prints the manual Trainer install path with --skip-phases=deps. setup reset and automatic recovery retain the shared JobSet CRD in every ownership mode, so a reset no longer destroys JobSets that belong to other workloads. A failed Trainer uninstall now stops the reset and exits non-zero instead of continuing into CRD cleanup, and --skip-phases=helm skips the Helm phase on both init and reset rather than being silently ignored.
Supply chain and release integrity. The attest self-test workflow could be dispatched at a release tag and mint the release signing identity for an arbitrary image. From this tag on, attest-selftest.yml holds its ref to main and attest.yml refuses allow_untagged on a release tag (#341). Tags v0.2.0 through v0.3.0 still carry the older workflow; the residual control is that Attest Self-Test stays disabled at the repository level, as documented in SECURITY.md. Two admission-policy samples under config/samples/policy/ require the release signature and SLSA provenance on the controller image before a Pod is admitted, one for Kyverno ImageValidatingPolicy and one for Sigstore policy-controller ClusterImagePolicy (#334). THIRD_PARTY_NOTICES.md, a signed release asset, now matches the modules compiled into nvcrectl (#363).
Docs and examples
- Runnable
CertificationandWorkloadRunmanifests underexamples/, with the commands to run them (#355) CHANGELOG.mdin Keep a Changelog format, covering every stable release (#355, #363)
Breaking changes
nvcrectl setup initandsetup resetreject unknown--skip-phasesvalues.initacceptsdepsandhelm;resetacceptscr,helm, anddeps. An invocation that passes any other name now exits with an error naming the accepted phases instead of silently ignoring it (#346). Remove the unknown names from your scripts.
Thanks to @asivanadi0, @kaynetu, @natherz97, and @ndipebot.
Install nvcrectl
The installer is signed. Download it with its bundle, verify, then run — piping it into a shell executes it before anything has checked it.
REL=https://github.com/NVIDIA/cluster-readiness-engine/releases/download/v0.4.0
curl -fsSLO "${REL}/installer"
curl -fsSLO "${REL}/installer.sigstore.json"
cosign verify-blob-attestation \
--bundle installer.sigstore.json \
--type https://slsa.dev/provenance/v1 \
--certificate-identity "https://github.com/NVIDIA/cluster-readiness-engine/.github/workflows/attest.yml@refs/tags/v0.4.0" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
installer
bash installer -v v0.4.0Without cosign
curl -fsSL https://github.com/NVIDIA/cluster-readiness-engine/releases/download/v0.4.0/installer | bash -s -- -v v0.4.0This runs the installer before anything verifies it. TLS proves you reached GitHub; it proves nothing about the asset if the release itself was tampered with. Use it only where installing cosign first is genuinely impractical.
# newest stable release; `releases/latest` never resolves to a pre-release
curl -fsSL https://github.com/NVIDIA/cluster-readiness-engine/releases/latest/download/installer | bashHelm Chart
This release's chart is published at digest sha256:f55f49639834922ce4721b3905b65ce5706c0f0276c2d1c5babc77103c0cf01f. The signature covers that digest; the version tag is mutable, so verify and install the same digest rather than verifying a digest and installing a tag.
CHART=ghcr.io/nvidia/cluster-readiness-engine
DIGEST=sha256:f55f49639834922ce4721b3905b65ce5706c0f0276c2d1c5babc77103c0cf01f
# 1. Verify the chart. Requires cosign; the package is public, so no login is needed.
cosign verify \
--certificate-identity "https://github.com/NVIDIA/cluster-readiness-engine/.github/workflows/attest.yml@refs/tags/v0.4.0" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
"${CHART}@${DIGEST}"
# 2. Pull that exact digest, then install the file you just verified.
helm pull "oci://${CHART}@${DIGEST}"
helm install nvcre ./cluster-readiness-engine@${DIGEST/:/-}.tgz \
--namespace nvcre --create-namespaceInstalling with --version v0.4.0 instead resolves the tag at install time, which is not provably the digest you verified.
helm install --verify does not check this signature. That flag looks for a PGP .prov file, a mechanism unrelated to Sigstore, and we publish no .prov files.
Controller image
A different artifact from the chart, verified separately. The release built and signed these exact digests:
| Subject | Digest |
|---|---|
| index (multi-platform) | sha256:9edcb0dcac225bd66daafb8af6e0038ab5fad950222ca5fa34ccb2c81dfd74a6 |
linux/amd64 |
sha256:2997ef1d8564185b09f85a06994ecc833c2aab0add20bd72c6fc2789d95e73e8 |
linux/arm64 |
sha256:480a4914690f217ad81c6b0fc9e85e7ba65df4af2db390c71576367d8f6366d0 |
The index carries the signature and the SLSA provenance; each platform digest carries a signature and its own CycloneDX SBOM. Pin the index digest rather than the tag:
IMAGE=ghcr.io/nvidia/cluster-readiness-engine/manager
INDEX=sha256:9edcb0dcac225bd66daafb8af6e0038ab5fad950222ca5fa34ccb2c81dfd74a6
cosign verify \
--certificate-identity "https://github.com/NVIDIA/cluster-readiness-engine/.github/workflows/attest.yml@refs/tags/v0.4.0" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
"${IMAGE}@${INDEX}"nvcrectl CLI
Download the binary for your platform from the assets below and place it on your $PATH.
| Platform | Binary |
|---|---|
| Linux amd64 | nvcrectl-linux-amd64 |
| Linux arm64 | nvcrectl-linux-arm64 |
| macOS amd64 | nvcrectl-darwin-amd64 |
| macOS arm64 (Apple Silicon) | nvcrectl-darwin-arm64 |
Verify your download
Every asset ships with a Sigstore bundle, <asset>.sigstore.json, carrying a SLSA Build Provenance v1 statement. Verify the artifact itself, not a checksum served from the same place as the artifact:
REL=https://github.com/NVIDIA/cluster-readiness-engine/releases/download/v0.4.0
ASSET=nvcrectl-linux-amd64 # or installer, or any published asset
# The bundle is a separate asset; fetch both.
curl -fsSLO "${REL}/${ASSET}"
curl -fsSLO "${REL}/${ASSET}.sigstore.json"
cosign verify-blob-attestation \
--bundle "${ASSET}.sigstore.json" \
--type https://slsa.dev/provenance/v1 \
--certificate-identity "https://github.com/NVIDIA/cluster-readiness-engine/.github/workflows/attest.yml@refs/tags/v0.4.0" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
"${ASSET}"Each nvcrectl-* binary also ships a CycloneDX SBOM, <binary>.cyclonedx.json. There are two bundles involving it, one segment apart in name, and they prove different things:
| Bundle | Proves |
|---|---|
<binary>.cyclonedx.json.sigstore.json |
the SBOM file is the one we published and was not altered |
<binary>.cyclonedx.sigstore.json |
the SBOM describes that binary — it is bound to the binary as its subject |
Before feeding an SBOM to a scanner, check both. The binding proves an SBOM describes the binary; it says nothing about the bytes of the file on your disk, which is a separate download.
cosign verify-blob-attestation \
--bundle "${ASSET}.cyclonedx.sigstore.json" \
--type cyclonedx \
--certificate-identity "https://github.com/NVIDIA/cluster-readiness-engine/.github/workflows/attest.yml@refs/tags/v0.4.0" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
"${ASSET}"
# 2. the SBOM file you downloaded is the one that was published
cosign verify-blob-attestation \
--bundle "${ASSET}.cyclonedx.json.sigstore.json" \
--type https://slsa.dev/provenance/v1 \
--certificate-identity "https://github.com/NVIDIA/cluster-readiness-engine/.github/workflows/attest.yml@refs/tags/v0.4.0" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
"${ASSET}.cyclonedx.json"Only the first would let a tampered local .cyclonedx.json reach your scanner: the binding attestation carries its own copy of the SBOM and never looks at your file.
checksums.txt is still published and still works, but it is not the verification story: it is served from the same origin as the assets and is itself unsigned, so it detects corruption rather than tampering.
sha256sum --check --ignore-missing checksums.txtThird-Party Notices
Third-party Go module licenses are listed in THIRD_PARTY_NOTICES.md and attached as a release asset.
Support
- Ask questions in GitHub Discussions.
- Report bugs with the issue templates.
- Report security issues per SECURITY.md, never through GitHub issues.
What's Changed
Documentation
Dependency Updates
- build(deps): bump the docker-images group with 2 updates by @dependabot[bot] in #360
- build(deps): bump golang.org/x/text from 0.41.0 to 0.42.0 in the go-dependencies group by @dependabot[bot] in #361
- build(deps): bump the actions group with 4 updates by @dependabot[bot] in #362
Other Changes
- chore(fern): register v0.3.0 by @github-actions[bot] in #345
- docs: propose JobSet ownership and cleanup design by @kaynetu in #336
- docs: design phase transition events in ADR-080 by @kaynetu in #338
- docs: add workload object labels ADR by @kaynetu in #337
- fix(setup): respect JobSet ownership across install, reset, and recovery by @kaynetu in #346
- fix(ci): gate attest-selftest.yml to refs/heads/main (#340) by @asivanadi0 in #341
- ci: supply-chain hardening, benchmark reporting, and expanded project docs by @ndipebot in #355
- feat: add ADR for cordoned node selection by @natherz97 in #348
- fix: address feedback for ADR 081 by @natherz97 in #356
- docs: admission-policy samples for Kyverno and Sigstore policy-controller (#272) by @asivanadi0 in #334
New Contributors
- @natherz97 made their first contribution in #348
Full Changelog: v0.3.0...v0.4.0