大数跨境
0
0

告别ZooKeeper依赖!KRaft模式Kafka集群搭建完整教程

告别ZooKeeper依赖!KRaft模式Kafka集群搭建完整教程 Annie出海
2025-09-26
5
导读:立即阅读

docker-compose方式部署kafka集群


Kafka 4.0引入了KRaft模式(Kafka Raft Metadata Mode),它使Kafka集群不再依赖ZooKeeper进行元数据管理。


KRaft模式简化了Kafka部署和管理,不需要额外配置ZooKeeper服务,使得集群的配置和运维更加高效。


本文将介绍如何配置一个基于KRaft模式的Kafka集群,步骤简单明了。


我们将从零开始,介绍如何配置Kafka集群并进行测试,包括遇到的权限问题以及如何通过自定义工具简化测试命令。


今日文章阅读福利:《运维入门大礼包

扫码添加小助理,发送暗号运维,即可获取。


一、KRaft模式简介

KRaft(Kafka Raft Metadata Mode)是Kafka在4.0版本引入的一个新特性,旨在替代传统的依赖ZooKeeper的架构。


在KRaft模式下,Kafka使用内建的Raft协议来管理元数据和集群协调,而不需要外部的ZooKeeper服务。


主要特点:


  • 不再依赖ZooKeeper。


  • 使用Kafka自带的Raft协议处理元数据和控制器选举。


  • 简化了集群配置,降低了维护成本。



二、集群配置

1.配置主机


在本例中,我们使用了3台主机,每台主机上启动一个Kafka容器,形成一个简单的KRaft模式集群。


  • 主机1(IP:172.16.0.106):配置为Kafka节点0。


  • 主机2(IP:172.16.0.107):配置为Kafka节点1。


  • 主机3(IP:172.16.0.108):配置为Kafka节点2。


2.Kafka配置


在docker-compose.yml中,我们配置了3个Kafka节点的容器,采用KRaft模式,并设置了必要的环境变量来启动集群。


这是第一个节点:0


services:  kafka-0:    image: bitnami/kafka:4.0.0    container_name: kafka-0    ports:      - "9092:9092"      - "9093:9093"    environment:      - KAFKA_CFG_NODE_ID=0      - KAFKA_CFG_PROCESS_ROLES=controller,broker      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@172.16.0.106:9093,1@172.16.0.107:9093,2@172.16.0.108:9093      - KAFKA_KRAFT_CLUSTER_ID=abcdefghijklmnopqrstuv      - KAFKA_CFG_LISTENERS=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://172.16.0.106:9092      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER      - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=PLAINTEXT      - KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=3      - KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3      - KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR=2    volumes:      - /data/kafka/kafka-0:/bitnami/kafka

这是第一个节点:1


services:  kafka-1:    image: bitnami/kafka:4.0.0    container_name: kafka-1    ports:      - "9092:9092"      - "9093:9093"    environment:      - KAFKA_CFG_NODE_ID=1      - KAFKA_CFG_PROCESS_ROLES=controller,broker      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@172.16.0.106:9093,1@172.16.0.107:9093,2@172.16.0.108:9093      - KAFKA_KRAFT_CLUSTER_ID=abcdefghijklmnopqrstuv      - KAFKA_CFG_LISTENERS=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://172.16.0.107:9092      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER      - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=PLAINTEXT      - KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=3      - KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3      - KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR=2    volumes:      - /data/kafka/kafka-0:/bitnami/kafka

这是第三个节点:2


services:  kafka-2:    image: bitnami/kafka:4.0.0    container_name: kafka-2    ports:      - "9092:9092"      - "9093:9093"    environment:      - KAFKA_CFG_NODE_ID=0      - KAFKA_CFG_PROCESS_ROLES=controller,broker      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@172.16.0.106:9093,1@172.16.0.107:9093,2@172.16.0.108:9093      - KAFKA_KRAFT_CLUSTER_ID=abcdefghijklmnopqrstuv      - KAFKA_CFG_LISTENERS=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://172.16.0.108:9092      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER      - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=PLAINTEXT      - KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=3      - KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3      - KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR=2    volumes:      - /data/kafka/kafka-0:/bitnami/kafka

每个Kafka节点的配置都类似,只是KAFKA_CFG_NODE_IDKAFKA_CFG_ADVERTISED_LISTENERS不同。


3.数据持久化


通过Docker的volumes配置,我们将每个容器的数据目录挂载到宿主机上,从而实现数据持久化。如下所示:


volumes:  - /data/kafka/kafka-0:/bitnami/kafka

这意味着Kafka容器中的数据会存储在宿主机的/data/kafka/kafka-0目录中,即使容器停止或删除,数据也不会丢失。



三、遇到的权限问题及解决方法

在配置过程中,我遇到了一个权限问题:容器内的脚本无法删除临时文件或执行一些操作。


解决方法:


1.容器内操作权限问题:由于容器内没有sudo权限,导致无法执行一些文件删除操作。


解决方案是在宿主机上执行相关操作,使用docker exec执行命令时确保使用正确的权限。


2.文件系统权限:挂载到容器的宿主机目录/data/kafka/kafka-0必须确保有正确的读写权限,否则Kafka容器无法正常写入数据。


确保宿主机上的目录拥有正确的权限,例如使用chmod命令修改目录权限。



四、集群测试

测试Kafka集群是否成功部署,我们使用了以下步骤:


1.启动Kafka容器:使用docker-compose up分别启动集群。


2.这个问题!Kafka在Docker容器中运行时,通常会以1001这个用户ID(UID)来启动,而宿主机上的目录默认可能是root用户所有。


这就导致了Kafka在容器内无法对挂载的目录进行写入或修改,因为容器用户与宿主机目录的所有者不同。


解决方法:


你可以通过更改宿主机目录的所有者为容器内的Kafka用户(即UID 1001),这样容器就能够正确地访问和修改该目录。


执行以下命令:


sudo chown -R 1001:1001 ./kafka_data

这将会把宿主机上的./kafka_data目录的所有者更改为UID 1001,即容器内的Kafka用户。


这样,容器就可以在该目录下创建所需的文件了。


为什么要这么做?


  • Kafka容器默认使用1001用户运行,而宿主机的目录默认是root用户拥有。


  • Docker容器内的进程没有root权限,因此无法修改宿主机上的目录(除非你将宿主机目录的权限改为所有人都能写入)。


  • 使用chown -R 1001:1001将目录所有者改为容器内Kafka用户,使容器能够访问和操作该目录。


1.检查Kafka主题:


使用kafka-topics.sh --list --bootstrap-server localhost:9092命令查看集群中的所有主题。


2.创建测试主题:


通过kafka-topics.sh --create --topic test --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1创建一个名为test的测试主题。


docker exec -it kafka-0 bashkafka-topics.sh --create --topic test --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1kafka-topics.sh --list --bootstrap-server localhost:9092


五、自定义工具简化命令

为了方便测试,我编写了一个自定义工具脚本kafka-tools.sh,通过简单的命令执行Kafka常用操作:


1.宿主机(容器外部)执行:vim kafka-tools.sh


#!/bin/bash
# Kafka操作函数
# 列出所有主题kt() {  kafka-topics.sh --list --bootstrap-server localhost:9092}
# 生产消息到指定主题kp() {  if [ -z "$1" ]; then    echo "请指定主题名称!"    return 1  fi  kafka-console-producer.sh --broker-list localhost:9092 --topic "$1"}
# 消费指定主题的消息kc() {  if [ -z "$1" ]; then    echo "请指定主题名称!"    return 1  fi  kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic "$1" --from-beginning}
# 删除指定主题kd() {  if [ -z "$1" ]; then    echo "请指定主题名称!"    return 1  fi  kafka-topics.sh --bootstrap-server localhost:9092 --topic "$1" --delete}
# 查看指定主题描述kdesc() {  if [ -z "$1" ]; then    echo "请指定主题名称!"    return 1  fi  kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic "$1"}
# 创建一个新主题create_topic() {  if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then    echo "请提供主题名称、分区数和副本数!"    return 1  fi  kafka-topics.sh --create --topic "$1" --bootstrap-server localhost:9092 --partitions "$2" --replication-factor "$3"}
# 提示echo "✅ Kafka 自定义工具函数已经加载成功(使用方式如下):"echo "  kt --list            ----查看所有主题"echo "  kp my-topic          ----使用主题生产"echo "  kc my-topic          ----使用主题消费"echo "  kd my-topic          ----删除主题"echo "  kdesc my-topic       ----主题描述"echo "  create_topic my-topic 3 1 ----创建主题 (例如:3个分区,1个副本)"

2.将.sh文件移动到容器内部:


docker cp kafka-tools.sh kafka-0:/tmp/kafka-tools.shdocker cp kafka-tools.sh kafka-1:/tmp/kafka-tools.shdocker cp kafka-tools.sh kafka-2:/tmp/kafka-tools.sh
docker cp kafka-tools.sh kafka-0:/tmp/kafka-tools.shdocker exec -it kafka-0 bashsource /tmp/kafka-tools.sh

3.进入容器 :

docker exec -it kafka-0 bash

4.执行:

 source /tmp/kafka-tools.sh

提示:则执行成功


生命周期是每次容器内执行后(容器不死,方便测试,复杂参数的命令还是需要自己去写或者完善该脚本)



使用方法:


  • kt --list:查看所有Kafka主题。


  • kp <topic>:生产消息到指定主题。


  • kc <topic>:消费指定主题的消息。


  • kd <topic>:删除指定的主题。


  • kdesc <topic>:查看指定主题的描述。


通过这些简化命令,我可以在容器内快速执行Kafka操作,而不需要记住每个命令的详细参数。


加载成功后,你可以直接在容器内使用简化命令,极大地方便了测试和管理Kafka集群。



六、总结

本文介绍了如何配置KRaft模式的Kafka 4.0集群,并解决了容器内的权限问题。


通过自定义工具脚本,我们将常用的Kafka操作简化为一系列简单的命令,使得集群管理更加高效。


KRaft模式是Kafka 4.0中的重要特性,它的引入让Kafka不再依赖ZooKeeper,简化了集群的部署和管理。


希望本文能帮助你顺利部署并管理KRaft模式的Kafka集群。


 文章声明 
本文部分素材整理自网络公开领域,版权归原作者所有,由Linux实战训练营排版成文,转载请注明出处,侵删。
图片
新盟教育自2009年成立,至今已有16年的IT培训经验。在长期的发展过程中,我们始终秉持“以学生发展为宗旨,以教学质量为生命,以团队精神为法宝,以服务态度为基础”的理念,踏踏实实地开展教学工作。

新盟教育是华为HALP授权培训机构,也是腾讯课堂101认证机构,还曾与思科官方、阿里云官方有过合作。这些合作与授权,代表着行业对我们的认可。

在课程设置上,我们以华为、思科课程为主,同时也开设了Linux、红帽、K8s微服务等课程。为了让学员能更好地适应企业工作,我们还提供企业实操的选修知识讲座。通过这些课程,我们希望帮助学员掌握扎实的IT技能。

成立至今,我们已经为18万多名学员提供了IT技术教育和指导,向Cisco、Google、联想、方正等上百家知名企业输送了很多IT人才,在合作伙伴和学员中都收获了不错的评价。

如果你有志于在IT领域发展,新盟教育愿意成为你成长路上的助力,帮你实现职业目标。
图片

【声明】内容源于网络
0
0
Annie出海
跨境分享地 | 持续输出实用建议
内容 42355
粉丝 2
Annie出海 跨境分享地 | 持续输出实用建议
总阅读242.1k
粉丝2
内容42.4k