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 cluster with a default StorageClass (for the log server's PVC) and
helm installed locally.
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 without log.url.
3. The log server
Apply deploy/kubernetes/distributed/log.yaml in the same namespace
before installing the chart -- a minimal StatefulSet, Service and PVC
running the same software values.yaml's log.url points at:
# deploy/kubernetes/distributed/log.yaml
apiVersion: v1
kind: Service
metadata:
name: jaque-log
spec:
clusterIP: None
selector:
app: jaque-log
ports:
- name: log
port: 4222
targetPort: 4222
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: jaque-log
spec:
serviceName: jaque-log
replicas: 1
selector:
matchLabels:
app: jaque-log
template:
metadata:
labels:
app: jaque-log
spec:
containers:
- name: log
image: nats:2.10-alpine
args: ["-js", "-sd", "/data"]
ports:
- name: log
containerPort: 4222
volumeMounts:
- name: data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 5Gi
kubectl apply -f deploy/kubernetes/distributed/log.yaml
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/status.json
The dashboard is at http://localhost:8080/ once the port-forward is
up (or through ui.ingress if enabled). 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
PVC in log.yaml; 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.