基于docker容器方式搭建KRaft模式的kafka集群
使用 KRaft 模式(无 ZooKeeper 依赖)搭建 Kafka 集群是目前官方推荐的新架构,具有启动快、运维简单的优势
在 KRaft 模式下,Kafka 节点通常同时承担 Broker(消息代理)和 Controller(集群控制器)两种角色。为了搭建一个高可用的三节点集群,以下是完整的
docker-compose.yml 配置方案:1. 准备工作:生成全局 Cluster ID
在 KRaft 模式下,集群内所有节点必须共享同一个全局唯一的
CLUSTER_ID。请在执行 docker compose up 之前,先在终端运行以下命令生成一个 UUID:docker run --rm apache/kafka:latest kafka-storage.sh random-uuid
假设生成的 ID 为:
I18FDd0MRVicvuH03j17lw,请将其替换到下方配置中2. Docker Compose 配置文件
将以下内容保存为
docker-compose.yml:services:
# ================= Kafka 节点 1 =================
kafka-node1:
image: apache/kafka:latest
container_name: kafka-node1
ports:
- "9092:9092"
- "9093:9093"
environment:
# [核心] 全局唯一的集群 ID,三个节点必须完全一致
CLUSTER_ID: "I18FDd0MRVicvuH03j17lw"
# [角色] 同时作为数据节点(broker)和管理节点(controller)
KAFKA_PROCESS_ROLES: broker,controller
# [身份] 当前节点的唯一 ID,集群内不能重复
KAFKA_NODE_ID: 1
# [选举] 定义谁有权参与元数据投票 (格式: node_id@hostname:port)
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka-node1:9093,2@kafka-node2:9093,3@kafka-node3:9093
# [监听器] PLAINTEXT 用于业务数据传输,CONTROLLER 用于集群内部指令传递
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
# [公告地址] 告诉外部客户端通过哪个地址访问我
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092 #如果在容器内容访问,localhost改成宿主机的IP
# [安全映射] 协议映射
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
# [存储] 内部数据路径
KAFKA_LOG_DIRS: /var/lib/kafka/data
volumes:
- ./kafka_data/node1:/var/lib/kafka/data
restart: unless-stopped
# ================= Kafka 节点 2 =================
kafka-node2:
image: apache/kafka:latest
container_name: kafka-node2
ports:
- "9094:9092"
- "9095:9093"
environment:
CLUSTER_ID: "I18FDd0MRVicvuH03j17lw"
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_NODE_ID: 2
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka-node1:9093,2@kafka-node2:9093,3@kafka-node3:9093
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9094
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_LOG_DIRS: /var/lib/kafka/data
volumes:
- ./kafka_data/node2:/var/lib/kafka/data
restart: unless-stopped
# ================= Kafka 节点 3 =================
kafka-node3:
image: apache/kafka:latest
container_name: kafka-node3
ports:
- "9096:9092"
- "9097:9093"
environment:
CLUSTER_ID: "I18FDd0MRVicvuH03j17lw"
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_NODE_ID: 3
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka-node1:9093,2@kafka-node2:9093,3@kafka-node3:9093
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9096
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_LOG_DIRS: /var/lib/kafka/data
volumes:
- ./kafka_data/node3:/var/lib/kafka/data
restart: unless-stopped
3. 核心配置参数详解
CLUSTER_ID:KRaft 集群的“身份证”,所有节点必须配置相同KAFKA_PROCESS_ROLES: broker,controller:让节点同时承担数据读写和元数据管理的职责,这是 KRaft 高可用集群的标准做法KAFKA_CONTROLLER_QUORUM_VOTERS:定义了参与集群 Controller 选举的节点列表。格式为节点ID@容器主机名:9093,三个节点必须填写完全相同的投票列表KAFKA_NODE_ID:当前节点在集群中的唯一数字标识,分别设为 1、2、3- 端口规划:
9092是 Kafka 处理业务数据(生产者/消费者)的端口,9093是 KRaft Controller 节点之间进行内部通信和选举的端口
4. 启动与验证
1. 准备数据目录并赋权
mkdir -p ./kafka_data/{node1,node2,node3}
# apache/kafka 镜像默认使用 UID 1000 运行,需赋予目录写权限
sudo chown -R 1000:1000 ./kafka_data
2. 启动集群
docker compose up -d
3.测试消息生产与消费(基础连通性)
验证客户端能否正常向集群写入和读取数据。
. 启动生产者并发送消息:
kafka-console-producer.sh --bootstrap-server localhost:9092 --topic test-kraft-topic
在提示符 > 后输入几条消息,按回车发送:
>Hello Kafka KRaft
>Testing cross-node replication
. 启动消费者并读取消息:
新开一个终端,进入 kafka-node2 容器,启动消费者从头开始读取:
docker exec -it kafka-node2 bash
kafka-console-consumer.sh --bootstrap-server localhost:9092 \
--topic test-kraft-topic --from-beginning
预期结果:
消费者会立刻打印出刚才在生产者中输入的两条消息,证明跨节点的数据读写完全正常。
浙公网安备 33010602011771号