Skip to main content

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.yaml

Upgrade 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.yaml

Wait 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-system
Chart version vs. appVersion

Chart 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.1

Rolling 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-system

helm 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-system

CRD rollback caveat

warning

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.

VersionChangeAction
v0.11.0Socket egress policy (egressPolicy), shipped in preview count modeNone on upgrade — nothing is enforced until you set socketEgress: enforce; plan the count→enforce rollout (and denySpecialRanges for the metadata endpoint) then
v0.11.0Chart-wide image registry override (global.image.registry); Traefik and its busybox init are now mirroredAir-gapped/mirrored installs: remove any per-component registry: ghcr.io so the global applies, and mirror the new traefik/busybox tags
v0.11.0imagePullSecrets now attached to Traefik and the HostGroup podNone unless your registry needs auth — then set global.image.pullSecrets
v0.11.0Host OCI registry controls (ociRegistry: allowInsecure, pullTimeout, cacheDir)None; opt-in
v0.11.0Connection quotas (connectionQuotas)None; the host derives a ceiling from its descriptor budget. Watch /readyz for http_ingress_saturated
v0.11.0TLS for the NATS connections (nexus.tls / dataNats.tls)None; opt-in for an external or managed NATS
v0.11.0Native cosmonic:kafka host pluginConfigure on the HostGroup to grant workloads Kafka
v0.9.3CA-bundle trust extended to component egress (caBundle.egress)None unless components call a service behind a private CA
v0.9.3wasmtime 47.0.4 security update (RUSTSEC-2026-0268/0269)None — security patch, applied on chart bump
v0.9.3HostGroup memory defaults raised; new hostMemory knobsReview sizing before upgrade; the larger default request can leave host pods Pending
v0.9.3Host health-probe listener (/livez, /readyz on 9192)None needed; set health.enabled: false to disable
v0.9.3caBundle now trusts a private CA for image pullsNone unless pulling from a registry behind a private CA
v0.9.3wasmcloud:nats host plugin (core, JetStream, KV)Configure on the HostGroup to grant workloads NATS access
v0.9.3Warm-pool idle reclaim (reclaimWindowSeconds, reclaimMinInstances)None needed; additive and opt-in per component
v0.9.2control-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.0Default resource requests and limits on every podReview sizing after upgrade; raise or remove limits that don't fit your cluster
v0.7.0Hardened pod and container securityContexts by defaultNone unless a container must write outside its mounted volumes
v0.7.0Baseline NetworkPolicies (networkPolicy.enabled, on by default)Set networkPolicy.enabled: false if a service mesh manages network policy
v0.7.0Named host interfaces and hostInterfaces admission validationDeduplicate hostInterfaces entries that share a namespace:package before re-applying manifests
v0.6.x and earlierNexus StatefulSet PVC migration, Traefik-as-default ingress, Console/Cloud removal, CA bundle, unpinned trigger environmentPrefer 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.existingClaim value was removed. Migrate any pre-v0.6.0 nexus-data PVC onto data-nexus-0 before upgrading, or you lose durable wasi:keyvalue and Artifact JetStream state. Nexus also gained HA through nexus.replicas (an odd number, for RAFT quorum).
  • Traefik became the default ingress (v0.4.0 and v0.4.1). Set ingress.provider: istio if you rely on Istio, or ingress.enabled: false to expose Envoy directly.
  • Console and Cloud components were removed (v0.4.0). Delete any console: and console_ui: blocks from your values.
  • CA bundle support was added (v0.5.0, opt-in), and HTTPTrigger.spec.environment became unpinned by default (v0.5.2); set environment explicitly 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:

  1. No two entries may be exact duplicates — the same namespace, package, name, and version.
  2. At most one entry of a given namespace:package may be unnamed. The unnamed entry is the default route and cannot be shared; give additional entries of the same package distinct names.

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 the 192Mi default limit for large clusters.
  • prometheus.resources — TSDB memory scales with active series; the default limit is 512Mi.
  • HostGroup resources — host pods run Wasm components in-process, so memory scales with the workloads scheduled onto each host. Size limits.memory (default 512Mi) 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: false

Baseline 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.

note

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 of resources.limits.memory, so under Kubernetes it tracks the pod automatically; set it only to override.
  • hostMemory.defaultHeapMemory (the chart ships 1Gi): 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 by defaultHeapMemory this is the pool's virtual reservation, mapped PROT_NONE and 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: 9192

It 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-only

trustRoots: 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 count mode, so nothing is severed on upgrade. With socketEgress unset (the default, count), the host evaluates the whole policy (the per-workload allowedHosts allowlist 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. Only enforce actually refuses. Roll it out gradually: run at RUST_LOG=debug for a representative period, confirm nothing legitimate appears in the would-refuse log, then set socketEgress: enforce. Under enforce, a hostPlugins entry that declares no allowedHosts has an empty allowlist and is denied every raw-socket connect, so check each plugin's allowedHosts first. wasi:http egress is gated by allowedHosts regardless of this setting.
  • denySpecialRanges is on by default within the policy. Once you enforce, raw-socket connections to loopback, link-local (including the cloud metadata address 169.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), set denySpecialRanges: false before flipping to enforce; the count-period debug log will show those 169.254.169.254 hits 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. allowHostLoopback lets workloads reach the pod's own loopback via host.wasmcloud.internal, and additionally requires the workload's own allowedHostLoopbackPorts entry, 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_NOFILE

These 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 caching

allowInsecure 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 server

Point 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.