Linux系统安装Kafka单机教程(带有kerberos和scram认证)
1.搭建Kafka环境
1.1 下载Kafka压缩包
-
去Kafka官网下载自己需要的版本安装包:https://kafka.apache.org/community/downloads/

我这里直接下的中间的Scala 2.12 - kafka_2.12-3.5.1.tgz (asc, sha512)
当然,也可以通过wget命令直接在linux上下载,我是window上下载完传输到Linux上 -
在Linux上解压缩
我这里是打算将所有Kafka相关安装到/home/cloud_nms/kafka/文件夹下,所以将压缩包放在/home/cloud_nms/kafka/下,执行命令如下
tar -zxvf kafka_2.12-3.5.0.tgz

1.2 修改配置文件
Kafka需要安装zookeeper使用,但kafka集成zookeeper,在单机搭建时可直接使用自带的Kafka。使用需配置kafka_2.12-2.5.0/config 下的“zookeeper.properties”
cd kafka_2.12-3.5.0/config/
注:经过部署发现 kafka必须配置zookeeper 否则无法启动 无论是单机还是集群,必须,必须,必须开启
配置"zookeeper.properties"。修改dataDir和clientPort。前者是快照存放地址(自己随意配置),后者是客户端连接zookeeper服务的端口。默认端口2181 最好默认不修改
vim zookeeper.properties
我的修改如下:

配置kafka_2.12-2.5.0/config下的“server.properties”,修改log.dirs和zookeeper.connect。前者是日志存放文件夹,后者是zookeeper连接地址(端口和clientPort保持一致)。
vim server.properties


地址配置的是centos(centos是我在/etc/hosts文件里面配置的127.0.0.1),这里localhost只能本机连接使用,若想其他连接建议更换成自定义的,我后续换为了centos,下面截图不在更改,还是localhost,大家记得别用就好,用自定义的

注意!!!!!!!!!!!!:listeners=SASL_PLAINTEXT://centos:9092,这里我配置的是centos,需要在客户端(要连kafka的机器)的/etc/hosts文件中加入如下:
139.19.71.86 centos

前面为ip,后面为自定义名称
若想不在客户端加配置,这里需要更改 server.properties配置为如下():
SASL认证:
listeners=SASL_PLAINTEXT://0.0.0.0:9092
advertised.listeners=SASL_PLAINTEXT://139.19.71.86:9092
账号密码或无认证:
listeners=PLAINTEXT://0.0.0.0:9092
advertised.listeners=PLAINTEXT://139.19.71.86:9092
1.3 启动Kafka和Zookeeper
(1) 开启kafka自带zookeeper
前台运行:
./bin/zookeeper-server-start.sh ./config/zookeeper.properties
后台运行:
./bin/zookeeper-server-start.sh -daemon ./config/zookeeper.properties
关闭zookeeper(仅用于出错关闭重启,实际上启动成功就行了):
bin/zookeeper-server-stop.sh
(2) 开启kafka
以下命令是在安装路径下执行的,我这里是/home/cloud_nms/kafka/
前台运行:
bin/kafka-server-start.sh config/server.properties
后台运行:
./bin/kafka-server-start.sh -daemon ./config/server.properties
关闭Kafka(仅用于出错关闭重启,实际上启动成功就行了):
bin/kafka-server-stop.sh
使用jps命令查看是否正常了
jps

1.4 Kafka测试
(1)创建kafka主题
貌似不同版本的命令有所不同,我这里用的3.5,就碰到了不支持zookeeper
旧版本命令:
./bin/kafka-topics.sh --create --zookeeper 192.168.118.128:2181 --replication-factor 1 --partitions 1 --topic test
#也可以使用下面命令 与上面命令等效
./bin/kafka-topics.sh --create --zookeeper web:2181 --replication-factor 1 --partitions 1 --topic test
报错如下:

原因:新版本的kafka,已经不需要依赖zookeeper来创建,可以使用如下
./bin/kafka-topics.sh --create --bootstrap-server centos:9092 --replication-factor 1 --partitions 1 --topic test

旧板与新版的主要差别在于--zookeeper变为了--bootstrap-server,后面命令只介绍我是用的3.5版本,旧命令不再赘述,想用自己替换一下就好了
(2)显示kafka所有主题
./bin/kafka-topics.sh --list --bootstrap-server centos:9092

(3)查看某个主题的详细信息:
./bin/kafka-topics.sh --bootstrap-server centos:9092 --describe --topic test

(4)创建kafka生产者:
./bin/kafka-console-producer.sh --broker-list centos:9092 --topic test

Ctrl + D 发送文件结束符 (EOF):这个组合键告诉生产者进程“输入流已经结束”。生产者接收到这个信号后,会触发一个优雅的关闭过程。它会等待内部缓冲区(RecordAccumulator)中所有尚未发送的消息被后台的 Sender 线程发送出去,并收到 Kafka 集群的确认(根据你的 acks 设置),然后才正常退出。这确保了数据的完整发送
(5)创建kafka消费者
./bin/kafka-console-consumer.sh --bootstrap-server centos:9092 --topic test --from-beginning
--from-beginning 是从头开始消费

Ctrl + C停止退出
(6)删除topic
./bin/kafka-topics.sh --bootstrap-server centos:9092 --delete --topic test

到此,Kafka单机安装完毕
2.安装kerberos
2.1 安装kerberos服务端
前提:必须能连接外网,因为网上教程全是直接用yum安装的,内网的话,直接传安装包,解压出来和教程对不上
yum install krb5-server

发现是镜像仓库不对,按照网上教程禁用fastestmirror和重新下载阿里云、清华镜像都不能用,直到询问同事,发现是镜像文件和服务器不匹配。。。。。
解决方法如下:
uname -r

我这是ARM服务器,使用的一直是x86镜像,所以出问题,如果查询出来有x86就可以直接用这个镜像了
2.2 重新配置yum镜像源:
如果上述yum install krb5-server执行成功可以跳过这一步
- 备份原yum镜像:
cd /etc/yum.repos.d
mkdir backup
mv *.repo backup/
- 下载最新yum源:
对应服务器下载镜像源,自己的是哪个,可以通过uname -r查看
x86:
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
arm:
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-altarch-7.repo
- 清除缓存和重新生成缓存
yum clean all
yum makecache
这里,如果yum源文件是错的,在执行yum makecache,会报错404,按照上述改一下就行了,报错如下

源文件是对的,执行如下:

问题解决,继续执行安装kerberos指令
sudo yum install krb5-server

中途Is this ok [y/d/N]: 直接输入y
- 修改配置文件
sudo vim /etc/krb5.conf
这里我只改了如下配置:

相关参数说明:
[logging]:日志的位置
[libdefaults]:每种连接的默认配置
dns_lookup_realm:是否通过 dns 查找需使用的 releam
ticket_lifetime:凭证的有效时限,一般为 24 小时
renew_lifetime:凭证最长可以被延期的时限,一般为一周。当凭证过期之后,对安全认证的服务后续访问就会失败
forwardable:ticket 是否可以被转发(如果用户已经有了一个TGT,当他登入到另一个远程系统,KDC会为他重新创建一个TGT,而不需要让用户重新进行身份认证)
rdns:如果为 true,则除根据 hostname 正向查找外,同时反向查找对应的 principal。如果 dns_canonicalize_hostname 设置为 false,则此标志不起作用。默认值为 true。
pkinit_anchors:受信任锚(根)证书的位置;如果用户在命令行上指定X509_anchors,则不使用该配置。
default_realm:默认的 realm,必须跟要配置的 realm 名称一致
default_ccache_name:指定默认凭据缓存的名称。默认值为 DEFCCNAME
[realms]:列举使用的 realm
kdc:kdc 运行的机器
admin_server:kdc 数据库管理服务运行的机器
[domain_realm]:配置 domain name 或 hostname 对应的 releam
详细解释如下:krb5.conf官方文档
sudo vim /var/kerberos/krb5kdc/kdc.conf
这个文件我没有更改

相关参数说明:
[kdcdefaults]:KDC 默认配置
kdc_ports:UDP 端口号
kdc_tcp_ports:TCP 端口号
[realms]:realm 数据库配置
master_key_type:主密钥的密钥类型;默认值为 aes256-cts-hmac-sha1-96。
acl_file:用于指定哪些用户可以访问 kdc 数据库的控制文件;如果不需要现在用户访问,该值可以设为空
dict_file:字典文件位置,该文件中的单词不能被用于密码;如果文件为空,或者没有为用户分配策略,则不会执行密码字典检查。
admin_keytab:KDC 进行校验的 keytab。
supported_enctypes:支持的加密方式,默认为 aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal
详细解释如下:kdc.conf官方文档
- 创建数据库
kdb5_util create -s -r KAFKA.COM
这里创建的数据库名字要和krb5.conf中配置的一样
若初始错误数据库:删库命令如下:
sudo kdb5_util destroy -f -r KAFKA.COM

这里创建报错配置有问题,无效的配置,原因:krb5.conf少加了结尾的},正常不会报错
- 启动服务
#开启自启动
[root@kafka01 ~]# systemctl enable krb5kdc.service
Created symlink /etc/systemd/system/multi-user.target.wants/krb5kdc.service → /usr/lib/systemd/system/krb5kdc.service.
#开启Kerberos服务
[root@kafka01 ~]# systemctl start krb5kdc.service
#开启kadmin服务
[root@kafka01 ~]# systemctl enable kadmin.service
Created symlink /etc/systemd/system/multi-user.target.wants/kadmin.service → /usr/lib/systemd/system/kadmin.service.
[root@kafka01 ~]# systemctl start kadmin.service
启动报错如下:

查看报错详细信息命令如下:
sudo journalctl -xe -u krb5kdc.service

可以看到是因为没有初始化KAFKA.COM数据库,如果初始化和上面配置文件中一样,就不会有这个问题
- 创建账号
创建存储位置和赋权,后面导出账号秘钥要用:
# 以 root 身份创建目录
sudo mkdir -p /root/data
# 确保目录权限允许写入(root 默认就有)
sudo chmod 700 /root/data
进入kadmin.local界面:
sudo kadmin.local

创建账号(kadmin.local界面):
add_principal root/admin@KAFKA.COM
add_principal kafka-client@KAFKA.COM


输入完,自己输入两次相同的密码即可,我这里就只先添加了这一个账号
导出账号秘钥(kadmin.local界面):
xst -norandkey -k /root/data/root.keytab root/admin@KAFKA.COM
xst -norandkey -k /root/data/kafka-client.keytab kafka-client@KAFKA.COM
exit是退出kadmin.local命令
2.3 安装kerberos客户端
yum install krb5-workstation

#客户端可以是用kadmin命令
[root@kafka01 ~]# kadmin
kinit(在客户端认证用户)
[root@kafka02 ~]# kinit root/admin@KAFKA.COM #输入密码认证完成
#查看当前的认证用户
[root@kafka01 ~]# klist
#kdestroy(删除当前的认证缓存)
[root@kafka01 ~]# kdestroy

3.kafka开启kerberos认证
3.1 创建 keytab
- 创建keytab存放路径,并给路径写入权限
sudo mkdir -p /root/data
sudo chmod 700 /root/data
- 进入kerberos服务器端(Kerberos 服务端上使用 kadmin.local,安装了 Kerberos Client 的机器上可以使用 kadmin)这里建议使用 kadmin.local便于账号管理,理论上kadmin也可以进行后续,就是有权限限制,比较麻烦,所以还是用kadmin.local吧
sudo kadmin.local
- 创建客户端和服务器端账号和导出keytab文件
kadmin.local: add_principal -randkey kafka-server/centos@KAFKA.COM
kadmin.local: add_principal -randkey kafka-client/centos@KAFKA.COM
kadmin.local: xst -k /root/data/kafka-server.keytab kafka-server/centos@KAFKA.COM
kadmin.local: xst -k /root/data/kafka-client.keytab kafka-client/centos@KAFKA.COM
执行addprinc命令,用于创建账号,如果没指定-randkey或-nokey参数,需要设置密码
执行xst导出命令,用于导出指定账号对应的keytab文件,如果没有使用-norandkey,会导致密码被随机重置
这里的创建不建议使用上述使用的root/adminlocalhost@KAFKA,容易乱,还是老实建两个吧,还有这里的localhost是因为我的/etc/hosts文件里配的localhost,如需要更改名称,可以自行配置,也可以直接用ip
3.2 配置
- 拷贝krb5.conf及keytab文件到所有安装Kafka的机器,把文件都放到Kafka的 config/kerberos 目录下(kerberos 目录需新建)
将keytab文件复制到config/kerberos下
sudo cp /root/data/kafka-server.keytab /home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/
sudo cp /root/data/kafka-client.keytab /home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/
将krb5.conf文件复制到config/kerberos下
sudo cp /etc/krb5.conf /home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/
- 配置权限:
给复制过来的加读权限,一定要加,因为我调了一天,一直报没有kafkaclient
sudo chmod 644 /home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/kafka-server.keytab
sudo chmod 644 /home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/kafka-client.keytab
sudo chmod 644 /home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/krb5.conf
3.2.1 Kafka服务端配置
- 复制 config/server.properties(复制动作能帮助我们在 认证/非认证 模式自由切换)重命名为 config/server-sasl.properties:
sudo cp /home/cloud_nms/kafka/kafka_2.12-3.5.0/config/server.properties /home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/server-sasl.properties
这里也可以选择不复制,直接在原文件更改,但是建议复制,因为确实能 认证/非认证 模式自由切换,认证启动使用sasl文件,否则使用原文件
- 在复制的server-sasl.properties下加如下配置:
listeners=SASL_PLAINTEXT://centos:9092
security.inter.broker.protocol=SASL_PLAINTEXT
sasl.mechanism.inter.broker.protocol=GSSAPI
sasl.enabled.mechanisms=GSSAPI
sasl.kerberos.service.name=kafka-server
这里第一行在之前安装kerberos时已更改过,这次更改为SASL_PLAINTEXT://localhost:9092就行,因为之前配的是PLAINTEXT://localhost:9092,还有这里的sasl.kerberos.service.name=kafka-server要记住,而且这里的service.name要和kafka-server-jaas.conf中principal的/前名称一致,后面要用
因为这里创建的是GSSAPI认证方式,在server-sasl.properties加入上述配置后,记得上面的listeners和advertised.listeners也要更改为对应的SASL_PLAINTEXT,如下图:

- 新建 kafka-server-jaas.conf 文件,该文件也放到 Kafka 的 config/kerberos 目录下
在 config/kerberos 目录下输入创建文件命令
sudo touch kafka-server-jaas.conf
- 加入如下内容:
KafkaServer {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/kafka-server.keytab"
storeKey=true
useTicketCache=false
principal="kafka-server/centos@KAFKA.COM";
};
这里不建议加#注释,感觉有时候识别不出来
我的如下:

- 复制 bin/kafka-server-start.sh 脚本重命名为 bin/kafka-server-start-sasl.sh
sudo cp /home/cloud_nms/kafka/kafka_2.12-3.5.0/bin/kafka-server-start.sh /home/cloud_nms/kafka/kafka_2.12-3.5.0/bin/kafka-server-start-sasl.sh
- kafka-server-start-sasl.sh倒数第二行增加如下配置
修改文件命令:
sudo vim kafka-server-start-sasl.sh
添加如下内容:
#-Dzookeeper.sasl.client=false zk没有开启认证就设置false
export KAFKA_OPTS="-Dzookeeper.sasl.client=false -Dzookeeper.sasl.client.username=zk-server -Djava.security.krb5.conf=/home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/krb5.conf -Djava.security.auth.login.config=/home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/kafka-server-jaas.conf -Dsun.security.krb5.debug=true"
-Dsun.security.krb5.debug=true是用来调试看报错的,可以不加
结果如下:

3.2.2 Kafka客户端配置
该配置主要为了使用 bin/kafka-topics.sh、bin/kafka-console-consumer.sh、kafka-console-producer.sh 等命令。
- 新建 client.properties 文件,该文件也放到 Kafka 的 config/kerberos 目录下:
在config/kerberos 目录下,执行创建文件:
sudo touch client.properties
加入如下内容:
security.protocol=SASL_PLAINTEXT
sasl.mechanism=GSSAPI
sasl.kerberos.service.name=kafka-server
这里的sasl.kerberos.service.name一定要和server-sasl.properties中一致
- 新建 kafka-client-jaas.conf 文件,该文件也放到 Kafka 的 config/kerberos 目录下
在config/kerberos 目录下,执行创建文件:
sudo touch kafka-client-jaas.conf
加入如下内容:
KafkaClient {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/kafka-client.keytab"
storeKey=true
useTicketCache=false
principal="kafka-client/centos@KAFKA.COM";
};
- 复制 bin/kafka-topics.sh、kafka-console-producer.sh、bin/kafka-console-consumer.sh 脚本,分别重命名为 bin/kafka-topics-sasl.sh、kafka-console-producer-sasl.sh、bin/kafka-console-consumer-sasl.sh
sudo cp /home/cloud_nms/kafka/kafka_2.12-3.5.0/bin/kafka-topics.sh /home/cloud_nms/kafka/kafka_2.12-3.5.0/bin/kafka-topics-sasl.sh
sudo cp /home/cloud_nms/kafka/kafka_2.12-3.5.0/bin/kafka-console-producer.sh /home/cloud_nms/kafka/kafka_2.12-3.5.0/bin/kafka-console-producer-sasl.sh
sudo cp /home/cloud_nms/kafka/kafka_2.12-3.5.0/bin/kafka-console-consumer.sh /home/cloud_nms/kafka/kafka_2.12-3.5.0/bin/kafka-console-consumer-sasl.sh
- kafka-topics-sasl.sh、kafka-console-producer-sasl.sh和kafka-console-consumer-sasl.sh倒数第二行增加如下配置:
#三个文件倒数第二行 新增以下内容
export KAFKA_OPTS="-Djava.security.krb5.conf=/home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/krb5.conf -Djava.security.auth.login.config=/home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/kafka-client-jaas.conf"
效果如下:

3.3 启动测试
- 运行 bin/kafka-server-start-sasl.sh 启动 Kafka 集群:
cd /home/cloud_nms/kafka/kafka_2.12-3.5.0
./bin/kafka-server-start-sasl.sh -daemon config/kerberos/server-sasl.properties

- 运行 bin/kafka-topics-sasl.sh 查看 topic 列表信息:
./bin/kafka-topics-sasl.sh --list --bootstrap-server centos:9092 --command-config config/kerberos/client.properties

- 运行 kafka-console-producer-sasl.sh 生产消息
./bin/kafka-console-producer-sasl.sh --broker-list centos:9092 --topic test --producer.config config/kerberos/client.properties

- 运行 bin/kafka-console-consumer-sasl.sh 消费消息:
./bin/kafka-console-consumer-sasl.sh --bootstrap-server centos:9092 --topic test --from-beginning --consumer.config config/kerberos/client.properties

至此,kafka开启kerberos认证完结,抱歉,后面开启认证不够详细,因为被权限的问题困扰一天,整到晚上8点才发现权限问题,中途遇到的报错我尽可能的写在下面,希望对你们有帮助
4. kafka由kerberos认证改为SCRAM认证
4.1 准备和创建用户凭证 (SCRAM机制的核心优势)
SASL/SCRAM 的一个主要优势是可以动态管理用户。使用 Kafka 自带的 kafka-configs.sh 脚本进行创建。
- 如果kafka开启kerberos认证开启着,关闭启动原始kafka
停止命令:
./bin/kafka-server-stop.sh
启动原始kafka(因为上述kerberos单独建立了kafka-server-start-sasl.sh ,所以启动kafka-server-start.sh就是原始 ):
./bin/kafka-server-start.sh -daemon ./config/server.properties
- 创建管理员用户 (admin):用于后续的 Broker 间通信。
执行如下命令的前提是server.properties中配置了advertised.listeners,否则会报连不上node,我的配置如下

./bin/kafka-configs.sh --bootstrap-server 139.19.71.51:9092 --alter --add-config 'SCRAM-SHA-256=[password=Marine.123],SCRAM-SHA-512=[password=Marine.123]' --entity-type users --entity-name admin
注意:对于 KRaft 模式下的 Kafka 集群,需要使用 kafka-storage 命令的 --add-scram 选项
- 创建普通用户 (alice):用于客户端(生产者/消费者)的连接。
./bin/kafka-configs.sh --bootstrap-server 139.19.71.51:9092 --alter --add-config 'SCRAM-SHA-256=[password=Marine.123],SCRAM-SHA-512=[password=Marine.123]' --entity-type users --entity-name alice
4.2 修改 Kafka 服务端 (server.properties)
对配置文件进行以下增、删、改操作:
- 修改与启用 (listeners 保持 SASL_PLAINTEXT 或 SASL_SSL 不变):
我这里同样复制一份server.properties,仅用于SCRAM认证
sudo cp config/server-sasl.properties config/server-scram.properties
修改server-scram.properties为如下内容:
sasl.enabled.mechanisms=SCRAM-SHA-256,SCRAM-SHA-512
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-256
- 删除:移除任何与 Kerberos 相关的配置行,例如 sasl.kerberos.service.name。
4.3 配置 Broker 的 JAAS (kafka-server-jaas.conf和kafka-client-jaas.conf)
创建或编辑 JAAS 配置文件(通常在 config/ 目录下),用于 Broker 自身的登录认证
同样的,复制一份kafka-server-jaas.conf,仅用于SCRAM认证:
我这里提前创建了个和kerberos同级的scram文件夹,用于scram认证
sudo cp config/kerberos/kafka-server-jaas.conf config/scram/kafka-server-jaas.conf
sudo cp config/kerberos/kafka-client-jaas.conf config/scram/kafka-client-jaas.conf
编辑scram/kafka-server-jaas.conf,为如下内容:
sudo vim config/scram/kafka-server-jaas.conf
KafkaServer {
org.apache.kafka.common.security.scram.ScramLoginModule required
username="admin"
password="Marine.123";
};
编辑scram/kafka-client-jaas.conf,为如下内容:
sudo vim config/scram/kafka-client-jaas.conf
KafkaClient {
org.apache.kafka.common.security.scram.ScramLoginModule required
username="alice"
password="Marine.123";
};
小提示:KafkaServer 是固定的 section 名称,Kafka 进程会去寻找它。JAAS 配置也可以通过 listener.name.{listenerName}.scram-sha-256.sasl.jaas.config 这样的格式直接在 server.properties 文件中定义,但使用独立的 JAAS 文件管理起来更清晰。
4.4 配置客户端 (client.properties)
sudo cp config/kerberos/client.properties config/scram/client.properties
sudo vim config/scram/client.properties
修改scram/client.properties为如下内容:
security.protocol=SASL_PLAINTEXT
sasl.mechanism=SCRAM-SHA-256
sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \
username="alice" \
password="Marine.123";
bootstrap.servers=139.19.71.51:9092
4.5 修改kafka脚本(kafka-server-start-sasl.sh、kafka-topics.sh、kafka-console-producer.sh和kafka-console-consumer.sh)
sudo cp bin/kafka-server-start-sasl.sh bin/kafka-server-start-scram.sh
sudo cp bin/kafka-topics-sasl.sh bin/kafka-topics-scram.sh
sudo cp bin/kafka-console-producer-sasl.sh bin/kafka-console-producer-scram.sh
sudo cp bin/kafka-console-consumer-sasl.sh bin/kafka-console-consumer-scram.sh
kafka-server-start-scram.sh:注掉kerberos配置,更改JAAS路径,如下:

kafka-topics-scram.sh:更改JAAS路径,如下:

kafka-console-producer-scram.sh:更改JAAS路径,如下:

kafka-console-consumer-scram.sh:更改JAAS路径,如下:

至此,所有配置更改完成
4.6 启动验证
启动:
./bin/kafka-server-start-scram.sh -daemon config/server-scram.properties
查询topic:
./bin/kafka-topics-scram.sh --list --bootstrap-server 139.19.71.51:9092 --command-config config/scram/client.properties
生产者:
bin/kafka-console-producer-scram.sh --bootstrap-server 139.19.71.51:9092 --topic test --producer.config config/scram/client.properties
消费者:
bin/kafka-console-consumer-scram.sh --bootstrap-server 139.19.71.51:9092 --topic test --from-beginning --consumer.config config/scram/client.properties
--from-beginning为查看所有,不需要可以不添加
5. 遇到的报错问题
- keytab文件有误,或者无法获取
Exception in thread "main" org.apache.kafka.common.KafkaException: Failed to create new KafkaAdminClient
at org.apache.kafka.clients.admin.KafkaAdminClient.createInternal(KafkaAdminClient.java:551)
at org.apache.kafka.clients.admin.KafkaAdminClient.createInternal(KafkaAdminClient.java:488)
at org.apache.kafka.clients.admin.Admin.create(Admin.java:134)
at kafka.admin.TopicCommand$TopicService$.createAdminClient(TopicCommand.scala:203)
at kafka.admin.TopicCommand$TopicService$.apply(TopicCommand.scala:207)
at kafka.admin.TopicCommand$.main(TopicCommand.scala:51)
at kafka.admin.TopicCommand.main(TopicCommand.scala)
Caused by: java.lang.SecurityException: java.io.IOException: 配置错误:
原因:keytab文件有误,或者无法获取
kafka的server.log报错:
client is being asked for a password, but the Kafka client code does not currently support obtaining a password from the user. not available to garner authentication information from the us
解决办法:
- 验证keytab文件:
检查 broker 的 keytab 文件:
# 查看 keytab 内容
klist -kt /home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/kafka-server.keytab
- 确认输出的 principal 为 kafka-server/localhost@KAFKA.COM(与你 JAAS 中配置的一致)
- 如果 principal 不对,需要重新生成 keytab。
测试 keytab 有效性:
kinit -kt /home/cloud_nms/kafka/kafka_2.12-3.5.0/config/kerberos/kafka-server.keytab kafka-server/centos@KAFKA.COM
- 如果成功,klist 会显示票据;如果失败,会给出具体错误(如 kvno 不匹配),需要重新生成 keytab。
- 检查kafka-server-jaas.conf文件内容
- 检查防火墙状态和端口状态
- 检查keytab文件权限(直接改权限644就行了)
最有效的办法,查看kafka启动报错信息,我的位置在/home/cloud_nms/kafka/kafka_2.12-3.5.0/logs/server.log中,查看kerberos启动日志,在/var/log/krb5kdc.log和/var/log/kadmind.log,一般后者不报错,主要看server.log,然后解决办法就是网页查询加问AI
server.log报错:
2. Message stream modified
解决办法:删除客户端使用的配置文件中的krb5.conf中的renew_lifetime配置项,也可以注释
- [Kerberos]Message stream modified (41)错误
[2026-03-27 13:59:52,805] ERROR Exiting Kafka due to fatal exception during startup. (kafka.Kafka$)
org.apache.kafka.common.KafkaException: javax.security.auth.login.LoginException: Message stream modified (41)
at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:184)
at org.apache.kafka.common.network.ChannelBuilders.create(ChannelBuilders.java:192)
at org.apache.kafka.common.network.ChannelBuilders.clientChannelBuilder(ChannelBuilders.java:81)
at kafka.server.BrokerToControllerChannelManagerImpl.buildNetworkClient$1(BrokerToControllerChannelManager.scala:204)
at kafka.server.BrokerToControllerChannelManagerImpl.newRequestThread(BrokerToControllerChannelManager.scala:243)
at kafka.server.BrokerToControllerChannelManagerImpl.<init>(BrokerToControllerChannelManager.scala:183)
at kafka.server.BrokerToControllerChannelManager$.apply(BrokerToControllerChannelManager.scala:149)
at kafka.server.KafkaServer.startup(KafkaServer.scala:316)
at kafka.Kafka$.main(Kafka.scala:113)
at kafka.Kafka.main(Kafka.scala)
Caused by: javax.security.auth.login.LoginException: Message stream modified (41)
at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:785)
at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:597)
at java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:679)
at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:677)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:677)
at java.base/javax.security.auth.login.LoginContext.login(LoginContext.java:587)
at org.apache.kafka.common.security.authenticator.AbstractLogin.login(AbstractLogin.java:60)
at org.apache.kafka.common.security.kerberos.KerberosLogin.login(KerberosLogin.java:103)
at org.apache.kafka.common.security.authenticator.LoginManager.<init>(LoginManager.java:62)
at org.apache.kafka.common.security.authenticator.LoginManager.acquireLoginManager(LoginManager.java:112)
at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:170)
... 9 more
Caused by: KrbException: Message stream modified (41)
at java.security.jgss/sun.security.krb5.KrbKdcRep.check(KrbKdcRep.java:103)
at java.security.jgss/sun.security.krb5.KrbAsRep.decrypt(KrbAsRep.java:159)
at java.security.jgss/sun.security.krb5.KrbAsRep.decryptUsingKeyTab(KrbAsRep.java:121)
at java.security.jgss/sun.security.krb5.KrbAsReqBuilder.resolve(KrbAsReqBuilder.java:310)
at java.security.jgss/sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:498)
at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:761)
... 21 more
[2026-03-27 13:59:52,806] INFO [KafkaServer id=0] shutting down (kafka.server.KafkaServer)
解决:
删除 krb5.conf 配置文件里的 renew_lifetime = xxx 这行配置即可
- 服务名不匹配
[2026-03-27 15:43:17,490] WARN [Controller id=0, targetBrokerId=0] Connection to node 0 (139.19.71.51/139.19.71.51:9092) could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient)
[2026-03-27 15:43:17,495] INFO [Controller id=0, targetBrokerId=0] Client requested connection close from node 0 (org.apache.kafka.clients.NetworkClient)
[2026-03-27 15:43:17,718] INFO [Controller id=0, targetBrokerId=0] Node 0 disconnected. (org.apache.kafka.clients.NetworkClient)
[2026-03-27 15:43:17,718] WARN [Controller id=0, targetBrokerId=0] Connection to node 0 (139.19.71.51/139.19.71.51:9092) terminated during authentication. This may happen due to any of the following reasons: (1) Authentication failed due to invalid credentials with brokers older than 1.0.0, (2) Firewall blocking Kafka TLS traffic (eg it may only allow HTTPS traffic), (3) Transient network issue. (org.apache.kafka.clients.NetworkClient)
[2026-03-27 15:43:17,718] INFO [Controller id=0, targetBrokerId=0] Client requested connection close from node 0 (org.apache.kafka.clients.NetworkClient)
[2026-03-27 15:43:17,887] INFO [Controller id=0, targetBrokerId=0] Node 0 disconnected. (org.apache.kafka.clients.NetworkClient)
[2026-03-27 15:43:17,887] WARN [Controller id=0, targetBrokerId=0] Connection to node 0 (139.19.71.51/139.19.71.51:9092) terminated during authentication. This may happen due to any of the following reasons: (1) Authentication failed due to invalid credentials with brokers older than 1.0.0, (2) Firewall blocking Kafka TLS traffic (eg it may only allow HTTPS traffic), (3) Transient network issue. (org.apache.kafka.clients.NetworkClient)
[2026-03-27 15:43:17,887] INFO [Controlle
解决:
-
如果 Broker principal 是 kafka/host@REALM,则 sasl.kerberos.service.name 应为 kafka(这是默认值,若未配置则使用此默认)。
-
所有 Broker 的 security.inter.broker.protocol 必须相同。
-
kerberos的缓存机制
-
操作系统级别:Kerberos 客户端库(如 MIT Kerberos、Heimdal)在首次调用时会读取 krb5.conf,并将其解析结果缓存在进程内存中。后续的认证请求直接使用内存中的配置,不会重新读取文件。
-
Java 环境:JRE 中的 sun.security.krb5.Config 类采用单例模式,第一次调用 Config.getInstance() 时加载并解析 krb5.conf,之后一直复用该实例,直至 JVM 退出。
这意味着,如果你直接修改了 krb5.conf 文件,正在运行的 Java 应用不会自动感知变化。
在设置 krb5 配置文件中添加清除缓存的代码:
jdk8:
try {
LOG.info("KAFKA -> setKrb5Config -> refresh");
Field configField = Config.class.getDeclaredField("singleton");
configField.setAccessible(true);
configField.set(null, null); // 强制置空
// 重新获取实例以触发重新加载
Config.refresh();
return Config.getInstance().getDefaultRealm();
} catch (Exception e) {
LOG.error("KAFKA -> setKrb5Config -> ERROR", e);
}
jdk17:因为17的封装不能使用jdk8的方式
private static void refreshJaasConfiguration() {
try {
System.clearProperty("java.security.krb5.realm");
System.clearProperty("java.security.krb5.kdc");
// 使用标准的 Configuration 类刷新
// Configuration.setConfiguration(null);
Class<?> configClass = Class.forName("sun.security.krb5.Config");
Method getInstance = configClass.getMethod("getInstance");
Object krb5Config = getInstance.invoke(null);
Method refresh = configClass.getMethod("refresh");
refresh.invoke(krb5Config);
LOG.info("成功刷新 JAAS 配置");
} catch (Exception e) {
LOG.warn("刷新 JAAS 配置失败:{}", e.getMessage());
}
}
参考文献:kafka安装参考:https://blog.csdn.net/u013416034/article/details/123875299
kerberos安装参考:https://www.cnblogs.com/wuyongyin/p/15634397.html
kafka开启kerberos参考:https://www.cnblogs.com/myownswordsman/p/kafka-security-kerberos.html
https://blog.csdn.net/mandiandengwo/article/details/144831039
https://www.cnblogs.com/lizhaoxian/p/16454980.html
错误报错参考:https://developer.aliyun.com/article/1604481

浙公网安备 33010602011771号