Skip to content

Deploy on Kubernetes

operations
TL;DR

Deploy the release-matched Helm chart with three replicas, trusted TLS, stable encryption and signing keys, and S3-compatible recovery storage. Pin image digests and validate the exact values before installation. Keep a healthy majority during updates, and verify authentication, data access and recovery before sending production traffic.

ArchitectureReplicas coordinate metadata and share published object storage
Replicas coordinate metadata and share published object storageClients connect to a server replica. The replicas participate in metadata consensus, while published files live in shared object storage. Recovery also depends on local state, completed backups and original encryption keys.Cluster: separate server processesSQL clientSupported entry pointReplica ALocal state and serverReplica BLocal state and serverReplica CLocal state and serverObject storagePublished files andbackupsConnectMetadata consensusConsensusConsensusPublish / readReplicas coordinate metadata and share published object storageClients connect to a server replica. The replicas participate in metadata consensus, while published files live in shared object storage. Recovery also depends on local state, completed backups and original encryption keys.Cluster: separate server processesSQL clientSupported entry pointReplica ALocal state andserverReplica BLocal state andserverReplica CLocal state andserverObject storagePublished files andbackupsConnectMetadata consensusConsensusConsensusPublish / read
Each replica uses shared storage; one storage path is shown. Metadata quorum alone does not prove that every acknowledged recent row is recoverable.

The Helm chart configures a three-replica BoilStream cluster. Object storage holds published files and completed metadata backups. Hydrated historical files are caches; unpublished hot rows have a separate durability boundary. A persistent volume does not replace the configured recovery path. For write and recovery limits, see Reliability and completion.

Use the chart and example values supplied with your server release.

OCI artifact: oci://ghcr.io/boilingdata/charts/boilstream

  • Kubernetes 1.27 or newer.
  • cert-manager 1.13 or newer, or equivalent pre-created public and private TLS Secrets.
  • Envoy Gateway 1.2 or newer with the configured GatewayClass.
  • An S3-compatible bucket and workload identity or a Secret containing access_key and secret_key.
  • A superadmin password Secret.
  • A stable key Secret containing two distinct values:
    • encryption_key: 32 random bytes encoded as 64 hexadecimal characters;
    • token_signing_key: 32 random bytes encoded as base64.
    • cluster_token: an independent random token of at least 32 characters.

Keep both keys in an external secret manager and restore them unchanged. The encryption key protects recovery state. Changing the signing key invalidates outstanding HTTP ingestion, auth, and PGWire bootstrap tokens.

Shell
kubectl -n boilstream create secret generic boilstream-encryption \
--from-literal=encryption_key="$(openssl rand -hex 32)" \
--from-literal=token_signing_key="$(openssl rand -base64 32)" \
--from-literal=cluster_token="$(openssl rand -base64 32)"

Start from the EKS or Hetzner example shipped with the chart. The following fields define the required topology; replace every example identity and endpoint:

YAML
replicas: 3
domain: data.example.com
image:
repository: registry.example.com/boilstream
tag: <release-version>
# Replace this non-resolving example with the published release digest.
digest: sha256:0000000000000000000000000000000000000000000000000000000000000000
pullPolicy: IfNotPresent
configRenderer:
image:
# Replace with the published Python multi-architecture manifest digest.
digest: sha256:0000000000000000000000000000000000000000000000000000000000000000
s3:
endpoint: https://s3.example.com # empty for AWS S3
bucket: company-boilstream-prod
region: eu-central-1
prefix: prod/
forcePathStyle: true
existingCredsSecret: boilstream-s3-creds
accessKey: ""
secretKey: ""
encryptionKey:
existingSecret: boilstream-encryption
secretKey: encryption_key
tokenSigningKey:
secretKey: token_signing_key # same Secret by default
# Explicit operator acceptance: use only with a continuous-clock rate of 0.9–1.1.
# The chart default stays untrusted and rejects clustered startup.
quack:
sharedSupport:
profile: clock-profile-1
cpMetadata:
enabled: true
ducklakeMultiRaft: true
usersMultiRaft: true
tokenSecretKey: cluster_token # same Secret by default
s3Dr:
enabled: true
clusterId: company-prod-eu-1
backend: primary-s3
prefix: quack-dr
durabilityMode: strict
bootstrapMode: new
recoveryEpoch: 1
recoveryId: company-prod-eu-1-first-install
clusterTls:
enabled: true
issuer:
name: boilstream-ca-issuer
kind: ClusterIssuer
httpIngestion:
enabled: true
port: 8446
allowedOrigins:
- https://data.example.com
persistence:
enabled: false
gateway:
enabled: true
className: eg

The chart rejects partial clustered configurations. clusterId is the durable identity of one logical cluster and must never be reused for another. bootstrapMode: new with epoch 1 is only for the first installation. Once the first recovery generation exists, change the mode to restore. When image.digest is set, the chart renders repository@sha256:…; image.tag is ignored and remains only a readable release label. The config-renderer init image follows the same rule and must also be digest-pinned.

Shell
helm install boilstream oci://ghcr.io/boilingdata/charts/boilstream \
--version '<chart-version>' \
--namespace boilstream --create-namespace \
--values my-values.yaml \
--set-string image.digest='sha256:<release-image-digest>' \
--set-string configRenderer.image.digest='sha256:<python-image-digest>'

Before installing or upgrading, validate the exact values:

Shell
helm lint oci://ghcr.io/boilingdata/charts/boilstream \
--version '<chart-version>' \
--values my-values.yaml
Interface Endpoint Purpose
Web and auth https://data.example.com/ Sign-in, administration, and issuing credentials
HTTP/2 Arrow https://data.example.com:8446/ingest/<token> Browser and service ingestion with a scoped token
Kafka data.example.com:9092 Kafka-compatible produce and consume
FlightRPC data.example.com:50051 Arrow Flight ingestion
FlightSQL data.example.com:50250 Arrow Flight SQL queries
PGWire per-pod ports beginning at 15432 PostgreSQL clients using vended credentials
Managed DuckDB supplied by the BoilStream extension Native DuckDB catalog queries over server TLS and a short-lived capability

Use returned connection metadata instead of assembling PGWire or managed DuckDB endpoints. The public extension authenticates to BoilStream and handles the managed DuckDB endpoint, TLS verification, catalog identity, and capability refresh. External clients do not receive a reusable client certificate or private key.

Upgrade one replica at a time and wait for readiness before continuing:

Shell
helm upgrade boilstream oci://ghcr.io/boilingdata/charts/boilstream \
--version '<chart-version>' \
--namespace boilstream \
--values my-values.yaml \
--set-string image.digest='sha256:<release-image-digest>' \
--set-string configRenderer.image.digest='sha256:<python-image-digest>'
kubectl -n boilstream rollout status statefulset/boilstream

The default disruption budget keeps two of three replicas available during voluntary maintenance. Spread replicas across nodes or failure domains when the platform permits.

A client connected to a failed pod must reconnect; existing TCP sessions are not promised to migrate. With quorum, metadata operations continue through healthy replicas. Without quorum, metadata-dependent admission fails closed. A replacement pod catches up from peers without a PVC.

For complete local-state loss, fence the old incarnation, increment the recovery epoch once, set a new recovery ID on every replica, and restore with the original cluster ID, S3 prefix, and encryption key. The recovery point is the latest completed generation.

Shell
kubectl -n boilstream rollout status statefulset/boilstream
kubectl -n boilstream get pods,gateway,certificate
boilstream-admin cluster status

Before admitting production traffic, exercise authentication, catalog vending, every enabled ingestion/query interface, a leader failover, a rolling restart, and an S3-only restore in a staging cluster built from the same release artifacts.