背景
目前网上搜索到的大部数Kafka资源和文档都是以Unix命令行为主。虽说大部分功能在Windows系统下的设置大同小异,但我在工作中解决各种Kafka问题时总是会遇到或大或小的困难。因此,我想把一些项目中解决的问题汇总成一些笔记。
这次我要完成的任务,是把Kubernetes QA集群里的Kafka的消息重新消费(re-consume),而要重新消费的topic有ACL+SASL认证。因为目前QA的代码并不处理重新消费功能,而且在下次小版本升级前要代码冻结,不能加入重新消费功能的新代码,所以可供替代的办法就是用Kafka自身的命令行的重置offset功能。重置offset需要关停consumer,而QA处于UAT阶段不能关停任何Kubernetes pod,所以我把这个任务放在本地的Windows机器上试验。
在这个过程中,我借助Google处理了大量报错,参照了很多博客文章和stackoverflow.com上的解答。在文章最后,我把这些资源也汇总分享。
版本
- Windows 10 Pro
- Apache Kafka 2.12-2.1.0 (C:\盘目录下)
- Zookeeper 3.4.13 (C:\盘目录下)
操作
配置文件准备
Zookeeper配置文件
在<kafka_dir>\config\
下,我拷贝一份zookeeper.properties
文件并将其命名为zookeeper-acl.properties
。用编辑器打开zookeeper-acl.properties
,在文档内容最后加入以下几行:
# SASL settings
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
requireClientAuthScheme=sasl
jaasLoginRenew=3600000
Clients配置文件
因为我主要用到的Kafka client是consumer,以kafka-console-consumer和kafka-consumer-groups命令为主,所以在此我只介绍consumer的设置。如果用到其他client,这个方法可以借鉴。
同样在<kafka_dir>\config\
下,我拷贝一份consumer.properties
文件并将其命名为consumer-acl.properties
。在该文档内容最后加入以下几行:
# ACL settings
security.protocol=SASL_PLAINTEXT
sasl.mechanism=PLAIN
Kafka Server配置文件
之后我再在相同目录下拷贝一份server.properties
并命名为server-acl.properties
。在文档内容末尾加入:
# ---- ACL AND RELATED STUFF
sasl.enabled.mechanisms=SASL_PLAINTEXT
sasl.mechanism.inter.broker.protocol=PLAIN
sasl.enabled.mechanisms=PLAIN
# Substitute with appropriate IP addresses:
listeners=SASL_PLAINTEXT://localhost:9092
advertised.listeners=SASL_PLAINTEXT://localhost:9092
security.inter.broker.protocol=SASL_PLAINTEXT
authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer
super.users=User:admin
JAAS配置文件
之后,我在相同目录下,创建一个JAAS配置文件zk-kafka-jaas.conf
。与很多文章1的做法不同,我把Zookeeper、Kafka server和Kafka client的设置放在这同一个文件里,而不是分成三个不同的JAAS conf文件。我这样做的原因主要是,ACL+SASL必需用到的环境变量KAFKA_OPTS我只需设置一次,而不像其他文章在分别启动Zookeeper、Kafka server和Kafka client(像producer、consumer等),都要在各自终端各设置一次,即至少设置3次。把这个程序主路径happy path介绍完后,我会提一下KAFKA_OPTS在不同终端多次设置并且值都不一样时,我所碰到的问题。
# Kafka Server
KafkaServer {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="admin"
password="password"
user_admin="password"
user_yd="password";
};
Client {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="admin"
password="password";
};
# Kafka Client (Consumer, Producer, etc.)
KafkaClient {
org.apache.kafka.common.security.p