Kafka 集群开启 SASL 认证实战(二):外置 ZooKeeper 之 kafka 与 zk 间认证

Kafka 集群开启 SASL 认证实战(二):外置 ZooKeeper 之 kafka 与 zk 间认证

很多场景下 Kafka broker 对内网客户端可以不加认证,但 kafka 与 ZooKeeper 之间的通道必须锁 ------zk 里存着 broker 元数据和消费者位移,谁都能连上去 rmr / 一键清空。本篇讲外置 ZooKeeper 场景下只做 kafka↔zk 间 SASL 认证的最小配置,不动 broker 对客户端的协议,业务应用零改造。配置在 ZooKeeper 3.6.3 + Kafka 2.5.1 生产集群验证通过。

系列导航

篇 场景 链接
一 内置 ZooKeeper 的 Kafka 集群加 SASL 全套配置 已发布,点击直达
二 外置 ZooKeeper,只做 kafka↔zk 之间认证(本篇) 本篇
三 外置 ZooKeeper 完整版:quorum 认证 + zk ACL + 客户端认证 敬请期待

一、适用场景与版本要求

适用判断:客户端都在可信内网、等保只要求"关键链路认证"时,用本篇最小方案;如果 kafka 也要对客户端加密码,直接看第三篇。

硬性限制 :ZooKeeper 3.6.0 及以上 ------sessionRequireClientSASLAuth 等参数 3.6 才有。本文以 3.6.3 为例。

最终效果:zk 的 quorum(集群节点间)通信和 server-client 通信都要求 SASL,kafka 用账号连 zk,其他未认证客户端一律拒绝。

二、停服务

登录每台服务器,先杀 Kafka 再杀 ZooKeeper:

bash 复制代码
[root@kafka01 ~]# jps
29552 Jps
11923 QuorumPeerMain
13053 Kafka
[root@kafka01 ~]# kill -9 11923 13053

三、ZooKeeper 侧配置

进入 zk 配置目录(本文密码用 Test@12345 演示,上线前替换):

bash 复制代码
cd /opt/module/apache-zookeeper-3.6.3-bin/conf

3.1 zk_server.jaas(服务端身份 + 客户端账号库)

text 复制代码
Server {
    org.apache.zookeeper.server.auth.DigestLoginModule required
    user_super="Test@12345"
    user_zkclient="Test@12345";
};

QuorumServer {
    org.apache.zookeeper.server.auth.DigestLoginModule required
    user_quorum="Test@12345";
};

QuorumLearner {
    org.apache.zookeeper.server.auth.DigestLoginModule required
    username="quorum"
    password="Test@12345";
};

三个段的分工:

段 用途
Server zk 对客户端提供服务时的认证,user_xxx 是账号库(kafka 用 zkclient 这个账号连入)
QuorumServer zk 集群选举/复制通道的服务端身份
QuorumLearner follower/observer 节点作为 learner 连 leader 时的客户端身份

3.2 zk_client.jaas(zk 自带命令行工具用)

text 复制代码
Client {
    org.apache.zookeeper.server.auth.DigestLoginModule required
    username="zkclient"
    password="Test@12345";
};

3.3 java.env(挂载 JAAS 的 JVM 参数)

bash 复制代码
vi java.env
bash 复制代码
SERVER_JVMFLAGS="-Djava.security.auth.login.config=/opt/module/apache-zookeeper-3.6.3-bin/conf/zk_server.jaas"
CLIENT_JVMFLAGS="${CLIENT_JVMFLAGS} -Djava.security.auth.login.config=/opt/module/apache-zookeeper-3.6.3-bin/conf/zk_client.jaas"

3.4 zoo.cfg 追加认证参数

properties 复制代码
# ===== Server-Server (quorum) 互相认证 =====
quorum.auth.enableSasl=true
quorum.auth.learnerRequireSasl=true
quorum.auth.serverRequireSasl=true
quorum.auth.learner.saslLoginContext=QuorumLearner
quorum.auth.server.saslLoginContext=QuorumServer
# 建议设为集群节点数 n*2
quorum.cnxn.threads.size=6

# ===== Server-Client 之间认证 =====
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
# 强制客户端必须 SASL 认证(zk >= 3.6.0)
sessionRequireClientSASLAuth=true

sessionRequireClientSASLAuth=true 是"锁死"的关键------不开的话,不带认证的客户端照样能连。zk 集群里 observer 节点没有投票权,但不影响本配置。

把 4 个文件拷贝到 zk 集群所有节点。

四、Kafka 侧配置

4.1 kafka.jaas(只需要 Client 段)

bash 复制代码
cd /opt/module/kafka_2.12-2.5.1/config
vi kafka.jaas
text 复制代码
Client {
    org.apache.kafka.common.security.plain.PlainLoginModule required
    username="zkclient"
    password="Test@12345";
};

注意 LoginModule 用的是 kafka 包里的 PlainLoginModule (不是 zk 的 DigestLoginModule)------kafka 连 zk 走 PLAIN 机制即可,账号对应 zk_server.jaas 里的 user_zkclient。

4.2 server.properties

追加一行:

properties 复制代码
zookeeper.client.sasl=true

同样检查并注释掉残留的旧配置:

properties 复制代码
#advertised.host.name=192.168.10.31
#advertised.port=9092

4.3 启动脚本挂 JAAS

修改 kafka/bin/kafka-run-class.sh(一处生效,所有 kafka 命令行工具都会带上):

bash 复制代码
vi /opt/module/kafka_2.12-2.5.1/bin/kafka-run-class.sh

在脚本靠前位置添加:

bash 复制代码
export KAFKA_OPTS="-Djava.security.auth.login.config=/opt/module/kafka_2.12-2.5.1/config/kafka.jaas"

kafka.jaas 拷贝到所有 broker 节点,server.properties 按各节点 IP 调整后分发。

五、启动与验证

先 zk 后 kafka:

bash 复制代码
cd /opt/module/apache-zookeeper-3.6.3-bin
./bin/zkServer.sh start

cd /opt/module/kafka_2.12-2.5.1
./bin/kafka-server-start.sh -daemon ./config/server.properties

验证三连:

bash 复制代码
# 1. broker 正常注册(说明 kafka->zk 认证通了)
./bin/kafka-topics.sh --bootstrap-server 192.168.10.31:9092 --list

# 2. 裸连 zk 被拒(不带 JAAS 的 zkCli 直接连会被 sessionRequireClientSASLAuth 挡掉)
./bin/zkCli.sh -server 192.168.10.31:2181

# 3. 命令行生产消费不受影响(本方案不动客户端协议)
./bin/kafka-console-producer.sh --broker-list 192.168.10.31:9092 \
  --producer.config ./config/producer.properties --topic test-topic

六、踩坑清单

坑 现象 解法
zk 版本低于 3.6.0 sessionRequireClientSASLAuth 不生效或不识别 先升级 zk
忘注释 advertised.host.name broker 起来了客户端连不上 注释掉旧配置
java.env 路径写错 zk 起不来,日志报找不到 LoginModule 核对绝对路径
只改了部分 zk 节点 集群选举分裂、脑裂 所有 zk 节点同步改
kafka.jaas 用了 zk 的 DigestLoginModule broker 连 zk 认证失败 用 kafka 的 PlainLoginModule

总结

外置 zk 只锁 kafka↔zk 通道的方案,改动集中在 zk 侧 4 个文件(jaas×2 + java.env + zoo.cfg)+ kafka 侧 2 处(kafka.jaas + zookeeper.client.sasl),客户端协议完全不动,业务零感知。下一篇是本系列终章:在外置 zk 场景上叠加 kafka 客户端认证和 zk ACL 白名单,做到"内外都锁死",敬请期待。

你们 zk 集群现在有没有裸奔?有没有被误操作删过节点的经历?评论区聊聊。


系列文章配置在 ZooKeeper 3.6.3 + Kafka 2.5.1 生产集群验证;示例密码请替换后使用。

相关推荐
方方洛8 小时前
ray教程-13-RayTrain与分布式训练
人工智能·分布式·机器学习
黄俊懿15 小时前
【架构师从入门到进阶】第七章:缓存和存储的优化思路——第一节:缓存概述
数据结构·数据库·分布式·缓存·架构·系统架构·1024程序员节
红海云15 小时前
两台DGX Spark部署DeepSeek的实战边界
大数据·分布式·spark
ly768919 小时前
Kafka 消费者重试与死信:Spring for Apache Kafka 的边界设计
spring·kafka·apache·并发消费·消费者重试·死信主题·位移提交
GlobalInfo1 天前
上新 | 全球及中国起重机摄像系统行业研究报告(2026版):市场现状、行业前景与占有率分析
大数据·分布式·微服务·ai·相机
方方洛1 天前
ray教程-11-可观测性与调试
人工智能·分布式·机器学习
samforce2 天前
为什么微服务会退化成“分布式单体”?——软件架构里的嵌套率传导定律
人工智能·分布式·微服务·架构·软件架构·结构认知
我不会起名字3222 天前
Kafka 顺序消息为什么乱了:分区数变化与重试的 3 类原因
kafka·消息队列·顺序·排查
每天一道题2 天前
Kafka 是如何工作的?从 Broker、Partition、Offset 到 Consumer Group
分布式·kafka
用户1494484813202 天前
为什么大厂很少直接用 2PC/TCC?聊聊分布式事务在真实业务里的落地套路
分布式·后端