无法将Docker应用连接到Kafka Docker容器。

3

我正在尝试连接本地运行的Kafka容器和docker镜像,不想创建一个包含Kafka和Zookeeper镜像的容器。

当我在没有将其docker化的情况下运行应用程序时,它可以正常工作。

在运行dockerize应用程序后,docker日志显示

could not read message dial tcp 172.21.0.3:9092: i/o timeout

在Kafka日志中,它显示

kafka-zookeeper-1  | 2021-12-07 06:17:15,755 [myid:1] - WARN  [NIOWorkerThread-7:ZooKeeperServer@1411] - Connection request from old client /172.18.0.1:56350; will be dropped if server is in r-o mode

这是用于kafka的Docker Compose文件。
version: "3"
services:
  zookeeper:
    image: 'bitnami/zookeeper:latest'
    ports:
      - '2181:2181'
    environment:
      - ALLOW_ANONYMOUS_LOGIN=yes
  kafka:
    image: 'bitnami/kafka:latest'
    ports:
      - '9092:9092'
    environment:
      - KAFKA_BROKER_ID=1
      - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092
      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9092
      - KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
      - ALLOW_PLAINTEXT_LISTENER=yes
    depends_on:
      - zookeeper
    volumes:
      - /Users/myuser/docker/volumes/kafka:/var/lib/kafka/data
    

请问有人能帮忙吗?我做错了什么?


请阅读 Bitnami 镜像自述文件中有关外部和内部客户端的部分。此外,如果您正在 Docker 中运行应用程序,则应将其包含在此 Compose 文件中。 - OneCricketeer
2个回答

1
当我在没有将应用程序docker化的情况下运行它时,它能够正常工作。基本上,您希望您的应用程序在两种情况下连接到Kafka,对吗?
  • 当您在本地运行应用程序(在主机上)
  • 当您将其作为docker化应用程序运行时。
但是,您只向127.0.0.1:9092(主机)广告一个侦听器,因此即使docker化的客户端(您的应用程序)可以访问Kafka容器,由于误导性的侦听器配置,它仍将无法建立连接。
例如,我可以使用此功能为两个不同的网络(docker网络和主机上的本地主机)广告两个不同的侦听器:
KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://broker:29092,PLAINTEXT_HOST://localhost:9092

当我运行我的Docker应用程序时,它可以通过broker:29092连接到Kafka。同样地,当我在主机上运行该应用程序时,它可以通过localhost:9092连接到Kafka。 这篇文章提供了更详细的解释,说明Kafka广告侦听器是如何工作以及我们应该如何配置它们。它基本上说:
您需要将advertised.listeners(或如果使用Docker镜像,则为KAFKA_ADVERTISED_LISTENERS)设置为外部地址(主机/IP),以便客户端可以正确连接到它。否则,他们将尝试连接到内部主机地址 - 如果无法访问,则会出现问题。

0

这是你的答案:

  • 你必须使用主机IP地址。不要使用127.0.0.1或容器IP地址。
  • 因为,代理正在向其客户端广告其ADVERTISED_LISTENERS,而客户端尝试连接到这些地址。
  • 因此,在ADVERTISED_LISTENERS中的IP地址必须可以从容器外部或其他容器访问。
  • 请参考以下示例
...
      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://<hostip>:9092
...

那么为什么我的应用程序在未被 Docker 化的容器中时会连接到代理? - Rachit Kawar
使用主机IP并不是“必须的”。使用可解析的地址,无论客户端从哪里运行都可以。在容器之间,这将是服务名称,而不是特定的IP。假设应用程序未容器化Kafka侦听器端口已转发,则广告本地主机是可以的。 - OneCricketeer
@RachitKawar,您的问题是错误的。只有在同一主机上运行的应用程序才能连接到代理。在其他主机上运行的应用程序无法连接到将其公布为127.0.0.1localhost的代理。如果代理未经docker化,则可以省略advertised.listeners配置。 - J. Song

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接