Skip to main content
The reference for the data-plane Helm chart. If you are installing for the first time, follow Install the data plane on Kubernetes instead — it walks the one path that works. This page is what you reach for when the wizard’s output is not enough: bringing your own Kafka, schema registry or PostgreSQL, tuning resources, or managing secrets out of band. The chart is published as an OCI artifact:
A full, annotated list of every value (with @param blocks) ships inside the chart’s own values.yaml, and the control-plane wizard links the reference values file for the version it serves you.

Components

Connector workers are not part of the chart: the data plane creates them as pods in its own namespace at runtime.
kodansu was previously called tansu, and the chart still reads a tansu: block for backwards compatibility (anything under kodansu: wins). New values files should use kodansu:.Two components that appeared in earlier versions of this page — karapace and kafka-ui — no longer exist in the chart. They were replaced by kora and kotatsu respectively. A values.yaml that still sets karapace.* or kafkaUi.* is silently ignored.

Identity

These come from the control plane (Deployments → New deployment → Self-hosted) and must be used verbatim — they are how the data plane authenticates itself.
deploymentMode: STANDALONE disables every control-plane call, including the heartbeat, and requires no deploymentJwtToken. It is the mode behind air-gapped installs — see Standalone for what you give up.
ingressUrl must match the public URL the control plane redirects users to — it is also used for OAuth-style callbacks. A mismatch shows up as a login redirect loop.

Secrets you must generate

Beyond the values handed by the control plane, four secrets are generated locally. The wizard mints three of them in your browser; installing by hand means producing them yourself.
These four secrets encrypt connector credentials, sign user sessions and protect the admin login. Lose them and you lose access to your stored connector configs. Back them up in your secret manager.connectorConfigEncryptionKey.key must never be rotated: every stored connector configuration is encrypted with it and becomes unreadable if it changes. Each deployment gets its own — never share one across deployments.

Managing secrets with existingSecret

Any sensitive value can come from an existing Kubernetes Secret instead of a literal. Set the matching existingSecret field and leave the literal unset — this works with Vault, Sealed Secrets and the External Secrets Operator, and is the recommended shape in production. Available for deploymentJwtToken, jwt, connectorConfigEncryptionKey, adminCredentials, kora.database, kodansu.storage.aws, externalDatabase and postgresql.auth. The sources are mutually exclusive: an existingSecret combined with a literal password or url is rejected at render time.

Image pull

All images are published to a private GAR registry:
Popsink provides a service-account JSON token to pull them.
global.imagePullSecrets is required alongside imagePullSecret.create. The chart creates the secret but does not attach it to any pod, so without it every image fails with ImagePullBackOff. This is a known chart defect.

Data-plane database

Fine for evaluation. In production, prefer a managed instance with snapshots.

Schema registry (Kora)

Kora is Popsink’s schema registry: every connector registers the structure of what it reads there, and every target resolves schemas from it. It is enabled by default and it requires its own PostgreSQL role and database, which the chart does not create for you.
This is the step most first installs miss. The bundled PostgreSQL provisions the data-plane’s own role and database (postgresql.auth.*) and nothing else, so leaving kora.database unset points Kora at a role that exists nowhere. From chart 0.1.0-alpha.162 the install aborts with the instructions below; on earlier charts it installs a pod that crash-loops on:
Credentials can also come from a secret rather than a literal — use kora.database.existingSecret with secretKeys.password, or secretKeys.url for a full connection URL. Kora also supports an Oracle backend: kora.database.backend: oracle, port 1521, and database set to the service name (e.g. FREEPDB1). The chart selects the matching image automatically.

Broker storage (Kodansu)

Kodansu is a stateless Kafka broker that stores log segments in an object store. kodansu.storage.engine decides where records live, and both it and kodansu.storage.aws.region are required by the chart — the region on every path, including the ones that never read it.
The bucket must exist, be writable by the configured identity, and ideally have object versioning enabled — on S3. On ADLS Gen2 versioning is the opposite instruction; see below.
There is no PostgreSQL retention. The broker has been object-store only since Kodansu 0.7.0-beta.11, and a postgres:// storage engine is now refused as an unsupported storage URL rather than ignored — the pods do not start. The self-hosted wizard still offers the choice and still generates that URL; do not take it. postgresql.* and externalDatabase.* are a different thing entirely: the data plane’s own database, which every install needs.

Azure (ADLS Gen2)

Supported from Kodansu 1.0.0-alpha.17. The install recipe, with the credential variants side by side, is on the Kubernetes install page; what follows is what the chart cannot express.

Accepted URL forms

wasbs://, adl://, azure:// and a raw https://<account>.blob.core.windows.net/ are refused, even though the underlying object-store parser understands them: every extra alias is another spelling a deployment can drift onto, and wasbs:// is the legacy Blob scheme — it should fail loudly rather than be treated quietly as Gen2. A dfs host is resolved to <account>.blob.core.windows.net: the broker speaks the Blob endpoint against an ADLS Gen2 account, never the DFS one. Every kodansu.storage.tuning knob is scheme-independent and applies unchanged.

Credentials

The broker reads them from the environment only, via the object-store client’s own resolution. The chart has no kodansu.storage.azure block, so anything other than workload identity goes in through kodansu.extraEnvVarsSecret, extraEnvVarsCM or extraEnvVars. Whichever you use, the identity needs Storage Blob Data Contributor on the account or container. Owner is an ARM role and grants no data-plane access whatsoever; it fails as a 403 AuthorizationFailure that names no role.

Account settings are part of the contract

The object layout is create-only and immutable, and retention is implemented by delete. Four account settings therefore are not preferences: A freshly created StorageV2 account with nothing but --enable-hierarchical-namespace true --access-tier Hot already satisfies all four. Read the table as “do not turn these on” rather than “remember to turn these off”: the deployment that gets it wrong is the one that hardened an existing data-lake account. None of the four is detectable from the data plane, so there is no startup warning for any of them. Hierarchical namespace is the target. Deleting every blob under a prefix leaves the directories behind — not billed for capacity, absent from the listings the broker issues, untidy and nothing more. Flat Blob Storage is untested.

Private endpoints

Azure’s guidance for an ADLS Gen2 account is a private endpoint for both the blob and dfs sub-resources, because managing ACLs and creating or deleting directories need the DFS one. The broker does none of those three, so blob alone is sufficient. The failure worth knowing is the other direction: a network team that provisioned dfs only — the usual default for a data-lake account — leaves the broker unable to connect, with nothing in the error naming the sub-resource. If abfss:// times out or is refused while the account resolves, check this first.

Cost and Kotatsu

At the shape of a measured production S3 fleet, ADLS Gen2 comes to roughly 1.11× the S3 request bill, almost entirely the ~30 % hierarchical-namespace write premium. Two differences worth knowing: a list is billed as a read here (≈9× cheaper than on S3, where LIST is priced with PUT), and read/write transactions are metered per 4 MiB — so every 16 MiB merged segment write bills four times. Deletes are free, exactly as on S3. Kotatsu has no ADLS client: it reads S3 objects directly. Keep kotatsu.enabled: false on this path.

Bring your own Kafka

Stream browser (Kotatsu)

Kotatsu is optional and disabled by default. It is a read-only browser over the objects the broker wrote to S3, and it backs two things in the UI:
  • search, pagination and the timestamp column on the datamodel Stream tab;
  • the per-subscription target lag rows on the pipeline latency view.
Without it, the Stream tab falls back to a live Kafka read (no search, no pagination) and the target-lag rows are simply absent. Pipelines, connectors, subscriptions and delivery are unaffected — it is safe to leave disabled in production. Because it reads the bucket the broker writes, it only means anything on an s3:// engine — it has no ADLS client. To enable it:
That is the entire configuration. Bucket, cluster id, region, endpoint and credentials all default to the broker’s own (kodansu.storage.*, kodansu.clusterId) — the only combination that can work, since the two read and write the same objects. Set kotatsu.s3.* only to point Kotatsu at a replica of the bucket or at a separate read-only credential. On EKS with IRSA, leave the keys empty and annotate kotatsu.serviceAccount.annotations with the role ARN.
On charts before 0.1.0-alpha.162 Kotatsu defaulted to enabled, so an install that had not opted into S3 aborted with kotatsu.s3.bucket must be provided when kotatsu is enabled. Setting kotatsu.enabled: false is the correct workaround on those versions.

Ingress

ingress.enabled is off by default and we recommend leaving it that way: ingress in production usually needs company-specific annotations (cert-manager, WAF, allow-lists). Both shapes — chart-rendered and bring-your-own — are covered in step 4 of the install guide. The chart never installs an ingress controller. Bringing your own means pointing it at the <release>-data-plane service on port 80.

Resources and availability

Safety switches

A complete values.yaml

values.yaml

Most useful values

Further reading

Install the data plane on Kubernetes

The guided path, from the control-plane wizard to a Live deployment.

Troubleshooting

Symptom-to-cause table for the install and the first boot.

Kubernetes requirements

What the cluster, the network and your Popsink account must provide first.

Deployments and environments

How to map deployments onto your regions, networks and staging tiers.