Upgrading
Standard upgrade
Check the Behavior changes index and the per-version section for any release between your current version and the target. These flag breaking changes, new values, and potential issues to address before running the recipe below.
Apply the updated CRDs before upgrading the Helm releases; Helm does not upgrade CRDs automatically:
helm show crds oci://ghcr.io/cosmonic/cosmonic-control --version 0.11.0 | kubectl apply -f -Then upgrade the control plane with the same values file used during installation:
# Check the currently installed release and chart version
helm list -n cosmonic-system
# Upgrade to a new chart version
helm upgrade cosmonic-control oci://ghcr.io/cosmonic/cosmonic-control \
--version 0.12.1 \
--namespace cosmonic-system \
-f cosmonic-control-values.yamlUpgrade the HostGroup release separately, reusing the same HostGroup values file you installed with — a bare helm upgrade with no -f resets the release to chart defaults and drops your hostPlugins (including the wasmcloud:nats grants), resources sizing, and any egressPolicy/caBundle/TLS settings:
helm upgrade hostgroup oci://ghcr.io/cosmonic/cosmonic-control-hostgroup \
--version 0.12.1 \
--namespace cosmonic-system \
-f hostgroup-values.yamlWait for the rollout to complete before considering the upgrade done:
kubectl rollout status deploy -l app.kubernetes.io/instance=cosmonic-control -n cosmonic-system
kubectl rollout status deploy -l app.kubernetes.io/instance=hostgroup -n cosmonic-systemChart versions do not track appVersion one-to-one. A single chart version (e.g. 0.4.1) may ship updated appVersion values as underlying Cosmonic Control images are patched. Check the current appVersion before upgrading:
helm show chart oci://ghcr.io/cosmonic/cosmonic-control --version 0.12.1Rolling back
Rolling back the Helm release
To roll back to the previous release after a failed upgrade:
helm rollback cosmonic-control -n cosmonic-system
helm rollback hostgroup -n cosmonic-systemhelm rollback restores the Helm release to its previous revision. Check the rollback status:
kubectl rollout status deploy -l app.kubernetes.io/instance=cosmonic-control -n cosmonic-system
kubectl rollout status deploy -l app.kubernetes.io/instance=hostgroup -n cosmonic-systemCRD rollback caveat
Helm does not downgrade CRDs on rollback — by design, to prevent accidental data loss. If the failed upgrade included CRD changes, rolling back the Helm release will leave the newer CRD versions in place.
If you need to roll CRDs back to a previous version, apply the old CRD manifests manually:
# Pull CRDs from the target (older) chart version
helm show crds oci://ghcr.io/cosmonic/cosmonic-control --version <previous-version> | kubectl apply -f -Verify the CRDs were restored before proceeding:
kubectl get crd | grep -E 'cosmonic|wasmcloud'Behavior changes since v0.4.0
A scan of operator-visible changes by release. Each entry links to the upgrade section below where the change is explained in full. Releases not listed here ship only dependency bumps and internal fixes; see cosmonic/control releases for those.
| Version | Change | Action |
|---|---|---|
| v0.11.0 | Socket egress policy (egressPolicy), shipped in preview count mode | None on upgrade — nothing is enforced until you set socketEgress: enforce; plan the count→enforce rollout (and denySpecialRanges for the metadata endpoint) then |
| v0.11.0 | Chart-wide image registry override (global.image.registry); Traefik and its busybox init are now mirrored | Air-gapped/mirrored installs: remove any per-component registry: ghcr.io so the global applies, and mirror the new traefik/busybox tags |
| v0.11.0 | imagePullSecrets now attached to Traefik and the HostGroup pod | None unless your registry needs auth — then set global.image.pullSecrets |
| v0.11.0 | Host OCI registry controls (ociRegistry: allowInsecure, pullTimeout, cacheDir) | None; opt-in |
| v0.11.0 | Connection quotas (connectionQuotas) | None; the host derives a ceiling from its descriptor budget. Watch /readyz for http_ingress_saturated |
| v0.11.0 | TLS for the NATS connections (nexus.tls / dataNats.tls) | None; opt-in for an external or managed NATS |
| v0.11.0 | Native cosmonic:kafka host plugin | Configure on the HostGroup to grant workloads Kafka |
| v0.9.3 | CA-bundle trust extended to component egress (caBundle.egress) | None unless components call a service behind a private CA |
| v0.9.3 | wasmtime 47.0.4 security update (RUSTSEC-2026-0268/0269) | None — security patch, applied on chart bump |
| v0.9.3 | HostGroup memory defaults raised; new hostMemory knobs | Review sizing before upgrade; the larger default request can leave host pods Pending |
| v0.9.3 | Host health-probe listener (/livez, /readyz on 9192) | None needed; set health.enabled: false to disable |
| v0.9.3 | caBundle now trusts a private CA for image pulls | None unless pulling from a registry behind a private CA |
| v0.9.3 | wasmcloud:nats host plugin (core, JetStream, KV) | Configure on the HostGroup to grant workloads NATS access |
| v0.9.3 | Warm-pool idle reclaim (reclaimWindowSeconds, reclaimMinInstances) | None needed; additive and opt-in per component |
| v0.9.2 | control-host image is now a glibc build (unblocks GPU and native host plugins) | None — a host group picks it up on chart bump; only matters if you run the host on a custom base (needs glibc ≥ 2.34) |
| v0.7.0 | Default resource requests and limits on every pod | Review sizing after upgrade; raise or remove limits that don't fit your cluster |
| v0.7.0 | Hardened pod and container securityContexts by default | None unless a container must write outside its mounted volumes |
| v0.7.0 | Baseline NetworkPolicies (networkPolicy.enabled, on by default) | Set networkPolicy.enabled: false if a service mesh manages network policy |
| v0.7.0 | Named host interfaces and hostInterfaces admission validation | Deduplicate hostInterfaces entries that share a namespace:package before re-applying manifests |
| v0.6.x and earlier | Nexus StatefulSet PVC migration, Traefik-as-default ingress, Console/Cloud removal, CA bundle, unpinned trigger environment | Prefer a fresh install of the current chart; upgrading in place, migrate the nexus-data PVC and drop removed values |
Upgrading from v0.6.x or earlier
These are large jumps to the current chart, and each intervening release carried its own CRD and values changes. For a gap this size, a fresh install of the current chart is usually simpler than an in-place upgrade; the cosmonic/control release notes carry the per-version detail. If you do upgrade in place, apply the current CRDs first (see Standard upgrade) and account for the load-bearing changes from that era:
- Nexus persistence moved to a StatefulSet (v0.6.0). The
nexus.persistence.existingClaimvalue was removed. Migrate any pre-v0.6.0nexus-dataPVC ontodata-nexus-0before upgrading, or you lose durablewasi:keyvalueand Artifact JetStream state. Nexus also gained HA throughnexus.replicas(an odd number, for RAFT quorum). - Traefik became the default ingress (v0.4.0 and v0.4.1). Set
ingress.provider: istioif you rely on Istio, oringress.enabled: falseto expose Envoy directly. - Console and Cloud components were removed (v0.4.0). Delete any
console:andconsole_ui:blocks from your values. - CA bundle support was added (v0.5.0, opt-in), and
HTTPTrigger.spec.environmentbecame unpinned by default (v0.5.2); setenvironmentexplicitly on triggers that must stay on a tenant-scoped host group.
Then follow the v0.6.1 to v0.7.0 section below, which establishes the current baseline: default resource requests and limits, hardened pod securityContexts, baseline NetworkPolicies, and hostInterfaces admission validation.
Upgrading from v0.6.1 to v0.7.0
Chart 0.7.0 ships appVersion 0.7.0 and bumps the control-host image to wasmCloud v2.5.1. The release hardens every pod both charts deploy — securityContexts, resource limits, probes, and NetworkPolicies are now on by default — and adds admission-time validation plus named routing to hostInterfaces. All of the hardening is overridable through values, but an upgrade of an existing release changes running pods, so review the sections below before running helm upgrade.
Apply the updated CRDs
helm show crds oci://ghcr.io/cosmonic/cosmonic-control --version 0.7.0 | kubectl apply -f -The v0.7.0 CRDs add size bounds on hostInterfaces (at most 64 entries; name and version capped at 64 characters, namespace and package at 128) and two admission rules, enforced via CEL validation on create and update:
- No two entries may be exact duplicates — the same
namespace,package,name, andversion. - At most one entry of a given
namespace:packagemay be unnamed. The unnamed entry is the default route and cannot be shared; give additional entries of the same package distinctnames.
Validation runs at admission, so objects already stored in the cluster are untouched until their next update. Audit any manifests that declare multiple hostInterfaces entries for the same namespace:package before re-applying them — entries that violate either rule are rejected with a descriptive error.
Named host interfaces and hostInterfaces admission validation
The name field on a hostInterfaces entry (present since v0.4.1) is now a routing identity end to end: the wasmCloud v2.5.1 host routes a component's named (implements <name>) imports by it, so a workload can import the same namespace:package more than once and resolve each import to a differently configured backend. Entries that share a namespace, package, and name with semver-compatible versions merge to the highest version, per the component model's canonical-version rules; semver-incompatible versions of the same package coexist as distinct interfaces.
See Named host interfaces for the manifest shape and a worked example.
Pods now ship default resource requests and limits
Every resources block in both charts previously defaulted to {} — pods ran unconstrained unless your values file said otherwise. As of v0.7.0, every container ships a memory request and limit plus a CPU request. CPU is deliberately request-only: a CPU limit only throttles, so none is set.
Upgrading an existing release imposes these limits on all pods. The defaults are sized conservatively for a small cluster; components under real load may need more:
operator.resources— the informer cache grows with the number of watched objects (Hosts, Workloads, Pods, EndpointSlices). Raise the192Midefault limit for large clusters.prometheus.resources— TSDB memory scales with active series; the default limit is512Mi.- HostGroup
resources— host pods run Wasm components in-process, so memory scales with the workloads scheduled onto each host. Sizelimits.memory(default512Mi) for your expected per-host workload density, or remove the limit to leave host memory uncapped.
Values you already set win over the new defaults. After upgrading, watch for OOMKilled restarts (kubectl get pods -n cosmonic-system will show them) and raise the affected component's limit. See Resource sizing.
Pods are hardened by default
Every container in both charts now runs with a hardened securityContext: runAsNonRoot (UID 65532 for first-party images, 10001 for bundled third-party images), the RuntimeDefault seccomp profile, all capabilities dropped, privilege escalation disabled, and readOnlyRootFilesystem with writable emptyDir volumes mounted where a process legitimately writes (a universal /tmp, the host's HOME, Prometheus's TSDB, Tempo's trace store). Liveness and readiness probes now cover every container, and automountServiceAccountToken is disabled everywhere the Kubernetes API isn't used — it stays on only for the operator, the Perses provisioning sidecar, and Traefik.
Stock installs need no changes. Override any field via values if an extension writes outside its mounted volumes — for example, a HostGroup plugin that writes to the container filesystem:
# hostgroup-values.yaml
securityContext:
readOnlyRootFilesystem: falseBaseline NetworkPolicies
Both charts gain a networkPolicy.enabled value, on by default. Each enabled component gets a NetworkPolicy whose podSelector matches its pods, restricting ingress to the ports the component actually serves. Egress is intentionally left unrestricted — the operator talks to the Kubernetes API, hosts pull OCI images from arbitrary registries, and components export telemetry to one another — so tightening egress is left to environment-specific policy.
On a CNI without NetworkPolicy support the objects are inert. Set networkPolicy.enabled: false in either chart's values if a service mesh or cluster-level policy engine manages this instead.
With the values file updated and CRDs applied, run the Standard upgrade flow with --version 0.7.0.
Upgrading from v0.9.1 to v0.9.2
Chart 0.9.2 ships appVersion 0.9.2. This is a low-risk patch: there are no CRD or values changes, so stock installs upgrade with the Standard upgrade flow and --version 0.9.2. One behavior change is worth knowing.
This guide documents upgrades through v0.7.0 and then v0.9.2 through v0.11.0. If you are coming from v0.8.x, v0.9.0, or v0.9.1, review the cosmonic/control release notes for changes in those releases.
The control-host image is now a glibc build
The control-host release image is now built against glibc (floor 2.34) rather than statically against musl. A static musl build's dlopen is a stub that always fails, which blocked the GPU release image and any host component plugin that loads a native library at runtime. On glibc those load correctly, and this release also unblocks the GPU-enabled control-host image and corrects Perses dashboard routing in the observability stack.
The published image runs on any glibc ≥ 2.34 base (Ubuntu 22.04 and newer), and a host group picks it up automatically when you bump the chart version. This floor matters only if you build or run the host on your own base image, which must then meet it.
Run the Standard upgrade flow with --version 0.9.2.
Upgrading from v0.9.2 to v0.9.3
Chart 0.9.3 ships appVersion 0.9.3 and pins the control-host wash-runtime past wasmCloud v2.8.0 to a revision on main that backs the new native wasmcloud:nats host plugin. This release changes the HostGroup memory defaults, adds a host health-probe listener, extends CA-bundle trust to image pulls, and adds two optional CRD fields. Stock installs upgrade with the Standard upgrade flow and --version 0.9.3, but the memory defaults change what the scheduler places, so review the sections below before running helm upgrade on an install that relies on the chart defaults.
Apply the updated CRDs
helm show crds oci://ghcr.io/cosmonic/cosmonic-control --version 0.9.3 | kubectl apply -f -The v0.9.3 CRDs add two optional fields to a Workload component's warm instance pool: reclaimWindowSeconds (how long the pool watches its own peak concurrency before retiring the warm instances that peak did not need) and reclaimMinInstances (a floor an idle sweep never retires below). Both are additive and preserve today's behavior (a pool that sets neither never reclaims warm instances for idleness), so existing Workloads are untouched until you opt in. See warm instance pools.
HostGroup memory defaults changed
The HostGroup chart now sizes host memory explicitly, and the defaults are larger than before. resources.requests.memory moves from 64Mi to 768Mi and resources.limits.memory from 512Mi to 6Gi, and a new hostMemory block governs how much of the pod the host hands to Wasm guests:
hostMemory.maxGuestMemory: total guest memory the host may hand out. Unset, the host derives it as three-quarters ofresources.limits.memory, so under Kubernetes it tracks the pod automatically; set it only to override.hostMemory.defaultHeapMemory(the chart ships1Gi): the ceiling on any single guest's linear memory, so one runaway component cannot exhaust the pod. Clear this value and the host falls back to wasmtime's 4GiB default, which exceeds the guest budget and makes the host warn at every start. Raising it is safe; lowering it is the change that needs testing.hostMemory.coreInstances: instance slots the pooling allocator keeps (wasmtime's default is 1000). Multiplied bydefaultHeapMemorythis is the pool's virtual reservation, mappedPROT_NONEand committed only as guests touch it, so the node needs nowhere near it and the pod's accounted memory is unaffected.
The host takes three-quarters of resources.limits.memory as its guest budget, reports the resolved numbers at startup (host memory resolved), and warns when defaultHeapMemory does not fit inside it. Because requests.memory is what the scheduler places on, the larger default request means an existing install that keeps the chart defaults will have its host pods request 768Mi and may reschedule onto nodes that can back it. Values you already set win over the new defaults, so an install that had sized resources for its workload density keeps those. Set hostMemory.defaultHeapMemory to fit within that guest budget. After upgrading, check for host pods stuck Pending (kubectl get pods -n cosmonic-system): a Pending host means its larger memory request does not fit the node, so lower resources.requests.memory to suit. The chart's values.yaml documents small/medium/large sizings; see also Resource sizing.
Host health-probe listener
The HostGroup gains a plaintext health listener, on by default, serving /livez and /readyz for the kubelet's liveness and readiness probes:
# hostgroup-values.yaml
health:
enabled: true
port: 9192It is deliberately separate from the workload HTTP ingress, so probes never traverse TLS and a host with no ingress is still probed. Stock installs need no changes; set health.enabled: false only if the listener conflicts with your environment.
CA bundles now apply to image pulls
caBundle previously mounted your extra CA certificates over the container trust store, but the host's OCI client never read that store, so image pulls from a private registry fronted by an internal CA still failed. As of v0.9.3, enabling caBundle also passes --oci-ca-path to the host, so those CAs are honored for every image the host pulls: workload components and host component plugins alike. If you run a private registry with an internal CA, set caBundle.enabled: true and supply the bundle through caBundle.contents (or caBundle.mountPath); no other change is needed.
The wasmcloud:nats host plugin
This release adds a native wasmcloud:nats host plugin (NATS core pub/sub, JetStream, and KV) configured on the HostGroup with deny-by-default subject, stream, and bucket grants and per-binding overrides. It is operator-configured through hostPlugins and requires no new CRD. See The wasmcloud:nats host plugin.
Observability: the Envoy dashboard now populates
This release also fixes the bundled Envoy dashboard in the observability stack: the metrics collector can now reach the Envoy admin endpoint, so the dashboard renders data instead of coming up empty. No action is required, the dashboard definitions themselves are unchanged, and the fix applies on chart bump.
With the values file updated and CRDs applied, run the Standard upgrade flow with --version 0.9.3.
Upgrading from v0.9.3 to v0.10.0
Chart 0.10.0 is a small mainline release. Its two operator-relevant changes (component-egress CA trust and the wasmtime 47.0.4 security fix) were also backported to the release-0.9 line in v0.9.3, so an install already on v0.9.3 gains nothing new here. Both are documented below for anyone upgrading from v0.9.2 or earlier, and this release makes no CRD changes.
CA-bundle trust for component egress
v0.9.3 extended caBundle to the host's image pulls. That same release, and v0.10.0 on mainline, extend it one step further, to the outbound HTTPS that components make (wasi:http). That egress uses a trust store separate from both the OCI client and the container's system store, so enabling caBundle alone does not cover it: a component calling a service behind your private CA still fails its TLS handshake with InvalidCertificate(UnknownIssuer) until you opt in.
# hostgroup-values.yaml
caBundle:
enabled: true
contents: "" # or existingConfigMap / existingSecret
egress:
enabled: true # also trust the mounted bundle for component wasi:http
trustRoots: "" # webpki (default) | webpki-and-native | native | extra-onlytrustRoots: extra-only trusts exactly the mounted bundle and nothing else; the default (webpki) layers your bundle under the compiled-in public roots. This is additive and off by default, so existing installs render the same egress trust as before.
wasmtime security update
The control-host runtime moves to wasmtime 47.0.4, picking up the fixes for RUSTSEC-2026-0268 and RUSTSEC-2026-0269. It reached both the release-0.9 line (v0.9.3) and mainline (v0.10.0); no configuration change, and the fix applies when you bump the chart.
Run the Standard upgrade flow with --version 0.10.0.
Upgrading from v0.10.0 to v0.11.0
Chart 0.11.0 ships appVersion 0.11.0 and bumps the control-host runtime to the latest wasmCloud. It adds a set of host security and air-gap controls (a raw-socket egress policy, connection quotas, OCI-registry settings, and NATS TLS), makes the chart's image-registry override work across every component, and adds a native Kafka host plugin. Most of it is opt-in. The change that can surprise an existing air-gapped install is the image-registry override, so review that section before running helm upgrade; the new egress policy ships in preview (count) mode and severs nothing until you enforce it.
Apply the updated CRDs
v0.11.0 makes no CRD schema changes; re-applying is a safe no-op, kept in the flow for consistency.
helm show crds oci://ghcr.io/cosmonic/cosmonic-control --version 0.11.0 | kubectl apply -f -Socket egress policy
The host now evaluates a policy on every raw-socket (wasi:sockets) connection a workload or host plugin opens, configured through a new egressPolicy block on the HostGroup. Two parts of it are on by default and change behavior on upgrade; the allowlist-enforcement part is deliberately not.
# hostgroup-values.yaml
egressPolicy:
socketEgress: "" # "" = host default (count) | count | enforce
denySpecialRanges: "" # on unless set to false
denyPrivateRanges: "" # off unless set to true
allowHostLoopback: "" # off unless set to true- The policy ships in
countmode, so nothing is severed on upgrade. WithsocketEgressunset (the default,count), the host evaluates the whole policy (the per-workloadallowedHostsallowlist and the range denials below), logs each connection it would refuse (socket egress policy would refuse this connection, at debug level), and allows it anyway. Onlyenforceactually refuses. Roll it out gradually: run atRUST_LOG=debugfor a representative period, confirm nothing legitimate appears in the would-refuse log, then setsocketEgress: enforce. Underenforce, ahostPluginsentry that declares noallowedHostshas an empty allowlist and is denied every raw-socket connect, so check each plugin'sallowedHostsfirst.wasi:httpegress is gated byallowedHostsregardless of this setting. denySpecialRangesis on by default within the policy. Once youenforce, raw-socket connections to loopback, link-local (including the cloud metadata address169.254.169.254), unspecified, multicast, and documentation ranges are refused. If a workload legitimately reaches the instance metadata endpoint over a raw socket (for example, for cloud IAM credentials), setdenySpecialRanges: falsebefore flipping toenforce; thecount-period debug log will show those169.254.169.254hits so you can decide. Leaving it on is the safer default, since it closes the SSRF-to-metadata path.denyPrivateRanges(private IPv4/IPv6 and carrier-grade NAT ranges: RFC1918, ULA, CGNAT) is off by default, because reaching a sibling service on a cluster-private address is the ordinary in-cluster case.allowHostLoopbacklets workloads reach the pod's own loopback viahost.wasmcloud.internal, and additionally requires the workload's ownallowedHostLoopbackPortsentry, so neither operator nor author can open it alone.
Connection quotas
A new connectionQuotas block bounds how many concurrent network connections the host lets its workloads hold (pooled outbound HTTP, raw wasi:sockets, and inbound published ports), rolling up into a host-wide ceiling.
# hostgroup-values.yaml
connectionQuotas:
maxConnections: "" # host-wide ceiling; unset derives from RLIMIT_NOFILEThese are bounds, not reservations: nothing is preallocated, so a generous number costs nothing until connections open. Left unset, the host derives the ceiling from its own RLIMIT_NOFILE (half of it, clamped to 64–32768), which tracks the container's real descriptor budget better than the chart can, so most installs should leave it empty. The host reports the resolved numbers at startup (connection quotas resolved), and a host that runs out of inbound slots reports http_ingress_saturated on /readyz rather than pushing the failure onto image pulls.
Host OCI registry controls
A new ociRegistry block governs how the host pulls workload components and host plugins. It is distinct from image.registry (which is where the host pod's own image comes from).
# hostgroup-values.yaml
ociRegistry:
allowInsecure: "" # off unless true; plain HTTP for EVERY pull, host-wide
pullTimeout: "" # e.g. "30s" / "2m"; unset = host default (30s)
cacheDir: "" # e.g. "/tmp/oci-cache"; unset = no cachingallowInsecure is whole-host and all-or-nothing: it downgrades every pull to plain HTTP, so turning it on to reach one in-cluster registry also sends ghcr.io pulls to http://ghcr.io/... (which fail). For the ordinary case of a registry behind a private or in-cluster CA, leave allowInsecure off and use caBundle instead, which keeps verification on and works per-registry. cacheDir should be a directory of its own (the host evicts everything it finds there older than an hour); /tmp/oci-cache is a good choice, and /tmp itself is refused at startup.
Image registry overrides apply to every component
Before v0.11.0, every component in both charts shipped an explicit registry: ghcr.io in values.yaml. Because a non-empty per-component registry always wins over global.image.registry, setting the global had no effect: every component pulled from ghcr.io regardless. The Traefik edge proxy and its busybox init container were worse off: both were hardcoded to docker.io and ignored overrides entirely.
As of v0.11.0, each component's per-component registry defaults to empty ("") in both charts, and the registry a component resolves to follows a clear precedence: the component's own image.registry, then global.image.registry, then the chart default ghcr.io. A fresh install, or one whose values set no component registry, renders exactly the same ghcr.io/... images as before; this only takes effect when you set global.image.registry.
Action for air-gapped and mirrored installs. If your values file was seeded from helm show values on v0.10.0 or earlier (or you copied a component block from an older chart), it carries an explicit registry: ghcr.io on one or more components. That value continues to shadow global.image.registry after the upgrade, with no render-time warning, so pointing the global at your mirror silently leaves those components pulling from ghcr.io. Remove the per-component registry: lines (or set them to ""), then verify before upgrading; every line should show your mirror:
helm template cosmonic-control oci://ghcr.io/cosmonic/cosmonic-control \
--version 0.12.1 -f cosmonic-control-values.yaml | grep 'image:'
helm template hostgroup oci://ghcr.io/cosmonic/cosmonic-control-hostgroup \
--version 0.12.1 -f hostgroup-values.yaml | grep 'image:'Check both charts: the control-host image an air-gapped install most needs to mirror lives in the HostGroup chart, and the registry override applies there too. The Traefik proxy and its init container are now pulled from the mirror like every other component (traefik and busybox under your configured registry) and honor global.image.registry. Air-gapped installs must mirror the two new tags (traefik:v3.6.6 and busybox:1.38.0) to their internal registry alongside the existing images. See Air-Gapped Installation.
imagePullSecrets reach Traefik and the HostGroup
The Traefik Deployment and the HostGroup pod now emit imagePullSecrets, matching the other components. A private mirror that requires authentication no longer leaves those two pods unable to pull. Set the secret once on global.image.pullSecrets (both charts read it); a component's own image.pullSecrets still overrides the global where present.
TLS for the NATS connections
The host can now dial NATS over TLS, configured through a tls block on nexus (the control-plane connection) and on dataNats (the data-plane connection workloads use for messaging). Both default to plaintext, which is what the in-cluster nexus serves, so existing installs are unaffected.
# hostgroup-values.yaml
nexus:
url: "tls://nats.example.com:4222"
tls:
enabled: true
existingSecret: "" # Secret (release namespace) holding the material below
caKey: "" # key holding the CA-bundle PEM the server chains to (private CA)
certKey: "" # client cert, for a mutual-TLS server (set with keyKey)
keyKey: "" # client private key
first: false # true for a tls_first / handshake_first serverPoint it at TLS material only when NATS is external or managed and reachable over a tls:// URL. Set caKey for a server behind a private CA and leave it empty for a publicly-signed one, since a bundle replaces the trust store rather than adding to it (and a kubernetes.io/tls secret carries no CA key). When dataNats.url is empty the data plane inherits nexus.tls; a dataNats.url that names its own server inherits nothing, so set dataNats.tls explicitly in that topology.
The cosmonic:kafka host plugin
v0.11.0 adds a native cosmonic:kafka host plugin, so workloads can produce to and consume from Kafka without a sidecar or bespoke provider. Like wasmcloud:nats, it is operator-configured through hostPlugins with deny-by-default grants and needs no new CRD. Configure it on the HostGroup to grant a workload Kafka access; see Host groups.
wasmCloud runtime bump
The control-host runtime is bumped to the latest wasmCloud release. No configuration change; it applies when you bump the chart.
With the values file updated and CRDs applied, run the Standard upgrade flow with --version 0.11.0.