將kafka集群端口映射到公網訪問

場景假設
比如你有一個kafka集群,在同一個vpc(私有網絡)里面也即是在一個內網環境里,該kafka集群有3個broker,broker1、broker2和broker3。
kafka集群信息如下:
broker1 IP: 192.168.xxx.1
broker2 IP: 192.168.xxx.2
broker3 IP: 192.168.xxx.3
kafka集群各個節點 server.properties配置
config/server-1.properties:
broker.id=1
listeners=PLAINTEXT://192.168.xxx.1:19092
config/server-2.properties:
broker.id=2
listeners=PLAINTEXT://192.168.xxx.2:19092
config/server-3.properties:
broker.id=3
listeners=PLAINTEXT://192.168.xxx.3:19092
現在希望通過配置vpc公網ip做端口轉發(也可以通過nginx做端口轉發),就可以通過外網訪問了(但是實際用kafka客戶端連接會報超時)
想通過vpc外的機器來訪問kafka集群,也就想訪問192.168.xxx.1:19092,192.168.xxx.2:19092,192.168.xxx.3:19092
在vpc上做端口轉發,vpc公網ip為192.168.xxx.xx,并在相應防火墻打開對應端口(19092、19093、19093),比如:
192.168.xxx.xx:19092 -> 192.168.xxx.1:19092
192.168.xxx.xx:19093 -> 192.168.xxx.2:19092
192.168.xxx.xx:19094 -> 192.168.xxx.2:19092
測試
這時,如果你通過vpc的公網ip和對應端口連接私有網絡(內網)內的kafka集群,192.168.xxx.xx:19092、192.168.xxx.xx:19093、192.168.xxx.xx:19094端口都是通的,但是訪問kafka發送或消費消息時,會報網絡超時,這是為什么呢?
kafka producer端(客戶端)和server之間有個類似協商的階段, server會把lkafka配置文件里listeners這里的地址直接返給producer,producer再發數據給這個listeners地址。
因為kafka客戶端是主動發現集群地址的,當你通過192.168.xxx.xx:19092、192.168.xxx.xx:19093、192.168.xxx.xx:19094確實是連接到kafka集群了,kafka集群返回給你的ip列表是你listeners配置的,也就是
192.168.xxx.1:19092
192.168.xxx.2:19092
192.168.xxx.3:19092
客戶端producer 在vpc這個私有網絡以外,producer 端通過ip轉發和端口都沒有用,producer 和vpc對應的公網ip是通的,但是與vpc內私有網絡不通,這就是訪問kafka發送或消費消息時會報網絡超時等等的本質原因。
解決
一種解決方式是客戶端通過域名映射的方式。
1.kafka配置:
修改kafka集群服務端各個節點的server.properties配置,注意listeners之后的ip和端口配置
config/server-1.properties:
broker.id=1
listeners=PLAINTEXT://kafka-1:19092
config/server-2.properties:
broker.id=2
listeners=PLAINTEXT://kafka-2:19093
config/server-3.properties:
broker.id=3
listeners=PLAINTEXT://kafka-3:19094
kafka集群的各個節點在服務端配置hosts
cat /etc/hosts
192.168.xxx.1 kafka-1
192.168.xxx.2 kafka-2
192.168.xxx.3 kafka-3
2.vpc做端口映射
kafka-1 映射至 192.168.xxx.1:19092
kafka-2 映射至 192.168.xxx.2:19093
kafka-3 映射至 192.168.xxx.3:19094
3.客戶端配置:
客戶端在host文件中把kafka01、kafka02、kafka03都映射到公網地址。這個很關鍵,上面提到過客戶端會獲取到kafka配置的元數據 ,客戶端會獲取到 kafka-1、kafka-2、kafka-3 這3個hostname,之后生產或消費數據會直接通過這個地址訪問。如果不把這三個hostname重新映射到公網IP,就不能成功生產或者消費數據。
#/etc/hosts
192.168.xxx.xx kafka01 kafka02 kafka03
客戶端訪問kafka集群時,獲取的是kafka-1:19092,kafka-2:19093,kafka-3:19094,通過客戶端配置的hosts映射,都轉成了對應的外網的ip,因此就可以訪問了。
注意:端口要一致,hosts映射只轉ip。