Kafka Karapace
Overview
This SecureAnyCloud image is a single-VM event-streaming appliance. It pairs the Apache Kafka broker with Karapace, the open-source, Confluent-compatible Schema Registry and Kafka REST proxy from Aiven.
Kafka provides durable publish/subscribe messaging. Karapace adds schema governance (Avro, JSON Schema, Protobuf) and an HTTP path for producing and consuming, so applications can talk to Kafka over plain REST or with strongly typed schemas.
What you get:
- Apache Kafka 4.2.0 (Scala 2.13) at
/opt/kafka, running as a single-VM KRaft broker and controller (kafka.service), with no ZooKeeper - Karapace 6.2.0 Schema Registry (
karapace-registry.service) and Kafka REST proxy (karapace-rest.service), installed in a dedicated Python 3.12 virtual environment - OpenJDK 17 JRE as the Kafka runtime, and a Python 3.12 venv at
/opt/karapace/venvas the Karapace runtime - A SASL/SCRAM-SHA-256 broker on
127.0.0.1:9092, bound to localhost only and reachable off-host through the authenticated Karapace REST proxy - An nginx authentication layer that exposes the Schema Registry on TCP 8081 and the Kafka REST proxy on TCP 8082
- A pre-created SecureAnyCloud topic (1 partition, replication 1)
- A single per-VM SecureAnyCloud password, generated at first boot, that secures Kafka SCRAM and the Karapace HTTP basic authentication terminated by nginx
- Credentials at
/stage/scripts/kafka-karapace-credentials.log - 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key, and a VNet with a subnet.
Standard_B2s (4 GB RAM) suits development, test, single-tenant streaming and proof-of-concept workloads. For production, move to D4s or D8s and increase KAFKA_HEAP_OPTS in /etc/default/kafka.
Configure the network security group (NSG) to allow inbound 22/tcp from your management CIDR. Allow 8081/tcp (Schema Registry) and 8082/tcp (Kafka REST proxy) from your client CIDR.
The Kafka broker listens on 127.0.0.1:9092 only and is not exposed directly. Off-host clients use the authenticated REST proxy, or you can add an external SASL_SSL listener yourself.
Step 1-3: Deploy and connect over SSH
Deploy the image from the Azure Marketplace, then connect to the VM over SSH:
ssh azureuser@<vm-ip>Check service status and versions
Confirm that all four services are active, and check the installed Kafka and Karapace versions.
for s in kafka karapace-registry karapace-rest nginx; do printf '%-26s : ' "$s.service"; systemctl is-active "$s.service" done echo "Kafka : $(ls /opt/kafka/libs/ | grep -oE '^kafka-clients-[0-9.]+' | head -1 | sed 's/kafka-clients-//')" echo "Karapace: $(/opt/karapace/venv/bin/pip show karapace 2>/dev/null | awk '/^Version:/{print $2}')"Read the per-VM credentials
The first-boot service generates a unique password for this VM. The same password authenticates the Kafka broker and the Karapace endpoints. Read it from the credentials file:
sudo cat /stage/scripts/kafka-karapace-credentials.logNote these values: KAFKA_ADMIN_USER and KAFKA_ADMIN_PASSWORD, KARAPACE_USER and KARAPACE_PASSWORD, and the SCHEMA_REGISTRY_URL and REST_PROXY_URL endpoints.
Produce and consume with Kafka (SASL/SCRAM)
The broker rejects anonymous clients. Build an admin client configuration from the per-VM password, then produce a message to the SecureAnyCloud topic and consume it back.
PASS=$(sudo grep '^KAFKA_ADMIN_PASSWORD=' /stage/scripts/kafka-karapace-credentials.log | cut -d= -f2-)
cat > /tmp/sac.properties <<EOF security.protocol=SASL_PLAINTEXT sasl.mechanism=SCRAM-SHA-256 sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="sac" password="${PASS}"; EOF echo -n 'anonymous client : ' timeout 12 /opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server 127.0.0.1:9092 >/dev/null 2>&1 && echo 'ACCEPTED' || echo 'REJECTED (auth required)' MSG="sac-demo-$(date +%s)" echo "${MSG}" | /opt/kafka/bin/kafka-console-producer.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/sac.properties --topic sac echo "produced: ${MSG}" echo -n 'consumed: ' timeout 20 /opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/sac.properties --topic sac --from-beginning --timeout-ms 12000 2>/dev/null | grep -F "${MSG}" | head -1 rm -f /tmp/sac.propertiesRegister and read a schema in the Karapace Schema Registry
The Schema Registry is exposed on port 8081 behind nginx basic authentication. Register an Avro schema for a subject, then read it back.
The commands below run on the VM and use 127.0.0.1. From another host, replace it with your VM's IP address, shown as <vm-ip> elsewhere in this guide.
PASS=$(sudo grep '^KARAPACE_PASSWORD=' /stage/scripts/kafka-karapace-credentials.log | cut -d= -f2-)
echo -n 'anonymous GET /subjects : HTTP ' curl -s -o /dev/null -w '%{http_code}\n' -m 8 http://127.0.0.1:8081/subjects
echo 'register schema for subject demo-value:' curl -s -u "sac:${PASS}" -H 'Content-Type: application/vnd.schemaregistry.v1+json' \
-d '{"schema":"{\"type\":\"record\",\"name\":\"demo\",\"fields\":[{\"name\":\"id\",\"type\":\"string\"}]}"}' \
http://127.0.0.1:8081/subjects/demo-value/versions echo;
echo 'read it back:' curl -s -u "sac:${PASS}" http://127.0.0.1:8081/subjects
echo curl -s -u "sac:${PASS}" http://127.0.0.1:8081/subjects/demo-value/versions/1 echoProduce over HTTP with the Karapace REST proxy
The Kafka REST proxy on port 8082 lets applications produce and consume without a Kafka client library. Produce a JSON record to the SecureAnyCloud topic over HTTP.
PASS=$(sudo grep '^KARAPACE_PASSWORD=' /stage/scripts/kafka-karapace-credentials.log | cut -d= -f2-)
echo -n 'anonymous GET /topics : HTTP ' curl -s -o /dev/null -w '%{http_code}\n' -m 8 http://127.0.0.1:8082/topics
echo 'produce a JSON record to topic sac:' curl -s -u "sac:${PASS}" -H 'Content-Type: application/vnd.kafka.json.v2+json' \
-d '{"records":[{"value":{"event":"order.created","id":42}}]}' \
http://127.0.0.1:8082/topics/sac echo;
echo 'topics visible to the REST proxy:' curl -s -u "sac:${PASS}" http://127.0.0.1:8082/topics echoSecurity notes
- No default credentials. The image ships none. Each VM generates its own SecureAnyCloud password at first boot (openssl rand) and writes it to /stage/scripts/kafka-karapace-credentials.log (mode 0600, root only).
- One password, two layers. The password secures the Kafka broker (SASL/SCRAM-SHA-256) and the Karapace Schema Registry and REST proxy (HTTP basic authentication via nginx). After deployment, split them if you prefer separate credentials.
- Keep the broker on localhost. Kafka listens on
127.0.0.1:9092. The only off-host endpoints are the authenticated registry (8081) and REST proxy (8082). For direct broker access from other hosts, add an externalSASL_SSLlistener in/opt/kafka/config/server.propertiesand terminate TLS. - Rotate the password. Update the Kafka SCRAM credential (kafka-configs.sh --alter --add-config 'SCRAM-SHA-256=...' --entity-type users --entity-name SecureAnyCloud) and the nginx htpasswd file (htpasswd /etc/nginx/karapace.htpasswd SecureAnyCloud).
Next steps
- Add topics with
kafka-topics.sh --create, and add brokers to scale the cluster horizontally. - Set the registry's compatibility mode (
BACKWARDby default) per subject withPUT /config/<subject>. - Point your producers and consumers at the Schema Registry (
http://<vm-ip>:8081) for schema validation, or at the REST proxy (http://<vm-ip>:8082) for HTTP-native streaming.
This image is backed by 24/7 SecureAnyCloud support.
Deploy on Azure
Launch Apache Kafka + Karapace on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com