Helm objects and values
For: cluster operators.
Look up the chart objects and supported values.
What the chart runs
| Object | What it does |
|---|---|
StatefulSet <release>-server | The servers. A StatefulSet so each keeps its name across restarts (the servers table, its leases, its logs), and upgrades roll one at a time. Each has a volume of its own for its data directory (--data-dir, server.persistence): the metering writes the database refused, kept until it takes them, and the erasure ledger, which a replaced pod (a rollout, an eviction, a drain) must not lose. --advertise is the pod's IP. |
Job <release>-init | server init as a pre-install,pre-upgrade hook. |
Service <release>-edge | Ports 7233 (Temporal for nodes) and 7443 (join, renewals, control stream). |
Service <release>-management | Port 8443: the admin API and the console. |
Service <release>-servers | Headless: stable names for the servers. |
| Probes | Startup and liveness GET /healthz, readiness GET /readyz, over HTTPS on 7443. A fenced edge answers 503, so the Services stop sending it nodes while its peers serve. |
| PodDisruptionBudget | At most one server down for a node drain (server.pdb). |
| NetworkPolicy | Servers reach each other on every port. The edge's ports are open to the chart's nodes and to networkPolicy.edgeFrom (by default anyone, for nodes outside the cluster). Management's port admits only the servers and networkPolicy.managementFrom, never nodes. Nodes reach only the edge, DNS and, unless nodes.networkPolicy.allowPublicEgress is off, public addresses for their plugins; private ranges stay closed. |
CronJob <release>-backup | Optional: server backup on a schedule into a volume (Back up). |
StatefulSet <release>-node | Optional: nodes in the cluster. |
Kubernetes port-forward reaches management without a NetworkPolicy rule. An Ingress controller needs one: add its namespace to networkPolicy.managementFrom.
Values
The full list with comments is the chart's values.yaml. The groups:
| Values | What they set |
|---|---|
image.server, image.node | Repository, tag (default: the chart's appVersion) or digest, pull policy. imagePullSecrets. |
cluster | What the first install creates: name, historyShards (never changes), tenant, operator. |
database | existingSecret and urlKey: the PostgreSQL URL. Required. |
masterKey | existingSecret and key: the master key file. Required. |
masterKey.command, caSigner.command | A key command that unwraps the master key, and the CA signing command, passed to init and every server. Bring the executables with server.extraVolumes, server.extraVolumeMounts or server.extraInitContainers; they run without a shell, with a minimal environment: name the variables they need in OZ0_KEY_COMMAND_ENV through server.extraEnv, such as AWS_*,VAULT_ADDR,VAULT_TOKEN. |
erasureLedger | Details |
init | enabled (off: run server init --master-key-file yourself before the first install), adminPassword.existingSecret (required while enabled is on), backoffLimit, activeDeadlineSeconds, resources. |
server | replicas (2 or more), logLevel, sans, publicURL and oidcConfig.existingSecret (Sign-in), routineOutputAllowNets, llm.anthropicURL and llm.openaiURL, persistence (on by default: size, storageClass; off, the data directory is an emptyDir, and a pod that is replaced loses the metering writes waiting there), extraArgs, extraEnv, extraVolumes, extraVolumeMounts, extraInitContainers, resources, scheduling (nodeSelector, tolerations, affinity, topologySpreadConstraints, priorityClassName), security contexts, the three probes' timings, pdb. |
service.edge, service.management | Service type, annotations; for the edge also loadBalancerSourceRanges, externalTrafficPolicy and nodePorts. |
ingress | Details |
metrics | enabled, port (9464): Prometheus metrics over plain HTTP, and a headless Service for them; serviceMonitor for the Prometheus Operator. |
otlp | endpoint, plain headers, and secretHeaders whose values come from Secrets. |
networkPolicy | enabled, edgeFrom, managementFrom, metricsFrom: lists of NetworkPolicy peers. |
backup | enabled, schedule, keep (archives to keep), persistence (existingClaim, or size and storageClass for one the chart makes once and keeps when it is uninstalled). |
nodes | enabled, replicas, joinToken.existingSecret or caHash, server (default: the edge Service), sandbox, sandboxTier1 (Sandbox tier 1 in node pods), runtimeClassName, stopGraceSeconds, persistence, resources, scheduling, networkPolicy.allowPublicEgress, privateRanges and extraEgress. |
temporal | The backend, connection, encryption, UI and codec settings. See Temporal chart settings. |
roles | Details |
payloadStore | url (s3://bucket/prefix?...) keeps payloads and plugin artifacts in an S3-compatible bucket instead of PostgreSQL, on every server that runs the edge role; credentials.existingSecret and credentials.key name a Secret with an AWS shared credentials file for it. See Payload storage. |
Temporal chart settings
backend: embedded (Temporal's services in every server, on your PostgreSQL), external or cloud, with address, tls, apiKey, cloudAccount, createNamespaces, encryptPayloads (true by default: payloads are encrypted with each tenant's key; false turns it off, which oz0 doctor warns about), uiURL and codec for the latter two (codec.audience, codec.accountClaim and codec.maxTokenAge bind the Temporal Cloud UI's tokens to this server).
The chart refuses what the server would: cloud without cloudAccount, an API key to an external Temporal without tls.enabled, and a codec.jwksURL of your own without codec.jwtIssuer. See Temporal.
Erasure ledger storage
Where management records every erasure for a restore to apply again (backups and erasure). By default each server gets a volume of its own for it (persistence: size, storageClass), mounted at /var/lib/orchestrator-zero/erasure-ledger, apart from the database and its backups. existingClaim names a ReadWriteMany claim instead, with one file per pod; roles.separate needs it, since management's Deployment has no volume per pod. enabled: false keeps no ledger (--erasure-ledger=off). A ledger on a pod's own storage would be lost at every rollout, and erasures would then be refused, so the chart refuses to render one.
Ingress configuration
An Ingress for the console on port 8443. Management speaks only HTTPS, so set your controller's backend protocol (for ingress-nginx: nginx.ingress.kubernetes.io/backend-protocol: HTTPS). The CLI uses client certificates, which pass only through TLS passthrough; use a port-forward otherwise. The Ingress hosts are added to the servers' certificates.
Set ingress.trustedProxies to the addresses the controller's own pods connect from: management then counts failed sign-ins per browser, by the client the controller names in X-Forwarded-For, instead of counting every browser as the controller's one address (sign-in).
Name the controller alone, never the cluster's whole pod network: a pod inside a trusted network chooses the address it is counted as, and unless roles.separate is on, the edge's API, which nodes and other pods reach, trusts the same list. Pin the controller where nothing else runs (a node pool of its own, whose pod range you name, or host networking and those machines' addresses), or run the roles separately. The install notes remind you while it is empty.
Separate roles configuration
separate: true runs management as a Deployment and edges as a StatefulSet with a volume each. With the embedded backend, Temporal's services run as a separate StatefulSet. roles.manager, roles.edge and roles.temporal set their replicas and resources.
The edges also need these settings:
| Setting | Purpose |
|---|---|
managementURL | Management's internal API address. |
payloadDatabase | A Secret with the edges' own PostgreSQL URL for payloads and plugin artifacts. Required unless payloadStore.url is set; a separate edge will not start without one of them. |
secretsKey | Required key for sealing tenant secrets, created with oz0 server secrets-key create. |
persistence | The edge's persistent volume configuration. |
With separate: true, the database user needs CREATEROLE, and pg_hba.conf must let oz0_edge_<database> log in with a password from the management pods (database requirements). The init Job checks both from its own pod with server init --roles-apart and fails with what to change.