Skip to content

Apache Kafka — Streaming Platform ​

Kafka provides the durable event-streaming layer: Flink SQL jobs consume and produce topics, and the kafka-to-iceberg bridge streams topic rows into the Iceberg lakehouse. It is deployed by the Strimzi cluster operator in KRaft mode (no ZooKeeper) as a single dual-role node, sized for local clusters.

  • Chart: strimzi-kafka-operator 1.1.0 from strimzi.io/charts/
  • Kafka version: 4.3.0 (KRaft, KafkaNodePool with controller + broker roles)
  • Cluster CR: templates/kafka-cluster.yaml (Kafka + KafkaNodePool + KafkaTopic)
  • Bootstrap address (in-cluster): aetherlake-kafka-bootstrap:9092
  • Ingress: none — external clients connect through the TLS + SCRAM-SHA-512 nodeport listener, not an HTTP ingress route

Architecture ​

Key settings (core-data-stack/values.yaml → kafka) ​

SettingDefaultDescription
kafka.enabledtrueToggle the Strimzi operator dependency and the Kafka cluster resources
kafka.cluster.nameaetherlakeKafka CR name; brokers become <name>-kafka-bootstrap
kafka.cluster.version4.3.0Kafka version (must be supported by the pinned Strimzi operator)
kafka.cluster.replicas1Dual-role node count
kafka.cluster.storageSize10GiPersistent log storage per node
kafka.cluster.storageClassName""Empty = cluster default StorageClass
kafka.cluster.replicationFactor1Topic/default replication; raise together with replicas
kafka.external.enabledtrueTLS + SCRAM-SHA-512 nodeport listener for clients outside the cluster
kafka.external.usernameexternal-producerKafkaUser holding the external credentials
kafka.topicseventsKafkaTopic resources reconciled by the topic operator

WARNING

The internal plain listener has no authentication — it is cluster-internal only and never exposed through any ingress. External access goes through the external listener (TLS + SCRAM-SHA-512); see below. Strimzi ACLs are cluster-wide, so they are intentionally not enabled (they would also lock down the internal listeners) — the SCRAM identity is the external boundary.

Querying topics with Trino ​

Topics are exposed as Trino tables through the kafka connector catalog, so data streamed by Flink SQL jobs is queryable with ordinary SQL:

sql
SELECT * FROM kafka.aetherlake.events LIMIT 10;

Column schemas come from the JSON table descriptions in trino.kafka.tableDescriptions (see Trino). Add a description file whenever a new topic should be queryable.

Control Panel ​

The Control Panel ships a Kafka view (/kafka, linked from the Overview dashboard): cluster status and version, broker health, and the topic list with partitions, replicas, config and reconciliation conditions — served through /api/kafka against the Strimzi CRs, protected by the usual session auth. The Flink SQL editor also lists topics and inserts a Kafka source-table template on click.

Producing from outside the cluster ​

The external listener (port 9094, type: nodeport, TLS, SCRAM-SHA-512) accepts authenticated clients from outside; on Docker Desktop the bootstrap is localhost:<nodePort>.

  1. Gather connection material:
bash
NODEPORT=$(kubectl get svc aetherlake-kafka-external-bootstrap -n aetherlake \
  -o jsonpath='{.spec.ports[0].nodePort}')
kubectl get secret aetherlake-cluster-ca-cert -n aetherlake \
  -o jsonpath='{.data.ca\.crt}' | base64 -d > cluster-ca.crt
kubectl get secret external-producer -n aetherlake \
  -o jsonpath='{.data.sasl\.jaas\.config}' | base64 -d   # sasl.jaas.config value
  1. Build a truststore from the cluster CA (any JDK):
bash
keytool -importcert -noprompt -alias ca -file cluster-ca.crt \
  -keystore client.p12 -storetype PKCS12 -storepass changeit
  1. Client properties:
properties
security.protocol=SASL_SSL
sasl.mechanism=SCRAM-SHA-512
sasl.jaas.config=<value from the external-producer secret>
ssl.truststore.location=client.p12
ssl.truststore.password=changeit
ssl.truststore.type=PKCS12
# The broker certificate does not carry the nodeport address; disable
# hostname verification for local testing.
ssl.endpoint.identification.algorithm=
  1. Produce (any Kafka client; console example):
bash
kafka-console-producer.sh --bootstrap-server localhost:$NODEPORT \
  --topic events --command-config producer.properties

Wrong credentials fail with SaslAuthenticationException — the listener rejects anything that is not a valid KafkaUser.

Operations ​

bash
# Broker status (Strimzi adds the strimzi.io/kind label to node pods)
kubectl get pods -n aetherlake -l strimzi.io/cluster=aetherlake

# Kafka resource status as reported by the operator
kubectl get kafka aetherlake -n aetherlake -o jsonpath='{.status.conditions[*].type}'

# Create an extra topic
kubectl apply -n aetherlake -f - <<'EOF'
apiVersion: kafka.strimzi.io/v1
kind: KafkaTopic
metadata:
  name: my-topic
  labels:
    strimzi.io/cluster: aetherlake
spec:
  partitions: 3
  replicas: 1
EOF

Control Panel ​

The /kafka view in the Control Panel provides live visibility into cluster health, broker statuses, and topic configurations:

Kafka Management UI

Released under the Business Source License 1.1.