目录
- 背景
- 第一部分 Kafka几个配置参数介绍
- 第二部分 外网环境访问内网(NAT)Kafka集群配置
- 第三部分 总结
- 参考文献及资料
背景
其实这是一个踩坑笔记。首先介绍踩坑背景。生产环境我们有两个网络区域,记为网络区域A(内网)、网络区域B(外网),其中为了外网环境能访问内网环境,内网对内部IP实施了IP映射(NAT),将内网IP映射为外部IP。Kafka版本为:kafka_2.11-0.10.2.0。IP清单及网络数据流图如下:
hostname | 内网ip | 外网Ip |
---|---|---|
kafka.node1 | 192.168.1.1 | 10.0.0.1 |
kafka.node2 | 192.168.1.2 | 10.0.0.2 |
kafka.node3 | 192.168.1.3 | 10.0.0.3 |
整个架构图为:
外网网络区域的客户端开始使用NAT地址(10.0.0.1-3)地址访问内部kafka,发现无法生产和消费kafka数据(telnet netip 9092是通的),会报解析服务器hostname失败的错误。而内部网络的客户端使用内网地址(192.168.1.1-3)是可以正常生产和消费kafka数据。
原因:advertised.listeners配置的是内网实地址,这个地址注册到Zookeeper中,当消费者和生产者访问时,Zookeeper将该地址提供给消费者和生产者。由于是内网地址,外网根本看不到这个地址(路由寻址)。所以无法获取元数据信息,通信异常。
第一部分 Kafka几个配置参数介绍
首先要了解一下几个配置:
host.name
已弃用。 仅当listeners属性未配置时被使用,已用listeners属性代替。表示broker的hostname。advertised.host.name
已弃用。仅当advertised.listeners或者listeners属性未配置时被使用。官网建议使用advertised.listeners。该配置的意思是注册到zookeeper上的broker的hostname或ip。是提供给客户端与kafka通信使用的。如果没有设置则使用host.name。listeners
监听列表,broker对外提供服务时绑定的IP和端口。多个以逗号隔开,如果监听器名称是一个安全的协议, listener.security.protocol.map也必须设置。主机名称设置0.0.0.0绑定所有的接口,主机名称为空则绑定默认的接口。如:1
listeners = PLAINTEXT://myhost:9092,SSL://:9091 CLIENT://0.0.0.0:9092,REPLICATION://localhost:9093
如果未指定该配置,则使用java.net.InetAddress.getCanonicalHostName()函数的的返回值。
advertised.listeners
客户端使用。发布至zookeeper的监听,broker会上送此地址到zookeeper,zookeeper会将此地址提供给消费者和生产者,消费者和生产者根据此地址获取消息。如果和上面的listeners不同则以此为准,在IaaS环境,此配置项可能和 broker绑定的接口主机名称不同,如果此配置项没有配置则以上面的listeners为准。
第二部分 外网环境访问内网(NAT)Kafka集群配置
2.1 配置hosts方式
Kafka集群节点配置
每一台Kafka节点的hosts节点配置内部地址映射:
192.168.1.1 kafka.node1
192.168.1.2 kafka.node2
192.168.1.3 kafka.node3Kafka中的配置文件(config/server.properties配置文件)
advertised.listeners=PLAINTEXT://kafka.node1:9092
advertised.listeners=PLAINTEXT://kafka.node2:9092
advertised.listeners=PLAINTEXT://kafka.node3:9092
客户端节点配置
客户端的hosts文件也需要配置外部地址映射:
10.0.0.1 kafka.node1
10.0.0.2 kafka.node2
10.0.0.3 kafka.node3应用程序使用
bootstrap.servers: [‘kafka.node1:9092’,’kafka.node2:9092’,’kafka.node3:9092’]
配置完成后,重启Kafka集群,重新使用客户端链接,测试客户端可以正常向Topic生产和消费数据。
2.2 内外部流量分离
通常对于外部网络访问内网安全区域,架构使用安全套接字层 (SSL) 来保护外部客户端与 Kafka 之间的流量。而使用明文进行内部网络的broker间的通信。当 Kafka 侦听器绑定到用于内部和外部通信的网络接口时,配置侦听器就非常简单了。但在许多情况下,例如在云原生环境上部署时,集群中 Kafka broker 的外部通告地址将与 Kafka 使用的内部网络接口不同。在此情况下,可以 server.properties
中的参数 advertised.listeners
进行如下配置:
1 | Configure protocol map |
内部使用9092端口,而外部网络使用9093端口。
第三部分 总结
Kafka集群在内外网网络环境下,需要关注地址映射。使用hosts 本地DNS进行主机名和内外地址的映射。至此爬出该坑。
参考文献及资料
1、kafka - advertised.listeners和listeners,链接:https://www.cnblogs.com/fxjwind/p/6225909.html
2、Kafka从上手到实践-Kafka集群:Kafka Listeners,链接:http://www.devtalking.com/articles/kafka-practice-16/
3、使用 Cloud Dataflow 处理来自 Kafka 的外部托管消息 链接:https://cloud.google.com/solutions/processing-messages-from-kafka-hosted-outside-gcp?hl=zh-cn
4、Kafka Listeners - Explained 链接:https://rmoff.net/2018/08/02/kafka-listeners-explained/