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.

image and operator.image

KeyDefaultMeaning
image.repository""Broker image. Empty derives ghcr.io/kaas-rs/kaas-broker, 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-broker-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).
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.
fsyncMaxLatencyMs30000—Fsync 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.

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 / ""
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.
logs.level / logs.formatinfo / jsondebug…error; json or text.
alerts.enabledfalseRender a PrometheusRule with the load-bearing kaas alerts (self-fence, stale assignments…). Needs Prometheus Operator.
alerts.additionalLabels{}Merged into every rule (Alertmanager routing).
alerts.thresholds.*see values.yamlPer-alert overrides.

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.
clientCA.existingSecret / keyInternal TLS listeners only (default key ca.crt): the Secret holding the CA that signs client certificates. Only this listener then requires a client certificate — SCRAM or OAuth listeners on the same broker keep accepting certificate-less clients, the way Apache Kafka's per-listener listener.name.<name>.ssl.client.auth works. Required for an internal mtls listener (the template fails without it); the external listener uses its own clientCA.enabled block below.

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 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.