通过 SSH 隧道从 Kafka 集群消费



我们尝试使用 Java 客户端从 Kafka 集群消费。集群位于跳转主机后面,因此访问的唯一方法是通过 SSH 隧道。但是我们无法读取,因为一旦消费者获取元数据,它就会使用原始主机连接到代理。这种行为可以被覆盖吗?我们可以要求 Kafka 客户端不使用元数据吗?

据我所知。

当我需要做类似的事情时,我使用的技巧是:

  1. 为每个 Kafka 代理设置虚拟接口
  2. 打开到每个代理的隧道,以便将代理 N 绑定到虚拟接口 N
  3. 配置/etc/hosts文件,以便将代理 N 的通告主机名解析为虚拟接口 N 的 IP。

是的。

夫卡经纪人

  • broker1(宣传为broker1.mykafkacluster(
  • broker2(
  • 宣传为broker2.mykafkacluster(

虚拟接口

  • VETH1 (192.168.1.1(
  • VETH2 (192.168.1.2(

隧道

  • 经纪人1:ssh -L 192.168.1.1:9092:broker1.mykafkacluster:9092 jumphost
  • 经纪人2:ssh -L 192.168.1.2:9092:broker1.mykafkacluster:9092 jumphost

/etc/hosts

  • 192.168.1.1 代理1.mykafkacluster
  • 192.168.1.2 代理2.mykafka集群

如果像这样配置系统,您应该能够访问 Kafka 集群中的所有代理。

注:如果将 Kafka 代理配置为通告 IP 地址而不是主机名,则该过程仍然可以工作,但您需要使用与代理通告的相同 IP 地址配置虚拟接口。

如果代理通告主机名,您实际上不必添加虚拟接口来通过 SSH 隧道访问代理。只需在客户端/etc/hosts中添加主机条目并将隧道绑定到添加的名称就足够了。

假设broker.kafkacluster是您的经纪人的 advertised.hostname:

/etc/hosts
127.0.2.1 经纪人.kafkacluster

隧道:
ssh -L broker.kafkacluster:9092:broker.kafkacluster:9092 <brokerhostip/name>

像这样尝试sshuttle :

sshuttle -r user@host broker-1-ip:port broker-2-ip:port broker-3-ip:port

当然,代理列表取决于播发的侦听器代理设置。

对我来说,绝对最好的解决方案是使用kafkatunnel(https://github.com/simple-machines/kafka-tunnel(。像魅力一样工作。

更改/etc/hosts文件不是正确的方法。

引用Confluent博客文章:

我看到一个堆栈溢出答案,建议只更新我的主机文件......这不是更容易吗?

这只不过是解决错误配置而不是实际修复它的黑客。

您需要将advertised.listeners(如果使用 Docker 映像,则KAFKA_ADVERTISED_LISTENERS(设置为外部地址(主机/IP(,以便客户端可以正确连接到它。否则,他们将尝试连接到内部主机地址,如果无法访问,则问题接踵而至。

融合博客文章

此外,您可以在GitHub上查看此拉取请求,我在其中编写了一个集成测试以通过SSH连接到Kafka。即使您不了解 Golang,也应该很容易理解。

那里有一个完整的客户端和服务器示例(请参阅TestSSH(。该测试正在启动实际的Docker容器,并针对它们运行断言。

TL;DR我必须在通过 SSH 连接时配置KAFKA_ADVERTISED_LISTENERS,以便每个代理通告的主机都可以从 SSH 主机访问。这是因为客户端首先连接到 SSH 主机,然后从那里连接到 Kafka 代理。因此,advertised.listeners中的主机必须可从 SSH 服务器访问。

最新更新