news 2026/5/24 17:31:51

基于Docker搭建kafka集群

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Docker搭建kafka集群

在单台服务器上使用 Docker Compose 部署 Kafka 3.7 KRaft 集群(3 节点)。所有 3 个 Kafka 节点(combined mode:broker + controller)运行在同一台物理机上,通过不同端口区分,适用于开发、测试或轻量级生产场景。

特点:

  • 单机部署,无需多台云服务器
  • 使用官方apache/kafka:3.7.0镜像(内置 JDK 17)
  • 启用SASL/PLAIN 认证
  • 支持从本机外部(如本地电脑)访问 Kafka

环境要求

  • 操作系统:CentOS 7/8/9、Ubuntu 等(本例以 CentOS 为例)
  • Docker ≥ 20.10
  • Docker Compose ≥ v2.0(或docker-compose
  • 可用内存 ≥ 4GB(建议 6GB+)

目录结构

kafka-cluster/ ├── docker-compose.yml ├── kafka/ │ └── kafka_server_jaas.conf └── client/ ├── kafka_admin_client_jaas.conf └── client.properties

第一步:创建配置文件

1. 创建 JAAS 文件(服务端)

mkdir-p /opt/kafka-cluster/{kafka,client}cd/opt/kafka-clustercat>kafka/kafka_server_jaas.conf<<EOF KafkaServer { org.apache.kafka.common.security.plain.PlainLoginModule required username="admin" password="StrongPassword123!" user_admin="StrongPassword123!" user_producer="StrongPassword456!" user_consumer="StrongPassword789!"; }; EOF

密码请按需修改,但所有节点必须一致。


2. 客户端认证文件(用于测试)

cat>client/kafka_admin_client_jaas.conf<<EOF KafkaClient { org.apache.kafka.common.security.plain.PlainLoginModule required username="admin" password="StrongPassword123!"; }; EOFcat>client/client.properties<<EOF security.protocol=SASL_PLAINTEXT sasl.mechanism=PLAIN sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="admin" password="StrongPassword123!"; EOF

第二步:编写docker-compose.yml(单机 3 节点)

vi docker-compose.yml

内容如下:

version:'3.8'services:kafka1:image:apache/kafka:3.7.0container_name:kafka1ports:-"9092:9092"environment:KAFKA_NODE_ID:1KAFKA_PROCESS_ROLES:"broker,controller"KAFKA_LISTENERS:"SASL_PLAINTEXT://:9092,PLAINTEXT://:9094,CONTROLLER://:9093"KAFKA_ADVERTISED_LISTENERS:"SASL_PLAINTEXT://host.docker.internal:9092,PLAINTEXT://kafka1:9094"KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:"SASL_PLAINTEXT:SASL_PLAINTEXT,PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT"KAFKA_CONTROLLER_QUORUM_VOTERS:"1@kafka1:9093,2@kafka2:9093,3@kafka3:9093"KAFKA_CONTROLLER_LISTENER_NAMES:"CONTROLLER"KAFKA_INTER_BROKER_LISTENER_NAME:"PLAINTEXT"KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR:3KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR:3KAFKA_CFG_AUTHORIZER_CLASS_NAME:"org.apache.kafka.metadata.authorizer.StandardAuthorizer"KAFKA_SASL_ENABLED_MECHANISMS:"PLAIN"KAFKA_SASL_MECHANISM_CONTROLLER_PROTOCOL:"PLAIN"KAFKA_OPTS:"-Djava.security.auth.login.config=/opt/kafka/config/kafka_server_jaas.conf"volumes:-./kafka/kafka_server_jaas.conf:/opt/kafka/config/kafka_server_jaas.confnetworks:-kafka-netextra_hosts:-"host.docker.internal:host-gateway"kafka2:image:apache/kafka:3.7.0container_name:kafka2ports:-"9093:9092"environment:KAFKA_NODE_ID:2KAFKA_PROCESS_ROLES:"broker,controller"KAFKA_LISTENERS:"SASL_PLAINTEXT://:9092,PLAINTEXT://:9094,CONTROLLER://:9093"KAFKA_ADVERTISED_LISTENERS:"SASL_PLAINTEXT://host.docker.internal:9093,PLAINTEXT://kafka2:9094"KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:"SASL_PLAINTEXT:SASL_PLAINTEXT,PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT"KAFKA_CONTROLLER_QUORUM_VOTERS:"1@kafka1:9093,2@kafka2:9093,3@kafka3:9093"KAFKA_CONTROLLER_LISTENER_NAMES:"CONTROLLER"KAFKA_INTER_BROKER_LISTENER_NAME:"PLAINTEXT"KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR:3KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR:3KAFKA_CFG_AUTHORIZER_CLASS_NAME:"org.apache.kafka.metadata.authorizer.StandardAuthorizer"KAFKA_SASL_ENABLED_MECHANISMS:"PLAIN"KAFKA_SASL_MECHANISM_CONTROLLER_PROTOCOL:"PLAIN"KAFKA_OPTS:"-Djava.security.auth.login.config=/opt/kafka/config/kafka_server_jaas.conf"volumes:-./kafka/kafka_server_jaas.conf:/opt/kafka/config/kafka_server_jaas.confnetworks:-kafka-netextra_hosts:-"host.docker.internal:host-gateway"kafka3:image:apache/kafka:3.7.0container_name:kafka3ports:-"9094:9092"environment:KAFKA_NODE_ID:3KAFKA_PROCESS_ROLES:"broker,controller"KAFKA_LISTENERS:"SASL_PLAINTEXT://:9092,PLAINTEXT://:9094,CONTROLLER://:9093"KAFKA_ADVERTISED_LISTENERS:"SASL_PLAINTEXT://host.docker.internal:9094,PLAINTEXT://kafka3:9094"KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:"SASL_PLAINTEXT:SASL_PLAINTEXT,PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT"KAFKA_CONTROLLER_QUORUM_VOTERS:"1@kafka1:9093,2@kafka2:9093,3@kafka3:9093"KAFKA_CONTROLLER_LISTENER_NAMES:"CONTROLLER"KAFKA_INTER_BROKER_LISTENER_NAME:"PLAINTEXT"KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR:3KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR:3KAFKA_CFG_AUTHORIZER_CLASS_NAME:"org.apache.kafka.metadata.authorizer.StandardAuthorizer"KAFKA_SASL_ENABLED_MECHANISMS:"PLAIN"KAFKA_SASL_MECHANISM_CONTROLLER_PROTOCOL:"PLAIN"KAFKA_OPTS:"-Djava.security.auth.login.config=/opt/kafka/config/kafka_server_jaas.conf"volumes:-./kafka/kafka_server_jaas.conf:/opt/kafka/config/kafka_server_jaas.confnetworks:-kafka-netextra_hosts:-"host.docker.internal:host-gateway"networks:kafka-net:driver:bridge

关键说明:

配置说明
host.docker.internal线下想使用且没有域名的话,可以替换成公网ip(在实验时,博主是配置的公网IP)
端口映射9092→9092,9093→9092,9094→9092→ 外部通过宿主机IP:9092/9093/9094访问
KAFKA_ADVERTISED_LISTENERS必须设为host.docker.internal,否则客户端连错地址
所有节点共用同一 JAAS 文件用户密码一致

第三步:启动集群

cd/opt/kafka-cluster docker compose up -d

如果提示docker compose不存在,请安装:

sudocurl-L"https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname-s)-$(uname-m)"-o /usr/local/bin/docker-composesudochmod+x /usr/local/bin/docker-compose

查看日志

docker compose logs -f kafka1

成功标志

[main] INFO ... Kafka is now ready to serve requests

首次启动可能需要 30~60 秒完成 controller 选举。


第四步:验证集群(从宿主机外部访问)

假设你的服务器公网 IP 是142.12.153.25,则外部可通过:

  • 142.12.153.25:9092
  • 142.12.153.25:9093
  • 142.12.153.25:9094

连接 Kafka。

1. 创建 Topic(在服务器本地执行)

使用 PLAINTEXT 端口 9094 创建 topic(无需认证,内部专用):

docker run --rm -it\--network kafka-cluster_kafka-net\apache/kafka:3.7.0\/opt/kafka/bin/kafka-topics.sh\--create\--topic test-single-host\--partitions3\--replication-factor3\--bootstrap-server kafka1:9094,kafka2:9094,kafka3:9094#列出topicdocker run --rm -it\--network kafka-cluster_kafka-net\-v$(pwd)/client/kafka_admin_client_jaas.conf:/tmp/jaas.conf\-v$(pwd)/client/client.properties:/tmp/client.properties\apache/kafka:3.7.0bash-c" export KAFKA_OPTS='-Djava.security.auth.login.config=/tmp/jaas.conf' && \ /opt/kafka/bin/kafka-topics.sh \ --list \ --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 \ --command-config /tmp/client.properties "#生产者生产消息echo"Hello Kafka"|docker run --rm -i\--network kafka-cluster_kafka-net\-v$(pwd)/client/kafka_admin_client_jaas.conf:/tmp/jaas.conf\-v$(pwd)/client/client.properties:/tmp/client.properties\apache/kafka:3.7.0bash-c" export KAFKA_OPTS='-Djava.security.auth.login.config=/tmp/jaas.conf' && \ /opt/kafka/bin/kafka-console-producer.sh \ --bootstrap-server kafka1:9092 \ --producer.config /tmp/client.properties \ --topic test-single-host "#消费者消费消息docker run --rm -it\--network kafka-cluster_kafka-net\-v$(pwd)/client/kafka_admin_client_jaas.conf:/tmp/jaas.conf\-v$(pwd)/client/client.properties:/tmp/client.properties\apache/kafka:3.7.0bash-c" export KAFKA_OPTS='-Djava.security.auth.login.config=/tmp/jaas.conf' && \ /opt/kafka/bin/kafka-console-consumer.sh \ --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 \ --consumer.config /tmp/client.properties \ --topic test-single-host \ --from-beginning "


2. 从本地电脑(线下)测试生产消息

# 替换 YOUR_SERVER_PUBLIC_IPSERVER_IP="142.12.153.25"echo"Hello from local!"|docker run --rm -i\-v$(pwd)/client/kafka_admin_client_jaas.conf:/tmp/jaas.conf\-v$(pwd)/client/client.properties:/tmp/client.properties\apache/kafka:3.7.0bash-c" export KAFKA_OPTS='-Djava.security.auth.login.config=/tmp/jaas.conf' && \ /opt/kafka/bin/kafka-console-producer.sh \ --bootstrap-server 115.159.155.193:9092 \ --producer.config /tmp/client.properties \ --topic test-single-host "

3. 消费消息(本地)

docker run --rm -it\-v$(pwd)/client/kafka_admin_client_jaas.conf:/tmp/jaas.conf\-v$(pwd)/client/client.properties:/tmp/client.properties\apache/kafka:3.7.0bash-c" export KAFKA_OPTS='-Djava.security.auth.login.config=/tmp/jaas.conf' && \ /opt/kafka/bin/kafka-console-consumer.sh \ --bootstrap-server${SERVER_IP}:9092 \ --consumer.config /tmp/client.properties \ --topic test-single-host \ --from-beginning \ --timeout-ms 10000 "

如果看到消息,说明单机 Kafka 集群工作正常!

上面23均未检验,仅在本地客户端通过过公网ip的方式连上kafka并进行生产和消费消息


安全与网络建议

  1. 防火墙:只开放

    9092-9094

    给可信 IP

    sudofirewall-cmd --permanent --add-port=9092-9094/tcpsudofirewall-cmd --reload
  2. 不要用于公网生产环境:建议仅限内网或测试

  3. 升级为 SASL_SSL:如需加密传输


停止容器

docker compose down

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/21 1:22:28

揭秘边缘端Agent数据持久化难题:4步实现低功耗高可靠存储

第一章&#xff1a;边缘端Agent数据持久化的挑战与意义在物联网和边缘计算快速发展的背景下&#xff0c;边缘端Agent作为连接终端设备与云端服务的核心组件&#xff0c;承担着数据采集、本地处理与状态同步等关键任务。由于边缘设备常面临网络不稳定、资源受限和突发断电等问题…

作者头像 李华
网站建设 2026/5/22 1:48:04

从采集到洞察:工业互联网Agent数据分析的7个必知步骤

第一章&#xff1a;工业互联网Agent数据分析的核心价值在工业互联网体系中&#xff0c;Agent作为部署于边缘设备或关键节点的智能代理程序&#xff0c;承担着数据采集、实时处理与本地决策的重要职责。其产生的数据不仅涵盖设备运行状态、环境参数和操作日志&#xff0c;还包含…

作者头像 李华
网站建设 2026/5/18 15:43:26

别再盲目部署!边缘AI推理速度优化的6大实战误区与避坑指南

第一章&#xff1a;边缘AI推理速度优化的核心挑战在边缘计算场景中&#xff0c;AI模型的推理速度直接影响用户体验与系统响应能力。受限于边缘设备的算力、内存和功耗&#xff0c;如何在资源约束下实现高效推理成为关键难题。硬件资源受限带来的性能瓶颈 边缘设备如树莓派、Jet…

作者头像 李华
网站建设 2026/5/24 2:10:31

从零开始:Keil5下载与STM32项目实战指南

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个基于STM32的LED闪烁项目&#xff0c;包含以下步骤&#xff1a;1. 提供Keil5的官方下载链接和安装指南&#xff1b;2. 配置Keil5开发环境&#xff0c;包括安装STM32支持包&a…

作者头像 李华
网站建设 2026/5/22 16:08:39

ElementPlus在企业级后台管理系统中的最佳实践

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个电商后台管理系统&#xff0c;使用ElementPlus实现以下功能&#xff1a;1. 商品管理&#xff08;CRUD操作&#xff09;&#xff1b;2. 订单处理流程&#xff1b;3. 数据统计…

作者头像 李华
网站建设 2026/5/15 3:35:12

下一代自动驾驶Agent感知技术趋势:2025年前必须掌握的5大核心技术

第一章&#xff1a;自动驾驶Agent环境感知技术演进全景自动驾驶系统的核心能力之一是环境感知&#xff0c;即通过多模态传感器理解周围动态与静态物体的状态。随着深度学习与边缘计算的发展&#xff0c;感知技术已从传统的规则驱动方法演进为以神经网络为主导的端到端模型架构。…

作者头像 李华