kafka在私有云DNAT环境中集群的典型应用
今天配置的是一个2.5.0的一个kafka集群,新的版本将废弃zookeeper,今天不讨论新版本有一个私有的云环境,业务需求希望通过公网向kafka发送数据,使用SCRAM-SHA-256加密,内网仍然需要能够正常访问, 而其中,需要通过DNAT的方式来映射内网端口暴漏给互联网。而在做映射的时候,必然是一个端口对一个端口的,于是,大致的示意拓扑如下
如果你不是这种方式,可以尝试Kafka 实现内外网访问流量分离来解决问题
而在实际的生产中,你会发现,内网采用内网IP进行访问的时候,kafka是可以正常协商进行处理请求
而在公网通过6.78.5.32的9092,9093,9094
端口访问的时候会出现出现一个问题,客户端当请求A通过6.78.5.32:9092
发送,经过防火墙DNAT层后,发给后端kafka,而此时kafka收到消息后回复给发送者,而回复的时候是使用的172.16.100.7:9092
端口,你的客户端根本就不认识172.16.100.7
,因此发送失败
而这个现象在你只是向kafka发送消息,而不在乎他是否返回的时候,代码层面显示是成功的,但是数据并未成功插入。于是,就有了另外一种方式
消息发送后需要返回,服务端和客户端都分别写ip和hostname,通过域名和本地hosts的方式解析出ip,分别发送到代理服务器和客户端,而不是某一个固定的ip。无论来自公网的访问还是内网的访问,最终在本地的hosts各自指向一个可以被访问到的一个ip,从而完成响应。
这种形式在官网的某些字段中被解读为“防止中间人攻击”
如下
- version: kafka_2.12-2.5.0
- jdk: 1.8.0_211
先决条件:
- 同步时间
10 * * * * ntpdate ntp.aliyun.com
- 修改hosts并本地hosts
#172.16.100.7
hostnamectl set-hostname kafka1
#172.16.100.8
hostnamectl set-hostname kafka2
#172.16.100.9
hostnamectl set-hostname kafka3
172.16.100.7 kafka1
172.16.100.8 kafka2
172.16.100.9 kafka3
准备工作
二进制安装java,或者rpm安装即可
tar xf jdk-8u211-linux-x64.tar.gz -C /usr/local/ cd /usr/local && ln -s jdk1.8.0_211 java cat > /etc/profile.d/java.sh /etc/systemd/system/zookeeper.service /usr/local/kafka/config/server-scram.properties /usr/local/kafka/config/server-scram.properties /etc/systemd/system/kafka.service /u01/data/zookeeper/myid
172.16.100.9
echo "2" > /u01/data/zookeeper/myid