Skip to main content

Production Installation

Cosmonic Control separates operator and developer concerns: Wasm component developers use their own tooling to build and publish Wasm components, while operators use standard Kubernetes-native pipelines and tooling to deploy and manage them.

This page covers installing and configuring Cosmonic Control on a production Kubernetes cluster. See also:

Prerequisites

Installing Cosmonic Control

Cosmonic Control is distributed as an OCI Helm chart at oci://ghcr.io/cosmonic/cosmonic-control. The chart deploys the following components into the cosmonic-system namespace:

ComponentRole
operatorRuntime operator — reconciles CRDs and manages wasmCloud workloads
nexusNATS message bus — internal communication backbone
envoyHTTP ingress proxy — routes external traffic to Wasm workloads
opentelemetry-collectorReceives OTLP telemetry from all components
prometheusMetrics store
lokiLog store
tempoTrace store
persesObservability dashboard UI

Cloud clusters (EKS, GKE, AKS)

For cloud clusters, set envoy.service.type=LoadBalancer. Most providers will provision a load balancer automatically. Use envoy.service.annotations to control cloud-specific load balancer behavior.

AWS (Network Load Balancer):

helm install cosmonic-control oci://ghcr.io/cosmonic/cosmonic-control \
  --version 0.5.1 \
  --namespace cosmonic-system \
  --create-namespace \
  --set envoy.service.type=LoadBalancer \
  --set-json 'envoy.service.annotations={"service.beta.kubernetes.io/aws-load-balancer-type":"nlb","service.beta.kubernetes.io/aws-load-balancer-scheme":"internet-facing"}'

GKE / AKS (standard cloud load balancer):

helm install cosmonic-control oci://ghcr.io/cosmonic/cosmonic-control \
  --version 0.5.1 \
  --namespace cosmonic-system \
  --create-namespace \
  --set envoy.service.type=LoadBalancer

On-premises and bare-metal

For clusters without a cloud load balancer controller, expose Envoy as a NodePort and route external traffic to that port yourself:

helm install cosmonic-control oci://ghcr.io/cosmonic/cosmonic-control \
  --version 0.5.1 \
  --namespace cosmonic-system \
  --create-namespace \
  --set envoy.service.type=NodePort \
  --set envoy.service.httpNodePort=30950

Traffic must reach port 30950 on any node in the cluster. Configure your external load balancer, firewall rules, or ingress proxy accordingly.

Using a values file

For anything beyond a simple install, use a values.yaml file to manage configuration:

# cosmonic-control-values.yaml
envoy:
  service:
    type: LoadBalancer
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-type: nlb
      service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
helm install cosmonic-control oci://ghcr.io/cosmonic/cosmonic-control \
  --version 0.5.1 \
  --namespace cosmonic-system \
  --create-namespace \
  -f cosmonic-control-values.yaml

Wait for readiness

kubectl rollout status deploy -l app.kubernetes.io/instance=cosmonic-control -n cosmonic-system

Installing HostGroups

A HostGroup is a group of one or more wasmCloud host pods that run Wasm workloads. Every Cosmonic Control installation needs at least one HostGroup. HostGroups connect to the nexus NATS server and register themselves as available hosts for workload scheduling.

Install the default HostGroup:

helm install hostgroup oci://ghcr.io/cosmonic/cosmonic-control-hostgroup \
  --version 0.5.1 \
  --namespace cosmonic-system

Wait for it to be ready:

kubectl rollout status deploy -l app.kubernetes.io/instance=hostgroup -n cosmonic-system

Scaling HostGroups

HostGroups are standard Kubernetes Deployments and can be scaled horizontally. Set replicaCount to run multiple host replicas:

helm install hostgroup oci://ghcr.io/cosmonic/cosmonic-control-hostgroup \
  --version 0.5.1 \
  --namespace cosmonic-system \
  --set replicaCount=3

Cosmonic Control automatically load-balances workloads across all available hosts in a HostGroup (round-robin). If a host crashes, its workloads are redistributed to remaining hosts.

Multiple HostGroups

Deploy multiple HostGroups with different names and host labels to create distinct scheduling zones—for example, separating general-purpose workloads from GPU workloads, or isolating workloads by team or environment:

# General-purpose HostGroup
helm install hostgroup-default oci://ghcr.io/cosmonic/cosmonic-control-hostgroup \
  --version 0.5.1 \
  --namespace cosmonic-system \
  --set hostgroup=default \
  --set replicaCount=2

# GPU-enabled HostGroup
helm install hostgroup-gpu oci://ghcr.io/cosmonic/cosmonic-control-hostgroup \
  --version 0.5.1 \
  --namespace cosmonic-system \
  --set hostgroup=gpu \
  --set gpu=true \
  --set runtimeClassName=nvidia \
  --set replicaCount=1

Workload placement is controlled through host labels on WorkloadDeployment manifests. See Multi-tenancy and RBAC for details.

GPU HostGroups

Setting gpu: true on a HostGroup passes --wasi-webgpu to the control-host container, enabling Wasm workloads on that HostGroup to call the wasi:webgpu WIT interface.

To schedule GPU pods onto NVIDIA GPU nodes, set runtimeClassName: nvidia. Configure the NVIDIA device plugin and a matching Kubernetes RuntimeClass on the cluster beforehand; the Helm value must match the RuntimeClass name.

To make host-side artifacts (model files, precompiled kernels, driver libraries) available inside the HostGroup pod, set volumes and volumeMounts. These accept the standard Kubernetes Volume and VolumeMount specs and are available on any HostGroup, not only GPU ones:

# hostgroup-gpu-values.yaml
hostgroup: gpu
gpu: true
runtimeClassName: nvidia
replicaCount: 1

volumes:
  - name: models
    hostPath:
      path: /opt/models
      type: Directory

volumeMounts:
  - name: models
    mountPath: /var/models
    readOnly: true
helm install hostgroup-gpu oci://ghcr.io/cosmonic/cosmonic-control-hostgroup \
  --version 0.5.1 \
  --namespace cosmonic-system \
  -f hostgroup-gpu-values.yaml

Resource sizing

Control plane

The control plane components are each deployed as single replicas. The v0.4.x chart exposes a resources block on every component. Defaults are empty (no requests or limits); set them per component in a values file as needed:

# cosmonic-control-values.yaml
operator:
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 512Mi

nexus:
  resources:
    requests:
      cpu: 100m
      memory: 256Mi
    limits:
      cpu: 500m
      memory: 512Mi

envoy:
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 256Mi

The resources block is accepted under operator, nexus, envoy, opentelemetryCollector, prometheus, loki, tempo, and perses. Each follows the standard Kubernetes ResourceRequirements shape.

note

The control plane components currently run as single replicas. For production deployments requiring high availability, contact support@cosmonic.com.

HostGroups

HostGroup pods run Wasm workloads and typically benefit from tuning. Set resources in the HostGroup values file:

# hostgroup-values.yaml
replicaCount: 3

resources:
  requests:
    cpu: 500m
    memory: 512Mi
  limits:
    cpu: 2
    memory: 2Gi

As a starting point: a single HostGroup pod can comfortably run dozens of concurrent Wasm components given their small footprint (typically sub-millisecond startup, kilobyte-scale memory per component). Scale out by increasing replicaCount rather than individual pod resource limits.

Multi-tenancy and RBAC

Host labels for workload placement

HostGroups expose a hostLabels map that is propagated to every wasmCloud host in the group. These labels are used in WorkloadDeployment manifests to control which HostGroup runs a given workload:

# hostgroup-team-a-values.yaml
hostgroup: team-a
hostLabels:
  team: a
  environment: production
replicaCount: 2
helm install hostgroup-team-a oci://ghcr.io/cosmonic/cosmonic-control-hostgroup \
  --version 0.5.1 \
  --namespace cosmonic-system \
  -f hostgroup-team-a-values.yaml

Reference the labels in a WorkloadDeployment using the hostSelector field to pin workloads to specific HostGroups.

Kubernetes RBAC

Cosmonic Control creates one ClusterRole for the operator service account, plus two namespace-scoped Role objects in cosmonic-system. The ClusterRole grants:

  • control.cosmonic.io: ProjectEnvironment, HTTPTrigger (plus their status subresources)
  • runtime.wasmcloud.dev: Artifact, Host, Workload, WorkloadReplicaSet, WorkloadDeployment (plus status and finalizers subresources)
  • "" (core): ConfigMap, Secret, Namespace (read-only); Service (read-only); Pod (get, list, patch, watch)

The namespace-scoped Roles cover leader election (coordination.k8s.io/leases in cosmonic-system) and host finalizer reconciliation (a second Pod grant scoped to cosmonic-system). The Pod permissions let the operator patch the finalizer on a wasmCloud host pod when it terminates, so workloads reschedule immediately instead of waiting for the reconciliation loop.

Tenant isolation is enforced by Kubernetes namespace-scoped RBAC. Grant teams access to their own namespaces with standard Role/RoleBinding objects scoped to the control.cosmonic.io and runtime.wasmcloud.dev API groups. See Tenant RBAC for the full RBAC reference and worked examples.

Further reading