由于最开始使用ambari自带的kerberos和kafka集成的时候,总是消费不成功数据,感觉自己还是哪儿出了问题,所以我就先自己搭了一套开源的单机kafka,搭了一套单机kerberos环境,用来测试kerberos。
单机版的kafka和kerberos:
(kerberos服务和数据库的搭建可以看下面ambari部署kerberos那里,是一样的)
1.官网下载zookeeper,安装,修改基本配置
2.从官网下载kafka,安装,修改基本配置,配置zookeeper地址时一定把localhost:2181替换成主机名:2181
3.启动zookeeper,测试是否能正常使用
4.启动kafka,列一下topic,生产消费一下消息
至此没有kerberos认证的kafka和zookeeper就完成了
接下来先安装kerberos的客户端,具体可以参考搭建kerberos的文章
然后就是修改kafka的配置了
1.在kerberos里面创建kafka用户
[root@bigdata config]kadmin.local
addprinc -randkey kafka/orchome@EXAMPLE.COM //创建用户
ktadd -k /etc/security/keytabs/kafka_server.keytab kafka/orchome@EXAMPLE.COM //生成keytab文件,指定路径
在kafka的conf目录下创建kafka_server_jaas.conf:
这里需要说明一下,kafkaserver是kafka服务端,kafkaclient是kafka客户端,client是连接zookeeper获取consumer等需要用的,如果指定了keytab路径,那么就会自动读取这个文件认证,如果没指定,就需要自己手动kinit某个用户,然后才能使用,如果没有kinit,那就用不了。
KafkaServer {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="/opt/kafka_2.11-2.0.0/bin/kafka_server.keytab"
principal="kafka/bigdata@YISA.COM";
};
KafkaClient {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=false
useTicketCache=true
renewTicket=true;
};
Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=false
useTicketCache=true
renewTicket=true;
};
创建kafka_client_jaas.conf:
KafkaClient {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="/opt/kafka_2.11-2.0.0/bin/kafka_client.keytab"
principal="kafka_client/bigdata@YISA.COM";
};
这个principal的选择我来回搞了半天才弄明白,大部分问题是出在这儿。
然后就是JDK的问题,如果用的是openjdk的话可以不进行任何操作,如果使用的是oracle jdk的话需要替换JCE目录,网上很多实例
然后要替换kafka的配置文件:
[root@bigdata config]# vim server.properties
listeners=SASL_PLAINTEXT://:9092
security.inter.broker.protocol=SASL_PLAINTEXT
sasl.mechanism.inter.broker.protocol=GSSAPI
sasl.enabled.mechanisms=GSSAPI
sasl.kerberos.service.name=kafka
super.users=User:kafka
authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer
然后修改kafka bin目录下的文件:
[root@bigdata bin]# vim kafka-run-class.sh
# JVM performance options
if [ -z "$KAFKA_JVM_PERFORMANCE_OPTS" ]; then
KAFKA_JVM_PERFORMANCE_OPTS="-server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -Djava.awt.headless=true -Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/opt/kafka_2.11-2.0.0/config/kafka_server_jaas.conf -Dzookeeper.sasl.client.username=kafka"
fi
其中下面的是我加在这一行的JVM参数
-Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/opt/kafka_2.11-2.0.0/config/kafka_server_jaas.conf -Dzookeeper.sasl.client.username=kafka
然后在kafka的config目录下创建文件:(创建这个文件的目的是每次使用kafka的消费者或者生产者的时候用)
[root@bigdata config]# vim client.properties
security.protocol=SASL_PLAINTEXT
sasl.kerberos.service.name=kafka
sasl.mechanism=GSSAPI
本来以为这样就大工搞告成了,结果在启动kafka服务的时候报错了:
ERROR SASL authentication failed using login context 'Client' with exception: {} (org.apache.zookeeper.client.ZooKeeperSaslClient)
javax.security.sasl.SaslException: Error in authenticating with a Zookeeper Quorum member: the quorum member's saslToken is null.
org.apache.zookeeper.KeeperException$AuthFailedException: KeeperErrorCode = AuthFailed for /consumers
这个一看就是zookeeper没权限的错,查到了全网唯一一个解决方案
具体就是这样操作:
先创建zookeeper的jaas文件:
[root@bigdata bin]# cd /opt/zookeeper/conf/
[root@bigdata conf]# vim zookeeper_jaas.conf
Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="/opt/kafka_2.11-2.0.0/bin/kafka_server.keytab"
principal="kafka/bigdata@YISA.COM";
};
QuorumServer {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
useTicketCache=false
debug=false
keyTab="/opt/kafka_2.11-2.0.0/bin/kafka_server.keytab"
principal="kafka/bigdata@YISA.COM";
};
QuorumLearner {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
useTicketCache=false
debug=false
keyTab="/opt/kafka_2.11-2.0.0/bin/kafka_server.keytab"
principal="kafka/bigdata@YISA.COM";
};
Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="/opt/kafka_2.11-2.0.0/bin/kafka_server.keytab"
principal="kafka/bigdata@YISA.COM";
};
然后修改zoo.cfg,在后面追加下面内容,其中servicePrincipal和上方的keytab保持一致
[root@bigdata conf]# vim zoo.cfg
quorum.auth.enableSasl=true
quorum.auth.learnerRequireSasl=true
quorum.auth.serverRequireSasl=true
quorum.auth.learner.saslLoginContext=QuorumLearner
quorum.auth.server.saslLoginContext=QuorumServer
quorum.auth.kerberos.servicePrincipal=kafka/bigdata
quorum.cnxn.threads.size=20
修改zkEnv,也是在JVM参数那里加上jaas的路径
[root@bigdata bin]# vim zkEnv.sh
# default heap for zookeeper server
ZK_SERVER_HEAP="${ZK_SERVER_HEAP:-1000}"
export SERVER_JVMFLAGS="-Xmx${ZK_SERVER_HEAP}m $SERVER_JVMFLAGS -Djava.security.auth.login.config=/opt/zookeeper/conf/zookeeper_jaas.conf"
然后就可以启动zookeeper了,然后启动kafka,启动kafka的命令:
bin/kafka-server-start.sh ../config/server.properties
然后可以在kinit认证的情况下和没有kinit认证的情况下分别测试下面命令:
#查看topic
./kafka-topics.sh --zookeeper bigdata:2181 --list
#生产
./kafka-console-producer.sh --broker-list bigdata:9092 --topic test --producer.config /opt/kafka_2.11-2.0.0/config/client.properties
#消费
./kafka-console-consumer.sh --topic topic-test --from-beginning --bootstrap-server bigdata:9092 --consumer.config /opt/kafka_2.11-2.0.0/config/client.properties
我在使用kafka的时候发现只有使用jaas文件里的那个kerberos用户认证,才能使用kafka生产消息和消费消息,在网上查找文档以后,找到了解决方案,
vim server.properties
其中我添加了一行 authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer
把这个注释掉就可以了
如果要使用权限控制的话,就需要加这一行配置,并且用kafka的acl脚本
ambari不支持删除配置项,可以把这一项的值写成空,等价于注释了这个配置
ambari下操作kafka以及安装部署
#1.安装包
yum install krb5-server krb5-libs krb5-workstation
#2.修改配置文件
vi /etc/krb5.conf
删除这一行renew_lifetime = xxx
vi /var/kerberos/krb5kdc/kdc.conf
vi /var/kerberos/krb5kdc/kadm5.acl
#创建应用
/usr/sbin/kdb5_util create -s -r HQGF.COM
#启动
service krb5kdc start
service kadmin start
#设置开机启动
chkconfig krb5kdc on
chkconfig kadmin on
#添加principal
[root@ws1es ~]# kadmin.local
Authenticating as principal root/admin@HQGF.COM with password.
kadmin.local: addprinc admin/admin@HQGF.COM
WARNING: no policy specified for admin/admin@HQGF.COM; defaulting to no policy
Enter password for principal "admin/admin@HQGF.COM":
Re-enter password for principal "admin/admin@HQGF.COM":
Principal "admin/admin@HQGF.COM" created.
kadmin.local: listprincs
K/M@HQGF.COM
admin/admin@HQGF.COM
kadmin/admin@HQGF.COM
kadmin/changepw@HQGF.COM
kadmin/ws1es.wondersoft.cn@HQGF.COM
krbtgt/HQGF.COM@HQGF.COM
#重启服务
service kadmin restart
接下来是web部署了(要确保目前部署的组件都是正常的)
然后一直默认的下一步就可以
中途遇到的错误:
1.安装完kerberos以后,所有组件都会重启,我在重启时发现其中的一台zookeeper起不来,其他两台正常,起不来的那一台页面报错无法连接到这台机器的2181端口,查看zookeeper日志,发现报错
java.io.IOException: Could not configure server because SASL configuration did not allow the ZooKeeper server to authenticate itself properly: javax.security.auth.login.LoginException: Message stream modified (41)
解决办法:
vim /etc/krb5.conf
删除这一行renew_lifetime = xxx
service kadmin restart
安装后各组件的kerberos文件都存放在/etc/security/keytabs目录下
ambari下kafka的使用
根据上文搭好kerberos以后
在kafka的config目录下创建文件:(创建这个文件的目的是每次使用kafka的消费者或者生产者的时候用)
[root@bigdata config]# vim client.properties
security.protocol=SASL_PLAINTEXT
sasl.kerberos.service.name=kafka
sasl.mechanism=GSSAPI
在kinit认证的情况下和没有kinit认证的情况下分别测试下面命令:
#查看topic
./kafka-topics.sh --zookeeper bigdata:2181 --list
#生产
./kafka-console-producer.sh --broker-list bigdata:9092 --topic test --producer.config /opt/kafka_2.11-2.0.0/config/client.properties
#消费
./kafka-console-consumer.sh --topic topic-test --from-beginning --bootstrap-server bigdata:9092 --consumer.config /opt/kafka_2.11-2.0.0/config/client.properties