One workload per role (engine as a StatefulSet, worker, ui, notifier and sink as Deployments), sharing one log server. This is the shape Choose your deployment points at for Kubernetes split by role. Topologies, section 2.2, is the mechanism.

1. Prerequisites

A log server the roles can reach, and helm installed locally. A default StorageClass is also needed if the log server runs in the cluster, whether that is one you manage yourself or the one the chart can install for you (section 3).

2. Install

helm install jaque oci://<registry>/jaque/charts/jaque --version <chart version> \
  -f values.yaml

See Kubernetes for what deploymentMode: split renders per role and what the chart refuses at render time.

3. The log server

Every role in split mode shares one log server, reached two ways:

Bring your own and point log.url at it, the shape deploy/kubernetes/distributed/values.yaml uses:

log:
  url: "nats://jaque-log:4222"

Or set nats.enabled: true and leave log.url empty: the chart installs one in the cluster from the official chart, with the log's persistent store on a 5Gi PVC.

nats:
  enabled: true

This guide's values.yaml uses the first shape, so the log server is a resource you manage; see Kubernetes, section 4, for what the second shape renders and what the chart refuses when both are set the wrong way.

4. The values file

The canonical copy is deploy/kubernetes/distributed/values.yaml in the repository.

# deploy/kubernetes/distributed/values.yaml
deploymentMode: split

image:
  tag: ""

config: |
  hosts: {
  	self: {
  		address: "127.0.0.1"
  		check: {type: "icmp", host: "127.0.0.1"}
  	}
  }

apiToken: ""

log:
  url: "nats://jaque-log:4222"

queue:
  url: ""

engine:
  replicas: 2
  heartbeatTTL: ""

worker:
  enabled: true
  replicas: 2
  zones:
    - default
  netRaw: true

ui:
  enabled: true
  replicas: 1
  ingress:
    enabled: false
    className: ""
    host: ""

sink:
  enabled: true
  replicas: 1
  select: []

notifier:
  enabled: true
  replicas: 1

5. Start

helm install jaque oci://<registry>/jaque/charts/jaque --version <chart version> \
  -f deploy/kubernetes/distributed/values.yaml

6. Verify

kubectl exec deploy/jaque-ui -- /jaque version
kubectl port-forward svc/jaque 8080:8080
curl http://localhost:8080/healthz

The dashboard is at http://localhost:8080/ once the port-forward is up (or through ui.ingress if enabled); that is where to read the current object list. For jaque_membership_size, port-forward the engine StatefulSet's Service instead and check /metrics there: ui never joins engine membership, so its own /metrics reads 0. With engine.replicas: 2, either engine pod reports jaque_membership_size as 2, since both see the same shared membership view.

7. Add a worker zone

Set worker.zones to include the new zone name and give the hosts in your config that zone, or run a second helm install/values.yaml overlay with a different worker.zones if the zone needs its own nodeSelector or tolerations. A check only runs on a worker serving its object's zone; see Topologies, section 3.

8. Where things live

Config is the config value, mounted as a ConfigMap into every role that takes -config. State (the event log) lives on the log server's own storage; no jaque workload keeps its own persistent state. Logs go to kubectl logs deploy/jaque-<role> (or statefulset/jaque-engine).

9. Upgrade

helm upgrade jaque oci://<registry>/jaque/charts/jaque --version <chart version> \
  -f deploy/kubernetes/distributed/values.yaml

Leave image.tag empty so the chart and the binary it deploys stay the same release. Roles upgrade independently as Kubernetes rolls each workload; engine is a StatefulSet with podManagementPolicy: Parallel.

10. Next steps

CUE in practice adds services and contacts to config. Contacts and policies wires a hard state to a person, delivered by the notifier role. Cluster and coordination is what engine.replicas: 3+ buys over 2.

11. Security considerations

worker.netRaw grants NET_RAW only to the worker role's container; no other role's containerSecurityContext carries it. ui.ingress.tls is the chart's only TLS termination; without it, and without an authenticating proxy in front, the dashboard, /metrics and any exposed Livestatus port are unauthenticated. See Kubernetes, section 7, and Security.