To set up Apache Kafka for development in KRaft mode using Docker
This configuration sets up a single Kafka broker running in KRaft mode
services:
Defines the services that will be part of the Docker Compose app. Each service represents a container.
environment:
Defines environment variables that will be passed to the Kafka broker node or container
It specifies the roles that a Kafka node can perform. Here, it is configured to act as both a broker and a controller
Broker Role:
A broker handles client requests like producing and consuming messages, stores data on disk, manages topics, partitions, and logs, handles client connections, and replicates data across other brokers.
Controller Role:
A controller manages the metadata for the Kafka cluster, including brokers, topics, and partitions. It elects partition leaders, manages topic creation and deletion, and ensures metadata consistency across the cluster.
It specifies the names of the listeners that the Kafka controller will use to communicate with each other and with brokers.
It defines the listeners for the Kafka brokers and specifies how it will accept connections from clients and other brokers.
{Protocol}:{Host}://{Port}
Example:
PLAINTEXT:10.0.0.1//:9092 ---> listen for 10.0.0.1
PLAINTEXT://:9092 ---> listen for all available network interfaces
PLAINTEXT Listener:
MY_CONTROLLER Listener:
It specifies which security protocol each listener will use. Here, both MY_CONTROLLER and PLAINTEXT listeners will use the plaintext protocol.
MY_CONTROLLER:PLAINTEXT
This listener will use the plaintext protocol, meaning the communication is unencrypted. This listener is typically used for internal communication between Kafka controllers and brokers.
PLAINTEXT:PLAINTEXT
This is used in Apache Kafka's KRaft mode to define the set of controller nodes that participate in the quorum for voting to elect the Controller or Leader. Here, it specifies that the controller quorum consists of the broker itself, listening on port 9094.
Format: node_id@host:port
Example:
if you have three Kafka nodes acting as controllers, the configuration might look like this
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka-broker-1:9094,2@kafka-broker-2:9094,3@kafka-broker-3:9094
It specifies the addresses that clients and other brokers used to connect to the given node.
This listener will advertise the address kafka-broker-1:9092 to clients and other brokers. Clients and brokers will use this address to connect to the Kafka broker
This configuration allows Kafka to start with plaintext listeners defined in the KAFKA_CFG_LISTENERS property, which means that the communication between clients and the broker, as well as between brokers, is not encrypted.
It is typically a base64 format of UUID used to identify the Kafka cluster.This ID is crucial for the KRaft mode, where Kafka operates without Zookeeper and uses a quorum-based consensus algorithm for metadata management.
It can be generated using kafka-storage.sh tool provided with Kafka
> bin/kafka-storage.sh random-uuid
You can also use below Online tool for generating random uuid
https://www.fileformat.info/tool/guid-base64.htm
Maps port 9092 on the host to port 9092 on the container, allowing external access to the Kafka broker
Kafka UI Docker image
The Kafka UI Docker image from Provectus Labs makes it easy to set up a web-based interface for managing and monitoring your Kafka clusters.
Here's the complete Docker Compose file for a single Kafka broker running in KRaft mode
Happy Coding :)
- Install Docker Desktop using https://docs.docker.com/desktop/
- Create a docker-compose.yml file with the following content
This configuration sets up a single Kafka broker running in KRaft mode
version: '3'
services:
kafka-broker-1:
image: 'bitnami/kafka:3.3.1'
environment:
- KAFKA_ENABLE_KRAFT=yes
- KAFKA_CFG_PROCESS_ROLES=broker,controller
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=MY_CONTROLLER
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,MY_CONTROLLER://:9094
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=MY_CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_BROKER_ID=1
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka-broker-1:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka-broker-1:9092
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_KRAFT_CLUSTER_ID=d8zv92ecQk6ZrAAA35SDbw
ports:
- 9092:9092
As per above docker-compose.yml file
version: '3'
Specifies the version of the Docker Compose file format
Defines the services that will be part of the Docker Compose app. Each service represents a container.
kafka-broker-1:
Indicates name of service and also name of the Kafka broker container name
image: 'bitnami/kafka:3.3.1'
Specifies the name of the Kafka docker image used for this serviceenvironment:
Defines environment variables that will be passed to the Kafka broker node or container
KAFKA_ENABLE_KRAFT=yes
It Enables KRaft mode and allows Kafka to run without Zookeeper.KAFKA_CFG_PROCESS_ROLES=broker,controller
Broker Role:
A broker handles client requests like producing and consuming messages, stores data on disk, manages topics, partitions, and logs, handles client connections, and replicates data across other brokers.
A controller manages the metadata for the Kafka cluster, including brokers, topics, and partitions. It elects partition leaders, manages topic creation and deletion, and ensures metadata consistency across the cluster.
When a Kafka process is configured to act as both a broker and a controller, it handles both client requests and metadata management. This setup can simplify the deployment by reducing the number of separate processes needed
KAFKA_CFG_CONTROLLER_LISTENER_NAMES=MY_CONTROLLER
The property is a comma-separated list of listener names(you can use any names). These names must match the listener names defined in the KAFKA_CFG_LISTENERS property
KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,MY_CONTROLLER://:9094
It supports various protocols like PLAINTEXT, SSL, SASL and etc.
It supports various protocols like PLAINTEXT,SSL, SASL and
etc
{Protocol}:{Host}://{Port}
Example:
PLAINTEXT:10.0.0.1//:9092 ---> listen for 10.0.0.1
PLAINTEXT://:9092 ---> listen for all available network interfaces
PLAINTEXT Listener:
This listener will accept plaintext (unencrypted) connections on port 9092. It is typically used for client connections (producers and consumers).
MY_CONTROLLER Listener:
This listener will accept connections on port 9094 specifically for controller communication. It is used for internal communication between Kafka controllers and brokers
KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=MY_CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
This setting ensures that each listener uses the appropriate security protocol.
MY_CONTROLLER:PLAINTEXT
This listener will use the plaintext protocol, meaning the communication is unencrypted. This listener is typically used for internal communication between Kafka controllers and brokers.
PLAINTEXT:PLAINTEXT
This listener will also use the plaintext protocol. This listener is typically used for client connections (producers and consumers) and broker-to-broker communication.
KAFKA_CFG_BROKER_ID=1
Sets the broker ID to 1. Each broker in a Kafka cluster must have a unique IDKAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka-broker-1:9094
Example:
if you have three Kafka nodes acting as controllers, the configuration might look like this
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka-broker-1:9094,2@kafka-broker-2:9094,3@kafka-broker-3:9094
The above specified nodes form the quorum. A majority of these nodes must agree on any changes to the cluster metadata
KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka-broker-1:9092
ALLOW_PLAINTEXT_LISTENER=yes
This setting is typically used for development and testing environments
KAFKA_KRAFT_CLUSTER_ID=d8zv92ecQk6ZrAAA35SDbw
This is important for ensuring that all nodes in the cluster recognize each other and can participate in the quorum.
> bin/kafka-storage.sh random-uuid
You can also use below Online tool for generating random uuid
https://www.fileformat.info/tool/guid-base64.htm
ports:
- 9092:9092
Format: host_port:container_port
docker compose -f "docker-compose.yml" up -d --build // run to build and start the container
Use the below configurations to start the Kafka UI docker container
kafka-ui:
container_name: kafka-ui
image: 'provectuslabs/kafka-ui:latest'
ports:
- "8080:8080"
environment:
- KAFKA_CLUSTERS_0_BOOTSTRAP_SERVERS=kafka-broker-1:9092
- KAFKA_CLUSTERS_0_NAME=d8zv92ecQk6ZrAAA35SDbw
version: '3'
services:
kafka-broker-1:
image: 'bitnami/kafka:3.3.1'
environment:
- KAFKA_ENABLE_KRAFT=yes
- KAFKA_CFG_PROCESS_ROLES=broker,controller
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=MY_CONTROLLER
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,MY_CONTROLLER://:9094
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=MY_CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_BROKER_ID=1
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka-broker-1:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka-broker-1:9092
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_KRAFT_CLUSTER_ID=d8zv92ecQk6ZrAAA35SDbw
ports:
- 9092:9092
kafka-ui:
container_name: kafka-ui
image: 'provectuslabs/kafka-ui:latest'
ports:
- "8080:8080"
environment:
- KAFKA_CLUSTERS_0_BOOTSTRAP_SERVERS=kafka-broker-1:9092
- KAFKA_CLUSTERS_0_NAME=d8zv92ecQk6ZrAAA35SDbw
Here's the complete Docker Compose file for multiple Kafka brokers running in KRaft mode
version: '3'
services:
kafka-broker-1:
image: 'bitnami/kafka:3.3.1'
environment:
- KAFKA_ENABLE_KRAFT=yes
- KAFKA_CFG_PROCESS_ROLES=broker,controller
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=MY_CONTROLLER
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,MY_CONTROLLER://:9094
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=MY_CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_BROKER_ID=1
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka-broker-1:9094,2@kafka-broker-2:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka-broker-1:9092
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_KRAFT_CLUSTER_ID=d8zv92ecQk6ZrAAA35SDbw
ports:
- 9092:9092
kafka-broker-2:
image: 'bitnami/kafka:3.3.1'
environment:
- KAFKA_ENABLE_KRAFT=yes
- KAFKA_CFG_PROCESS_ROLES=broker,controller
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=MY_CONTROLLER
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,MY_CONTROLLER://:9094
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=MY_CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_BROKER_ID=2
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka-broker-1:9094,2@kafka-broker-2:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka-broker-2:9092
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_KRAFT_CLUSTER_ID=d8zv92ecQk6ZrAAA35SDbw
ports:
- 9093:9092
kafka-ui:
container_name: kafka-ui
image: 'provectuslabs/kafka-ui:latest'
ports:
- "8080:8080"
environment:
- KAFKA_CLUSTERS_0_BOOTSTRAP_SERVERS=kafka-broker-1:9092
- KAFKA_CLUSTERS_0_NAME=d8zv92ecQk6ZrAAA35SDbw
docker compose -f "docker-compose.yml" up -d --build // run to build and start the container
Apache Kafka for Developers Journey:
- Apache Kafka for Developers #1: Introduction to Kafka and Comparison with RabbitMQ
- Apache Kafka for Developers #2: Kafka Architecture and Components
- Apache Kafka for Developers #3: Kafka Topic Replication
- Apache Kafka for Developers #4: Kafka Producer and Acknowledgements
- Apache Kafka for Developers #5: Kafka Consumer and Consumer Group
- Apache Kafka for Developers #6: Kafka Consumer Partition Rebalancing
- Apache Kafka for Developers #7: Kafka Consumer Commit Offset
- Apache Kafka for Developers #8: Kafka Consumer Auto Offset Reset
- Apache Kafka for Developers #9: Replacing ZooKeeper with KRaft
- Apache Kafka for Developers #10:Setting Up Kafka Locally with Docker
- Apache Kafka for Developers #11: Creating and Managing Kafka Topics
- Apache Kafka for Developers #12: Setting Up a Kafka Producer in Node.js using KafkaJS
Comments
Post a Comment