Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chart values reference

Every key in deploy/helm/kaas/values.yaml, what it does, and where it lands. The Helm chart chapter tells the narrative story (listeners, upgrades, CRDs); this page is the exhaustive reference. Defaults shown are the chart's.

Two Helm behaviors worth knowing before overriding anything:

  • Helm deep-merges values, so restating a default changes nothing — and removing a chart default requires an explicit null, not omission.
  • A handful of keys are dead — parsed by nothing, kept only until a cleanup release removes them. They are flagged dead below rather than silently omitted, so you can tell "documented and inert" from "undocumented".

image and operator.image

KeyDefaultMeaning
image.repository""Broker image. Empty derives ghcr.io/kaas-rs/kaas, with a -preview suffix appended automatically when the resolved tag is a pre-release (contains -) — the same naming rule the release workflow uses. An explicit value overrides the derivation.
image.tag""Defaults to the chart's appVersion.
image.pullPolicyIfNotPresent
operator.image.*"" / "" / IfNotPresentSame derivation for ghcr.io/kaas-rs/kaas-operator[-preview].

operator

KeyDefaultMeaning
operator.enabledtrueDeploy the operator (single replica, leader-elected). Without it, CRs are never reconciled — see runtime independence for what keeps working.
operator.resources100m/128Mi – 500m/256MiRequests/limits.
operator.podSecurityContextnon-root 65532, group 0, fsGroup: 0, OnRootMismatchMirrors the broker's shared-volume permission scheme (below) — the operator writes the same volume at reconcile time. There is deliberately no init container here: the reconcile loop retries until the broker's permission floor has run.

broker

KeyDefaultMeaning
replicaCount3Brokers in the StatefulSet. Multi-broker requires RWX storage — see storage requirements.
clusterIDkaas-localThe cluster id reported to clients.
minReadySeconds60Rolling-update pacing: a pod must hold Ready this long before the next one is replaced. Belt-and-braces on top of honest readiness; raise it on slow storage where takeover recovery scans run long.
ports.health8080Health/readiness HTTP (fixed).
ports.heartbeat9094Inter-broker heartbeat gRPC (fixed, in-cluster only).
ports.kafka, ports.tls9092/9093dead — superseded by the listeners[] array, referenced by no template.
resources500m/1Gi – 2/4GiRequests/limits. For benchmarking, note the memory limit also caps page cache under cgroup v2 — a tight limit costs cold-read throughput.
readinessGate.enabledtrueAdds the kaas.rs/PartitionsReady pod readiness gate: a pod joins Service endpoints only once its partition directories exist. Disable only for bare-bones smoke tests.

broker.podSecurityContext

Default: non-root UID 65532, group 0, fsGroup: 0, fsGroupChangePolicy: OnRootMismatch. Two independent mechanisms both make the shared volume writable: on CSI drivers that honour fsGroup, the kubelet chowns the volume to group 0 (the broker runs 65532:0, the Strimzi "primary GID 0" convention); on shared NFS — where most CSI drivers skip that chown — the broker's partition-init init container is the floor, chowning the volume itself before the broker starts.

broker.controllerLease

KeyDefault
durationSeconds15
renewDeadlineSeconds10
retryPeriodSeconds2

The Kubernetes Lease behind controller election. Tighter = faster failover, more API-server writes. On an API server with high tail latency (small shared nodes), widen the ratios — a lease that flaps during pod churn moves the controller for no reason.

Durability, retention, limits

KeyDefaultKafka equivalentMeaning
flushIntervalMessages1log.flush.interval.messagesThe durability dial. 1 = fsync every record (honest acks=all; kaas has no replication, so fsync is the only durability mechanism). N = up to N−1 records lost per partition on crash. 0 = fsync only at segment roll. Overridable per topic via flush.messages. See performance for what this costs.
retentionCheckIntervalSeconds300log.retention.check.interval.msRetention sweep cadence — retention is enforced (7-day default for unconfigured topics). 0 disables the sweep entirely. Leader-gated; the active segment is never reclaimed.
maxMessageBytes1048588message.max.bytesCap on one Produce batch (Apache's default: 1 MiB + header overhead). Oversized batches get MESSAGE_TOO_LARGE. Raise together with consumer fetch.max.bytes.
fsyncMaxLatencyMs30000Fsync watchdog — the stuck-storage tripwire. Every acked produce fsyncs (at the default flush interval), and a hung NFS server makes that fsync block forever, not fail: appenders queue behind the partition lock and producers time out with no error naming the cause. Past this deadline the append instead fails with a retriable error and the broker's health state reports storage as stalled, so clients retry and /healthz points at the substrate. Apache has no equivalent because ISR failover covers a broker with a hung disk; kaas has no replicas, so failing fast is the fallback. On healthy storage it never fires (fsyncs run in the tens of milliseconds). 0 disables it, for substrates whose legitimate worst-case fsync latency exceeds any sane deadline.
txnState.numSlots50transaction.state.log.num.partitionsTransaction-state slot-file count, cluster-wide. Changing it on a live cluster re-shards slot ownership; drain transactional producers first.
autoCreateTopics.enabledtrueauto.create.topics.enableMetadata requests for unknown topics mint a KafkaTopic CR and answer LEADER_NOT_AVAILABLE until the operator materializes it — what Kafka Streams' .to(sink) relies on.
autoCreateTopics.numPartitions1num.partitionsPartition count for auto-created topics only.

storage

KeyDefaultMeaning
classNameceph-filesystemStorageClass for the data volume. Multi-broker needs RWX with NFSv4-class semantics — see storage requirements for the provider matrix.
size500Gi
accessModeReadWriteManyReadWriteOnce + a local-path class is fine for single-broker.
mountPath/data

All PVCs the chart renders carry helm.sh/resource-policy: keep — they survive helm uninstall and must be deleted explicitly.

storage.controlPlane

KeyDefaultMeaning
enabledfalseMove cluster-wide coordination state (assignment, transaction slots, offsets, credentials, queues) onto its own small volume, so a runaway topic filling the data volume degrades into per-topic produce errors instead of taking the control plane down.
className"" (= storage.className)
size / accessMode / mountPath1Gi / ReadWriteMany / /cluster

Enabling this on an existing cluster is a breaking change (pre-v1 policy): redeploy fresh, or copy __cluster/* onto the new volume with brokers and operator scaled down.

storage.pool[]

Default []. Named additional RWX volumes — "log dirs" in Kafka's KIP-113 vocabulary — mounted on every broker at /vols/<name> and selectable per topic. Each entry:

FieldMeaning
nameLog-dir name topics bind to via KafkaTopic.spec.storage.volumes.
size, className, accessModePVC shape; empty className inherits storage.className.
defaultEligibletrue = receives topics that don't name volumes; false = reserved for explicit binding.
cordonedtrue = no new placements (the decommission drain primitive).
labelsMatched by KafkaTopic.spec.storage.volumeSelector.

The full model — placement stickiness, selectors, explicit migration — is the volume pool chapter.

auth

KeyDefaultMeaning
enabledtruefalse swaps in an allow-all engine: no authentication anywhere, every connection is User:ANONYMOUS.
requireSaslfalsetrue arms the SASL pre-auth gate on anonymous listeners too — closes the "connect to the plain listener and skip auth" hole cluster-wide. auth.enabled: false outranks it.
sslPrincipalMappingRules""Apache's ssl.principal.mapping.rules, verbatim — regex rules mapping an mTLS client cert's subject DN to a principal. Empty = use the CN. Parse errors fail startup deliberately, so a typo crash-loops instead of silently mapping every cert to its CN.
mechanisms[SCRAM-SHA-512]dead — mechanism advertisement is per-listener now; no template reads this.
tls.enabled / tls.existingSecret / tls.certManagerIssuerfalse / "" / ""dead — pre-listener-array TLS shape; TLS is declared per listeners[] entry.

Authentication/authorization architecture, including what each listener authentication.type means, is Listeners, authentication, authorization.

admin.argocd

KeyDefaultMeaning
enabledfalseStamp ArgoCD coexistence annotations onto CRs the broker creates at runtime (admin-protocol topic creation), so they render in the Application tree instead of being pruned as drift.
applicationName"" (= release name)The Application the tracking-id claims.
compareOptionsIgnoreExtraneousPassed through verbatim; "" skips the annotation so runtime topics surface as deliberate drift.
syncOptionsDelete=falseDefault means runtime-created topics survive an Application delete. "" restores cascade-delete; Prune=false,Delete=false surfaces drift and survives deletes.

Details and the reasoning: Kubernetes integration.

Scheduling and identity

KeyDefaultMeaning
podDisruptionBudget.enabled / maxUnavailabletrue / 1Applies to node drains and other eviction-API disruptions. Note it is inert for StatefulSet rollouts (those delete pods directly); rollout pacing is broker.minReadySeconds.
serviceAccount.broker.create / .nametrue / ""
serviceAccount.operator.create / .nametrue / ""
autoscaling.*enabled: false, 3–10, lag 100000dead — the chart renders no HorizontalPodAutoscaler; autoscaling.enabled: true does nothing today.
clusterDomaincluster.localDNS suffix for the per-broker FQDNs advertised on internal listeners. Override only on clusters with a non-default CoreDNS domain.

observability

KeyDefaultMeaning
otlp.metrics.enabledfalsePush metrics (OTLP/HTTP) to Prometheus's native OTLP receiver (--web.enable-otlp-receiver).
otlp.metrics.endpointhttp://prometheus.observability...:9090/api/v1/otlp/v1/metricsPath must end in /v1/metrics.
otlp.metrics.exportInterval"30s"Push cadence. The SDK's 60 s default leaves Grafana rate([1m]) panels with one sample per window; 30 s guarantees two. Duration strings accepted.
otlp.traces.enabledfalsePush traces (OTLP/gRPC) to Tempo or a Collector.
otlp.traces.endpointtempo.observability...:4317host:port; a scheme prefix is stripped, and plaintext-vs-TLS is inferred from it.
otlp.traces.samplerRatio0.11.0 = every trace (dev/debugging).
logs.level / logs.formatinfo / jsondebug…error; json or text.
alerts.enabledfalseRender a PrometheusRule with the load-bearing kaas alerts (byte-opacity tripwires, self-fence, stale assignments…). Needs Prometheus Operator.
alerts.additionalLabels{}Merged into every rule (Alertmanager routing).
alerts.thresholds.*see values.yamlPer-alert overrides. Caveat: heartbeatRttP99Seconds tunes an alert whose metric is not yet emitted — that alert cannot fire today.

The wider observability story: Observability.

listeners[]

The Strimzi-shape listener array — each entry is one TCP listener on every broker, described by three orthogonal axes (type, tls, authentication.type). The Helm chapter and listeners architecture page cover the model; this is the field reference. Defaults ship four entries: plain (9092, anonymous), external (9093, TLS, disabled), authed (9095, SCRAM, disabled), oauth (9096, TLS + OAUTHBEARER, disabled).

FieldMeaning
nameFree-form, unique; keys the per-listener auth engine and appears in Metadata advertisement. Duplicate names or ports fail at boot.
enabledAbsent = enabled.
portUnique per entry.
typeinternal (headless-Service DNS) or external (per-broker plumbing below).
tlsIndependent of authentication; tls: true + type: none is opportunistic TLS.
authentication.typenone / scram-sha-512 / plain / mtls / oauth. mtls requires tls: true; SASL PLAIN and OAUTHBEARER are refused over non-TLS connections at runtime (they carry reusable credentials). Anonymous listeners skip ACL evaluation entirely unless auth.requireSasl arms them.

external-type extras

FieldDefaultMeaning
hostnamePatternbroker-%d.kafka.example.comPer-broker FQDN pattern (%d = ordinal), used for certificate SANs and routes. Honesty note: the pattern does not currently reach Metadata advertisement — external listeners still advertise the in-cluster FQDN, so external access effectively requires SNI routing that terminates on those internal names. Tracked as a known gap.
bootstrapHostname""Optional single bootstrap CNAME, added to certificate SANs.
certManager.enabled / issuerReftrue / letsencrypt-prod (ClusterIssuer)One cert-manager Certificate covering all per-broker hostnames.
clientCA.enabled / existingSecret / keyfalse / "" / ca.crtRequire client certs signed by this CA; pair with authentication.type: mtls.
gateway.enabled / gatewayReftrue / kaas-gateway in kafkaOne Gateway-API TLSRoute per broker (TLS passthrough). With false, the per-broker Services remain and can be fronted by LoadBalancers instead.
service.annotations{}Extra annotations for the per-broker Services — not yet applied by the operator (declared, ignored; tracked as a known gap).

Only the first type: external entry drives the operator's Certificate/Service/TLSRoute reconciliation today.

oauth authentication fields

Strimzi's KafkaListenerAuthenticationOAuth field names, verbatim:

FieldMeaning
validIssuerUriExact-match iss claim.
jwksEndpointUriWhere signing keys are fetched — every jwksRefreshSeconds (default 300) and early on an unknown key id. Fail-closed before the first fetch.
userNameClaimClaim that becomes the principal (User:<value>); default sub.
fallbackUserNameClaimTried when userNameClaim is absent.
checkAudience / clientIdWhen true, the token's aud must contain clientId. Off by default.
maxSecondsWithoutReauthenticationKIP-368: advertise session_lifetime_ms = min(this, token remaining lifetime) and refuse requests past the deadline until re-authentication. Unset = sessions outlive their token.

authorization

KeyDefaultMeaning
type"""" = no authorization (Strimzi's "missing = no restrictions"). simple = ACL enforcement from the operator-managed ACL file. Cluster-wide — authentication stays per-listener, and quotas fire regardless of this setting (orthogonal axes).
superUsers[]Principals that bypass ACL evaluation (early-allow). Matched verbatim: bare names for SCRAM/OAuth principals, CN=… for mTLS subjects.

Implementation notes (for contributors)

  • Templates consuming these values live in deploy/helm/kaas/templates/; listener JSON assembly is the kaas.listenersJSON helper in deploy/helm/kaas/templates/_helpers.tpl, landing as the KAAS_LISTENERS env (gh #126). Env-var names for the broker knobs are parsed in crates/kaas-broker/src/cli.rs.
  • The ⚠ dead keys (broker.ports.kafka/tls, auth.mechanisms, auth.tls.*, autoscaling.*) and the inert heartbeatRttP99Seconds threshold are tracked in gh #265; the external advertised-hostname gap is gh #263; the unapplied service.annotations is part of gh #266.
  • This page documents chart defaults, not any specific deployment. When a key moves or dies, update this page in the same commit — the drift gates don't cover values keys.