Updates: Platform and Foundation
CloudGrange has two layers, and each has its own updates:
| Platform update | Foundation update | |
|---|---|---|
| What changes | The CloudGrange Helm release: service images, chart version and database schema | The operating system and Kubernetes under the Platform: Ubuntu packages, the K3s version, and CloudGrange's host services and configuration |
| Where it is offered | Every deployment method | Only where you used a CloudGrange installer: the VHDX appliance, the Windows script, the Linux script (and the Azure VM path). On those paths CloudGrange owns the Foundation, including operating-system updates |
| Who starts it | An administrator, in Platform → Updates | An administrator, always. Nothing in the Foundation updates by itself |
| Reboot | No | Sometimes. The portal warns you and asks you to confirm first |
| Versioning | Platform release, for example 2609.0.0 |
Its own Foundation release, for example F2609.1.0 |
| Rollback | Yes: the Helm release and the database backup taken before the update | Where possible |
The two are released, versioned and applied separately, and never bundled together. A Platform update never changes your operating system or Kubernetes, and a Foundation update never changes the Platform.
CloudGrange is in active development and is not GA. See current product and release status.
What each deployment method gets
| Deployment method | Foundation | Platform updates (in-app) | Foundation updates (in-app) | Kubernetes maintained by |
|---|---|---|---|---|
| VHDX appliance | Managed | Yes | Yes, admin-started | CloudGrange, through Foundation updates |
| Windows script (Hyper-V) | Managed | Yes | Yes, admin-started | CloudGrange, through Foundation updates |
| Linux script | Managed | Yes | Yes, admin-started | CloudGrange, through Foundation updates |
| Azure VM | Managed | Yes | Yes, admin-started | CloudGrange, through Foundation updates |
Bring your own Kubernetes (helm directly) |
Customer | Yes | No. The portal shows your Kubernetes version and whether it is supported | You |
| AKS | Azure + customer | Yes | No. As above | You, together with Azure |
| Azure Container Apps | Azure + customer | Yes | No | Azure |
Who owns what on each path is set out in Support boundary.
Platform updates
Platform → Updates shows a Platform card on every deployment method. It shows:
- the installed and available Platform versions;
- the release notes;
- Apply and Rollback buttons.
When you apply a Platform update, CloudGrange runs a short-lived updater Job inside your cluster. The Job uses a service account whose rights are limited to the CloudGrange release's own namespace. It:
- Verifies the release manifest: it must come over HTTPS from your update channel's host, its SHA-256 must match the value the channel publishes, and every image in it must be pinned by
@sha256:digest. See How updates are verified. - Backs up the database with
pg_dump. - Runs
helm upgradeto the new release's pinned chart and image versions. - Runs the health checks.
- If anything fails, runs
helm rollbackand restores the database backup.
Because the updater runs inside Kubernetes rather than on the host, the same button works the same way on K3s, on your own cluster and on AKS. On Azure Container Apps, which does not use Helm, the same button and API drive a separate executor that moves Container App revisions using a managed identity.
The Platform updater refuses an update that your current Kubernetes version cannot run. Each Platform release declares the Kubernetes range it supports.
Platform updates restart CloudGrange's services, and some take a database migration. Read the release notes for the target version first, and schedule the update for a quiet period.
How updates are verified
CloudGrange updates do not need a signing key or any manual step. An update is trusted through HTTPS and digest pinning:
- HTTPS only. The update channel, the release manifest and the chart are downloaded over
https://, with normal certificate checks, from the update channel's host.http://links, redirects tohttp://, and other hosts are refused. If you mirror releases on another host, list it inplatformUpdater.trust.allowedHosts. For a mirror with a private certificate authority, setplatformUpdater.trust.caBundle; it is added to the system CAs. - The channel pins the manifest. The update channel publishes the SHA-256 of each release manifest (
manifestSha256) and bundle (sha256). The updater refuses a manifest whose SHA-256 is different. - The manifest pins everything else. The release manifest pins the chart by SHA-256 and every image by
@sha256:digest. The updater refuses an image without a digest, andhelm upgradedeploys exactly those digests. - Signatures are optional. If you set
platformUpdater.signing.publicKey, the updater also checks the manifest's signature and refuses a missing or invalid one. If you leave it empty, which is the default, no signature is needed. - Offline bundles are trusted by the SHA-256 you confirm. When you upload an offline bundle (below), the portal shows the bundle's full SHA-256. You compare it with the
.sha256file published beside the download and confirm it; nothing is applied without that confirmation. The updater checks the file again against the value you confirmed before it unpacks anything, and then checks every pin inside it exactly as for an online update.
The update channel is the chart's api.updateChannel setting. The API and the updater both read it, so they always check the same channel.
Foundation updates follow the same rule. The bundle must come over HTTPS from the Foundation channel's host, or be an uploaded bundle whose SHA-256 you confirmed, and every file in it must match its SHA-256 in foundation-release.json.
Air-gapped (offline) updates and modules
Without internet access, the update check reports the channel as unavailable and the online module catalog is empty. The platform itself keeps working. You bring updates and modules in as offline bundles. How depends on who owns the Foundation.
Managed foundation: offline mode
This covers every CloudGrange installer when it installs from the offline payload: the VHDX appliance (always), the Windows script with -Mode Bundled, and the Linux script run from the offline bundle (it contains airgap/cloudgrange-images-amd64.tar; --offline forces the same mode). These install in offline mode, with no extra option:
- the chart runs a small in-cluster registry (
airgap.registry.enabled); - K3s is configured once, as Foundation configuration, to look for images there first:
/etc/rancher/k3s/registries.yamlmirrorsghcr.io,docker.io,quay.ioandregistry.k8s.iotohttp://127.0.0.1:30500, the registry's read-only side. Only the updater Job can write to the registry.
When the internet is reachable, containerd falls back to the public registries, so online updates keep working too.
Update the Platform offline
- On a connected machine, download
cloudgrange-platform-<version>.zipandcloudgrange-platform-<version>.zip.sha256from the CloudGrange download site, next to the release's other downloads (releases/<version>/). The zip is larger than GitHub allows for a release asset, so it is not on the GitHub release page. - Carry the zip into the isolated network.
- In Platform → Updates, on the Platform card, choose Upload offline update and select the zip. The card shows the upload's progress, then the version the bundle contains and its full SHA-256.
- Compare that SHA-256 with the one in the
.sha256file. If they match, tick I compared this SHA-256 and choose Install <version>.
When you install, the updater Job:
- Checks that the zip still has exactly the SHA-256 you confirmed.
- Checks the bundle's
images.txtagainst theimages.sha256pinned in itsmanifest.json, the chart against its SHA-256, and every first-party image against its digest. - Checks that every image the new chart uses is in the bundle.
- Pushes the images into the in-cluster registry, and checks each pushed image against its pinned digest.
- Backs up the database, runs
helm upgrade, and runs the health checks. - If anything fails, runs
helm rollbackand restores the database backup.
If any check in steps 1–4 fails, nothing is changed. Rollback works the same way as for an online update, with no network.
A Platform bundle also carries a snapshot of the module catalog and the module images. After the update, those modules appear in Platform → Modules and install as usual.
Limits and storage:
- The largest upload is 8 GiB by default (
api.platformBundles.maxBytes). - Bundles are stored on the PVC
<release>-platform-bundles, one of each kind at a time. A new upload replaces the previous one. - The 5 GB free-space check before an update still applies.
- Uploads go straight to the API, not through the portal's proxy, because they can be several GB.
Add or update modules offline
To bring in modules between Platform releases, use a module bundle (cloudgrange-modules-<name>.zip, built with scripts/release/New-ModuleBundle.sh):
- In Platform → Modules, under Offline modules, choose Upload and select the zip.
- Compare the SHA-256 shown with the published one, confirm it, and choose Import.
The updater Job checks the SHA-256, loads the module images into the in-cluster registry and publishes the bundle's catalog. The modules then appear in the catalog and install, open and update exactly as online.
Update the Foundation offline
On the Foundation card, choose Upload offline Foundation and select cloudgrange-foundation-<version>.zip. The card shows its version, its K3s version, whether it restarts the host, and its full SHA-256. Compare and confirm the SHA-256 (and the reboot, if needed), then apply it. The host's Foundation updater checks the SHA-256 you confirmed and every file in the bundle. A Foundation bundle carries K3s and CloudGrange's host files; operating-system packages need the Ubuntu archive or your own mirror, so an offline Foundation release that pins Ubuntu packages cannot install them without one.
Customer foundation (your own Kubernetes, AKS): mirror the images
On a cluster CloudGrange did not provision, you mirror our pinned images into your own registry and set global.imageRegistry. Every image then comes from your mirror, including the Platform updater Job's image. Each release publishes images.txt on the download site (releases/<version>/images.txt), the list to mirror, including the module images. See Air-gapped clusters for the procedure. To update, mirror the new release's images, then use the Platform card as online, or helm upgrade directly.
Command line and API
The same Platform update is available from the cg CLI and the PowerShell module:
cg platform update check # is a Platform update available?
cg platform update apply # apply it
cg platform update --rollback # roll back to the previous version
The API separates the two layers:
| Endpoint | Purpose |
|---|---|
GET /api/v1/platform/updates/environment |
Whether the Foundation is managed, the detected Kubernetes version, the supported range, and whether the cluster is in range |
GET /api/v1/platform/updates/platform |
Installed and available Platform versions, and the current update status |
POST /api/v1/platform/updates/platform/apply, .../platform/rollback |
Apply or roll back a Platform update. With {version, bundleId, sha256}, apply an uploaded offline bundle |
POST /api/v1/platform/updates/platform/upload |
Upload an offline Platform bundle (raw zip). Returns its bundleId and sha256 |
GET /api/v1/modules/offline, POST .../upload, POST .../import |
Offline module bundles: status, upload, and import with {bundleId, sha256} |
POST /api/v1/platform/updates/foundation/upload |
Upload an offline Foundation bundle (managed foundations only) |
GET /api/v1/platform/updates/foundation |
Foundation status. Returns 404 on a customer foundation |
POST /api/v1/platform/updates/foundation/apply, .../foundation/rollback |
Apply or roll back a Foundation update. Apply returns 400 if a reboot is needed and confirmReboot is not true |
See the REST API reference.
Foundation updates
A Foundation card appears in Platform → Updates whenever you installed with a CloudGrange installer: the VHDX appliance, the Windows script or the Linux script (and the Azure VM path). If you ran any of these, CloudGrange owns the Foundation, including the operating system and its updates, and delivers those updates through this card. The installer marks the deployment as managed (foundation.managed=true). When you install the chart with helm directly on your own cluster, or run on AKS or Azure Container Apps, there is no Foundation card.
A Foundation update covers:
- Ubuntu packages, either at the versions the Foundation release names or the security updates available now — see what the OS update numbers mean;
- the K3s version, pinned by the Foundation release;
- CloudGrange's host services and configuration.
How Foundation updates behave:
- An administrator always starts them. Nothing in the Foundation updates automatically, not even operating-system security patches. The portal shows what is available, and nothing is applied until an administrator clicks Apply. Ubuntu's automatic
unattended-upgradesstays disabled, and K3s is never upgraded by a background controller. - You see exactly what will change first. Before you confirm, the card lists the exact packages and the K3s version the update will change, and whether a reboot is needed. If it needs a reboot, you must confirm that too. The Platform is unavailable while the host restarts.
- They are released separately. A Foundation release is versioned on its own, for example
F2609.1.0, and pinned by the SHA-256 its channel publishes (a signature is optional; see How updates are verified). It declares its K3s version and the range of Platform versions it supports. - They are checked for compatibility. CloudGrange refuses a Foundation update that would move Kubernetes outside the range your installed Platform supports.
The Foundation card shows the installed and available Foundation versions, the current and target K3s versions, the operating-system updates grouped as below, whether a reboot is required, the release notes, and Apply and Rollback buttons.
What the OS update numbers mean
A Foundation release installs only the package set that release names. So the number of packages Ubuntu could upgrade on the host is not the number Apply will change. Rather than show a total you cannot act on, the card puts every upgradable package in exactly one group and tells you what to do about each. Expand a group to see the packages, each with its installed and offered version and the reason it is in that group.
| Group | What it means | What you do |
|---|---|---|
Included in Foundation <version> |
The available Foundation release installs this package when you press Apply — either because the release pins that exact version, or because the release takes all Ubuntu security updates. | Press Apply. The confirm dialog lists these packages before you commit. |
| Not yet released | The package is upgradable on this host, but no published Foundation release covers it. This is the normal state between releases: Ubuntu publishes continuously, CloudGrange releases in batches. | Nothing. There is no button, and that is correct. A future Foundation release will cover it. |
| Not managed by CloudGrange | The package is outside this Foundation's managed set, listed in /etc/cloudgrange/foundation-unmanaged.conf on the host. No Foundation release will change it, even one that takes all security updates or names the package explicitly — your exclusion wins, and the update's result says what it left alone. |
Update it the way you update the rest of this host. CloudGrange does not. |
Two details worth knowing:
- A package the release pins at an older version than the one your host is offered is shown as not yet released, and the reason names both versions. Applying the release still installs the pinned version, but the newer one remains available afterwards — so calling it "included" would be misleading.
- The not managed group is empty on the appliance and Windows-script foundations: those are dedicated hosts, and every package on them is CloudGrange's. It exists for the Linux-script path, where you may run your own agents on the host. Create
/etc/cloudgrange/foundation-unmanaged.confwith one package-name glob per line (#starts a comment) to keep those out of Foundation releases. - The counts come from the last Check for updates. Until a check has run, the card says the groups are not known yet rather than showing a number without an explanation.
On managed foundations, a host service (cloudgrange-updater-k3s.service) carries out Foundation updates. It runs only when an administrator asks. It has no timers that apply anything, and it no longer applies Platform updates.
Customer foundations: your own Kubernetes (helm directly) and AKS
When you install the chart with helm directly on your own cluster, you maintain Kubernetes. On AKS you share this with Azure. That covers its version, its nodes and their operating system, the ingress controller, storage and cert-manager. CloudGrange never changes them.
Platform → Updates shows:
- the Platform card, with in-app Platform updates exactly as above;
- the Kubernetes version it detected, the supported range for the installed Platform, and whether your cluster is in range.
Before you upgrade Kubernetes, check that the new version is inside the supported range of your installed Platform. If it is not, update the Platform first. If your cluster is out of range, the portal warns you and the Platform updater refuses updates your cluster cannot run.
One case an in-app update hands back to you
The in-cluster updater runs under a ServiceAccount whose rights stop at the release namespace, and it cannot grant itself more — granting RBAC requires already holding what you grant. So a chart version that adds, changes or removes a cluster-scoped object (a ClusterRole, a ClusterRoleBinding, a ClusterIssuer) cannot be applied in-app.
The updater checks this before it touches anything — before the database backup and before helm upgrade — so a release it cannot apply is refused with nothing changed and no rollback. Platform → Updates then shows the exact command to run, for example:
Platform
<version>changes cluster-scoped objects the in-cluster updater is not allowed to change: create ClusterRole/<release>-platform-updater (cluster-scoped). … this one update has to be applied once by a cluster administrator …
Run that helm upgrade yourself with a cluster-admin kubeconfig (the command is in the message and under Updating with Helm directly), and in-app updates resume from the next release. On the current chart's defaults there is nothing cluster-scoped for an update to trip over, so this should not come up; see In-app Platform updates on your cluster.
Updating with Helm directly
You can always apply a Platform release with Helm instead of the portal, for example from a pipeline. Pin the chart version and the image tag:
helm upgrade cloudgrange oci://ghcr.io/cloudgrange/charts/cloudgrange \
--version <new-version> --namespace <namespace> --reset-then-reuse-values \
--set global.image.tag=<new-version> --wait --timeout 10m
On the managed-foundation paths the release is in the default namespace and Helm needs the K3s kubeconfig:
sudo KUBECONFIG=/etc/rancher/k3s/k3s.yaml helm upgrade cloudgrange \
oci://ghcr.io/cloudgrange/charts/cloudgrange --version <new-version> \
--reset-then-reuse-values --set global.image.tag=<new-version> --wait --timeout 10m
Always
--reset-then-reuse-values, never--reuse-values.--reuse-valueskeeps the previous release's values verbatim and therefore drops every default the new chart adds. That is what broke the in-app updates to2609.0.0-preview.18and.19(nil pointer evaluating interface {}.registry).--reset-then-reuse-values(Helm 3.14 and later) resets to the new chart's defaults and re-applies only the values you supplied; it is the flag the in-cluster updater uses. Re-passing your full values file with-fis equally correct.
Roll back with helm rollback cloudgrange, and list earlier revisions with helm history cloudgrange. A Helm rollback does not restore the database. The in-app Platform update takes and restores a database backup for you.
Never deploy the latest image tag. Every release pins its own versions.
Legacy Docker Compose installs
Installs on the retired Docker Compose engine (up to 2609.0.0-preview.4) keep their original Compose-era updater, under Platform Management → Platform Updates. They do not get the two-layer Platform and Foundation update model.