当前位置: 首页 > 知识库问答 >
问题:

Docker/Kafka连接两个不同的容器

史钊
2023-03-14

我正在使用wurstmeister的docker-kafka项目在容器中运行kafka/zoomaster。我使用docker-comup将容器localhost作为KAFKA_ADVERTISED_HOST_NAME:localhost变量。

我已经编写了一个Java应用程序,它使用flink连接并使用这个Kafka容器的一个主题。如果我导出一个可运行的罐子,并从我的机器上运行它,它绝对可以正常工作。当我创建下面的图像以从另一个docker容器运行jar时,我在线程“main”组织中收到一个异常(执行后大约30秒)exception。阿帕奇。Flink。运行时。客户JobExecutionException:org。阿帕奇。Kafka。常见的错误。TimeoutException:获取主题元数据时超时,我认为这与我的Java程序无法与另一个容器中运行的Kafka服务器通信有关。

以下是我的Java应用程序的dockerfile:

# Dockerfile

FROM anapsix/alpine-java

MAINTAINER myself myself

COPY myApp.jar /home/myApp.jar

CMD ["java","-jar","/home/myApp.jar"]

这是沃斯特迈斯特的码头工人Kafka的docker-compose.yml:

version: "3.5"

networks:
  myNetwork:
    name: myNetwork
    driver: bridge

services:
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"
    networks:
      - myNetwork
  kafka:
    build: .
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: localhost
      KAFKA_ADVERTISED_PORT: "9092"
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
      ALLOW_PLAINTEXT_LISTENER: "yes"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - myNetwork
  auth_analytics:
      build: 
        context: .
        dockerfile: auth_dockerfile
      depends_on:
        - kafka
      networks:
        - myNetwork

我已经尝试了上面的多个版本。起初,我没有设置任何网络,我认为这可能是个问题,但是,上面创建网络没有任何区别。我在Java应用程序中尝试了“localhost:9092”作为引导服务器,在网上阅读时尝试了“myNetwork: 9092”。

我还阅读了wurstmeister关于连接性的FAQ,但我没有发现我的设置有问题。

我也试过在不使用docker-comush的情况下运行我的Java应用程序映像(我运行docker-comush来启动zooManager/kafka,然后在我Java应用程序的映像上运行docker构建和docker运行。这没有什么不同。)

我卡住了。我做错了什么?

共有2个答案

戎洛城
2023-03-14

KAFKA_ADVERTISED_HOST_NAME:localhost

是你的客户将收到的Kafka连接字符串。这意味着带有应用程序的容器将尝试到达localhost的Kafka,localhost是带有应用程序的容器的本地网络堆栈。

为了解决这个问题,你应该使用kafka主机作为你的kafka_广告_主机_名称和引导服务器——这将允许你的容器在dockers内部连接到kafka,但当你试图通过在PC上运行java-jar连接到kafka时,会破坏配置。。。

要解决此问题,请使用映射Kafka在PC上的主机文件中输入-

耿敏达
2023-03-14

您需要正确设置KAFKA_ADVERTISED_LISTENERS。目前它是localhost,这意味着任何连接的客户端都将被代理告知代理在localhost上-当客户端尝试连接到该代理时,它将失败(除非Kafka代理实际上在localhost上可用,否则它不会在仅运行您的应用程序的Docker容器上)。

解决方案是定义侦听器,这样就可以从任何需要侦听器的代理和客户机位置对其进行寻址。我的首选方法是这样的,其中一个用于容器内通信,另一个用于从主机中进行通信:

  KAFKA_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
  KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
  KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
  KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092

Docker网络上的客户使用kafka:29092进行连接;主机上的客户端连接到localhost:9092(并确保通过Docker向主机公开9092)。

要了解更多信息,请参阅https://rmoff.net/2018/08/02/kafka-listeners-explained/

顺便说一句,我强烈建议用正确的方法解决这个问题;重写/etc/hosts文件是一种无法解决实际问题的黑客行为。

 类似资料:
  • 我正在尝试从另一个码头工人容器连接到 kafka docker 容器。但它没有连接。 为了运行kafka和zookeeper,我使用了docker compose文件: 容器docker compose 17138956372294708100 _ kafkatest . producer _ 1和docker compose 17138956372294708100 _ kafkatest .

  • 我试图连接两个conainers使用网络docker,但由于某种原因,我得到一个错误: MongoNetworkError:在第一次连接时无法连接到服务器[db:27017][错误:connect-EConRefuse172.22.0.3:27017] 有什么建议吗? 谢谢 docker-compose.yml

  • : : 这是行不通的,因为链接的容器没有配置在同一个文件中。但有没有办法实现类似的事情呢? 我想有一个更干净的设置,以设置我的生产环境,使我能够重新启动只有相关的位,改变,而不是所有的一次。

  • 我有两个不同的服务器和,现在我有中的和中的。我试图加入这两个表在MySQL像这样。 但是我犯了一个错误。这在MYSQL中是可能的。

  • 我有一个dockerized应用程序,其中有几个服务使用Docker-Compose运行。我想使用另一个docker-compose应用程序docker-elk将这个应用程序与elasticsearch/logstash/kibana(ELK)连接起来。两者都运行在开发中的同一台docker机器中。在生产中,情况可能就不是这样了。 如何配置应用程序的链接到ELK堆栈?

  • 主要内容:网络端口映射,Docker 容器互联,配置 DNS前面我们实现了通过网络端口来访问运行在 docker 容器内的服务。 容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。 下面我们来实现通过端口连接到一个 docker 容器。 网络端口映射 我们创建了一个 python 应用的容器。 另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。 我们使用 -P 绑定端口号,使用 dock