【问题标题】:Why Kafka broker connects to itself?为什么 Kafka 代理连接到自身?
【发布时间】:2017-07-14 06:29:53
【问题描述】:

几天前,我尝试使用 Docker Compose 和端口映射配置 Kafka Docker 容器,并发现了我不完全理解的有趣行为:

Kafka 代理似乎连接到自身。为什么?

我的设置是:

  • Ubuntu 14.04、Docker 1.13.1、Docker-Compose 1.5.2
  • Kafka 0.10 监听 9092 端口,该端口被容器暴露。
  • 在 Docker Compose 中,我有从容器端口 9092 到本地端口 4005 的端口映射。
  • 我在adverted.listeners (docker-host:4005) 中配置了我的Docker 主机的主机名和本地端口,因为我的公司网络应该可以看到代理。

当我尝试向/从 Kafka 发送/获取数据时,通过此设置,所有尝试都以:

Topic metadata fetch included errors: {topic_name=LEADER_NOT_AVAILABLE}

在尝试了advertised.listeners 中端口和主机名的各种组合后,我发现唯一有效的组合是localhost:9092。任何更改主机名或端口的尝试都会导致上述错误。
这让我觉得 Kafka 尝试连接到 advertised.listeners 中配置的地址,这在某种程度上与主题元数据有关。

所以我在 Docker 容器中做了:

  • 将流量重定向到“docker-host”到环回
    echo "127.0.0.1 $ADVERTISED_HOST" >> /etc/hosts
  • 配置 Kafka 监听所有接口和端口(与宣传的完全一样)
    sed -r -i "s/#(listeners)=(.*)/\1=PLAINTEXT:\/\/0.0.0.0:4005/g" $KAFKA_HOME/config/server.properties
  • 宣传“docker-host”和外部端口
    sed -r -i "s/#(advertised.listeners)=(.*)/\1=PLAINTEXT:\/\/$ADVERTISED_HOST:4005/g" $KAFKA_HOME/config/server.properties

现在它就像一个魅力。

但是我还是不明白:

  1. 为什么 Kafka 代理可能需要通过 advertised.listeners 中配置的地址连接到自身?
  2. 有没有办法禁用此功能或至少将其配置为使用“侦听器”属性中的地址(使用默认 Kafka 端口)?

UPD 值得一提的是,以下设置不起作用:Kafka 侦听 0.0.0.0:9092,广告侦听器配置为 docker-host:4005
在这种情况下,只要消费者或生产者连接到 kafka,它就会收到 LEADER_NOT_AVAILABLE。 netstat(在容器内)还显示了与处于 SYN_SENT 状态的 docker-host:4005 的连接。

UPD 2 看起来 Kafka 也有类似的问题,但在 AWS 内部描述了 here
不同之处在于,在我的情况下,我想使用不同的 Kafka 端口。

UPD 3 好的,第一个 UPD 段落中提到的设置不起作用的原因是 - UFW,由于某些原因,它会阻止通过主机从 docker 容器到自身的流量。

【问题讨论】:

    标签: docker apache-kafka docker-compose


    【解决方案1】:

    为什么 Kafka 代理可能需要通过地址连接到自身 在 Advertisementd.listeners 中配置?

    当客户端首次连接 Kafka 代理时,它会回复它希望客户端在未来与代理对话时使用的地址。这是 advertised.listeners 属性中设置的内容。如果您不设置此属性,则将使用来自 listeners 的值(这回答了您的第二个问题)。

    所以您的“问题”是,远程客户端连接到您的主机:9092,到达 Kafka 代理,因为您转发了端口,代理然后响应“您可以在 localhost:9092 与我联系”,当客户端发送那里的下一个数据包只是连接回自身。 元数据在这里并不真正相关,它只是发出的第一个请求。 我认为您的解决方案对于此设置是正确的,让 Kafka 在本地接口上侦听并将adverted.listeners 设置为您公司网络中的某个人将连接到的主机。 我不是 100% 知道代理是否也需要连接到自己,但很确定不是这样。我认为您的设置也可以在 /etc/hosts 文件中不输入外部主机名的情况下工作。

    有没有办法禁用此功能或至少将其配置为使用地址 来自“listeners”属性(使用默认的 Kafka 端口)?

    见上

    【讨论】:

    • 嗨 Sönke,感谢您的回答,您对“listener”和“advertised.listener”的含义是正确的,但是当我配置不同的地址和端口时(请参阅我更新的问题)它仍然没有工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    • 2021-12-22
    • 2018-12-24
    • 2018-02-17
    • 2022-01-06
    • 1970-01-01
    • 2020-08-13
    相关资源
    最近更新 更多