内网有个ambari-hdp3.1的kafka环境 2节点 kafka版本2.0
目前已经映射出去6667 6668 kerberoos通信端口 2181端口
公网ip只有一个ip 58.240.xxx.xxx
节57的6667 6668 映射成外网ip的6667 6668。
内网kafka1配置:
advertised.listeners=SASL_PLAINTEXT://dn9057:6667,EXTERNAL://58.240.xxx.xxx:6668
listeners=SASL_PLAINTEXT://:6667,EXTERNAL://:6668
security.inter.broker.protocol SASL_PLAINTEXT
sasl.mechanism.inter.broker.protocol GSSAPI
listener.security.protocol.map=SASL_PLAINTEXT:SASL_PLAINTEXT,EXTERNAL:SASL_PLAINTEXT
kafka2配置:
advertised.listeners=SASL_PLAINTEXT://dn9057:6667,EXTERNAL://dn_kafka:6668
listeners=SASL_PLAINTEXT://:6667,EXTERNAL://:6668
security.inter.broker.protocol SASL_PLAINTEXT
sasl.mechanism.inter.broker.protocol GSSAPI
listener.security.protocol.map=SASL_PLAINTEXT:SASL_PLAINTEXT,EXTERNAL:SASL_PLAINTEXT
内网58节点 域名映射
58.240.xxx.xxx dn_kafka
公网1节点 的/etc/hosts
都加了域名映射
58.240.xxx.xxx dn9057
58.240.xxx.xxx dn9058
58.240.xxx.xxx dn_kafka
(两个节点外部连接一直会报错,所以节点2绕了一下)
然后再kerberos数据库里添加dn_kafka票据
另外krb5文件也优化了 加了配置改成tcp通信
公网节点:
上传了krb5conf
添加环境变量
export KAFKA_OPTS="-Djava.security.auth.login.config=/usr/hdp/current/kafka-broker/conf/kafka_jaas.conf -Djava.security.krb5.conf=/etc/krb5.conf"
KafkaClient {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab = true
useTicketCache=false
storeKey = true
keyTab="/home/kafka.user.keytab"
principal="kafka@DDP.COM"
serviceName="kafka";
};
[libdefaults]
renew_lifetime = 7d
forwardable = true
default_realm = DDP.COM
udp_preference_limit = 1
ticket_lifetime = 24h
dns_lookup_realm = false
dns_lookup_kdc = false
default_ccache_name = /tmp/krb5cc_%{uid}
default_tgs_enctypes = aes128-cts
default_tkt_enctypes = aes128-cts
[logging]
default = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
kdc = FILE:/var/log/krb5kdc.log
[realms]
DDP.COM = {
admin_server = dn9057
kdc = dn9057
}
节点上kinit也能通过 klist也能正常显示
然后启动producer连接内网kafka
cd /usr/hdp/3.1.0.0-78/kafka/bin/ && ./kafka-console-producer.sh --broker-list dn9057:6668 --topic hk --producer.config /home/producer.properies
发10条消息能消费5条,其中发到节点57的5条能正常消费,但是其他5条消息:
Connection to node 1002 failed authentication due to: Authentication failed due to invalid credentials with SASL mechanism GSSAPI (org.apache.kafka.clients.NetworkClient)
/home/producer.properies
bootstrap.servers=dn9057:6668
compression.type=none
security.protocol=SASL_PLAINTEXT
sasl.mechanism=GSSAPI
sasl.kerberos.service.name=kafka
我尝试bootstrap.server写多个也没效果。
排查过程:
58开出去一个6669端口 然后58监听端口改用6669 还是一样的错误。
有大佬可以替我解答一下吗。
公网ip只有一个,是不行的。因为kafka客户端要与每个node建立长连接,进行数据交换的。
你可以参考:kafka外网访问 ,里面有外网转发的原因。
另外注意,端口不能变,要映射一模一样的。
最后,你做测试的时候,可以先不用kerberos,一步一步来,如果内网、外网消费和生产都可以了,在加上认证。
感谢大佬回复解答。之前确实一直怀疑过公网ip只有一个的环境问题,但不是很有把握。
后续打算采纳先关闭kerberos的建议,也许关了之后发现就是连接不上,目前报的验证失败其实可能就是连接失败的异常抛出。
看了上述提到的文章 认真看了一遍 有解释单个公网ip不可以 也有称解决了的
重新提问一个问题和我的验证思路
我新找了个无kerberos的kafka环境
90.86
port=26667 advertised.listeners=PLAINTEXT://dn86:26667 listeners=PLAINTEXT://dn86:26667
90.87
port=26668 advertised.listeners=PLAINTEXT://dn86:26668 listeners=PLAINTEXT://dn86:26668
将dn86的26667映射到外网的26667
将dn87的26668映射成外网的26668
在客户端90.86的
/etc/hosts
中配置启动
cd /usr/hdp/3.1.0.0-78/kafka/bin/ && ./kafka-console-producer.sh --broker-list dn86:26667 --topic test_kk
这样的话 不管从zk中返回的是dn86:26667 还是dn87:26668 那么访问的都是dn86 dn87两个节点 两个端口。
想问一下 这种方案 理论上是否可行
补充:因为90.86-87节点和测试的客户端节点70.110本身是能访问的,所以为了排除风险。
在86 87上开了防火墙 86 87互为白名单,开放26667 26668 2181 端口,最后把70.110拉入黑名单,70.110直接访问86 87是不通的。
截至目前是可以消费了(无kerberos)但是之前报错太多了 不是很确定,所以请大佬帮忙再看一下目前的方案理论上是否ok。
有点乱,你提供的配置。
90.86
listeners=PLAINTEXT://dn86:26667
90.87
listeners=PLAINTEXT://dn86:26668
这个
dn86
是一样的?另外,你应该一个kafka集群走内网,客户端走外网,否则全走外网,kafka集群性能很差的。
例如:
port=26667 advertised.listeners=PLAINTEXT://外网ip:26667 listeners=PLAINTEXT://内网ip:26667
不好意思 环境配置 提供的有点问题
实际是这样的
dn86:
port=26667 advertised.listeners=PLAINTEXT://dn86:26667 listeners=PLAINTEXT://内网ip:26667
dn87:
port=26668 advertised.listeners=PLAINTEXT://dn87:26668 listeners=PLAINTEXT://内网ip:26668
然后在客户端添加dn86 dn87的域名映射
我自己测试的结果写
是不是这样就可以实现一个公网ip下的 “外网访问内网集群”
配置没问题,可以的。
感谢大佬的指点,目前已经全部调通,包括kerberos环境!
非kerberos环境最后配置的格式就是上面贴的。
kerberos环境 大致还需要以下几点。
1、kafka-server端加了环境变量
export KAFKA_OPTS="-Djava.security.auth.login.config=/usr/hdp/current/kafka-broker/conf/kafka_jaas.conf"
2、/etc/krb5.conf文件可能需要加一行udp_preference_limit = 1 将udp改成tcp防止丢包(这个不一定需要)
3、客户端需要一个kafka_client_jaas.conf
KafkaClient { com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true renewTicket=true serviceName="kafka"; }; Client { com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true renewTicket=true serviceName="zookeeper"; };
4、然后一些sasl的配置,监听器的配置就不赘述了
总结:之前对“主动发现集群机制”了解不够,也不知道消费时要对每一个broker都开一个长连接* 加上报错一直都是权限验证失败让人感觉是kerberos的问题,绕了很久。后面排除无关的因素,就很明显了。另外提醒ambari安装的kafka不管界面上配置的advertised.listeners是多少,内部代码还是会强行将listeners的值赋给advertised.listeners。
还是很感谢大佬的及时回复 耐心指导。期待以后更多的交流
你的答案