【问题标题】:Connect to Apache Kafka brokers running in Docker Container连接到在 Docker Container 中运行的 Apache Kafka 代理
【发布时间】:2021-11-20 04:56:20
【问题描述】:

我正在尝试在 docker 容器上部署 Apache Kafka(不是 Confluent Kafka),并使用 kafka-python 的生产者和消费者 api 连接到它。生产者api和消费者api应该能够在docker容器之外运行。


管道由一个 zookeeper 实例和 3 个 Kafka 代理组成,每个代理位于一个单独的容器中。以下是我用来初始化容器的 docker-compose 代码。

services: 
zookeeper-1:
    container_name: zookeeper-1
    image: zookeeper:2.7.0
    build:
      context: ./zookeeper
    volumes:
    - ./config/zookeeper-1/zookeeper.properties:/kafka/config/zookeeper.properties

kafka-1:
    container_name: kafka-1
    image: kafka:2.7.0
    build: 
        context: .
    volumes:
    - ./config/kafka-1/server.properties:/kafka/config/server.properties
    - ./data/kafka-1/:/tmp/kafka-logs/

kafka-2:
    container_name: kafka-2
    image: kafka:2.7.0
    build: 
        context: .
    volumes:
    - ./config/kafka-2/server.properties:/kafka/config/server.properties
    - ./data/kafka-2/:/tmp/kafka-logs/

kafka-3:
    container_name: kafka-3
    image: kafka:2.7.0
    build: 
        context: .
    volumes:
    - ./config/kafka-3/server.properties:/kafka/config/server.properties
    - ./data/kafka-3/:/tmp/kafka-logs/

我能够在 docker 映像中使用 cli 生成和使用消息。


我希望能够从 docker 容器外部访问它。我知道它需要通过添加侦听器来修改 docker-compose 脚本,但我是 Docker 新手,无法正确添加侦听器。

请提出所需的补充,以便我可以在同一台机器上从容器外部访问 Kafka。


P.S.:我已经访问了大部分关于 SO 的 kafka docker 容器讨论,包括“Connect to Kafka running in Docker”、“Interact with kafka docker container from outside of docker host [duplicate]”,但他们没有回答我的问题。

【问题讨论】:

  • 1) 在一台机器上运行多个代理不会改善任何东西,而且会浪费您的硬盘寿命和空间 2) buildimage 不应该一起使用。 3) 您目前的配置是什么样的 4) 您了解您需要听众,那么您尝试了哪些内容以及链接帖子中不清楚的地方,以便未来的读者可以从集中的答案中受益?

标签: docker apache-kafka docker-compose


【解决方案1】:

您可以向每个 Kafka 构建添加环境变量,以允许通过一个端口进行内部 DNS 访问,并通过另一个端口进行外部访问。例如,对于 kafka-1,我们可以公开一个端口并添加环境变量,这将使 Kafka 通过 localhost(即在您的主机上运行的 Python 生产者)侦听连接:

kafka-1:
  container_name: kafka-1
  image: kafka:2.7.0
  build: 
    context: .
  volumes:
  - ./config/kafka-1/server.properties:/kafka/config/server.properties
  - ./data/kafka-1/:/tmp/kafka-logs/
ports:
  - 9092:9092
environment:
  KAFKA_ADVERTISED_HOST_NAME: kafka-1
  KAFKA_BROKER_ID: 1
  KAFKA_ZOOKEEPER_CONNECT: zookeeper-1:2181
  KAFKA_LISTENERS: PLAINTEXT://kafka-1:29092,PLAINTEXT_HOST://localhost:9092
  KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-1:29092,PLAINTEXT_HOST://localhost:9092
  KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
  KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
  KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

我确实看到您正在执行 docker build,因此无法确定您的配置和设置,但如果环境变量不合适,您可以将相同的设置添加到已安装的配置文件 server.properties

我还假设 zookeeper 服务于 2181 端口,以上不考虑安全要求等。

Kafka 侦听器使用与它们连接的相同名称,并且在建立连接时,只有与该侦听器关联的名称与它连接的名称匹配时才会成功。例如:

  • Kafka-python 客户端连接到主机上运行的“localhost:9092”
  • Kafka 服务器将“localhost”中继回来,因为这是与 9092 关联的名称
  • 连接成功

但是,这不起作用:

  • Kafka-python 客户端远程运行,通过“SERVERIP:9092”连接到主机
  • Kafka 服务器将“localhost”中继回来,因为这是与 9092 关联的名称
  • 由于名称不匹配,连接失败

如果您需要远程访问,请将您的 Kafka 配置中的 localhost 更改为 0.0.0.0

要在此 docker-compose 设置中使用多个代理,请对 kafka-1 使用 9092,对 kafka-2 使用 9093,对 kafka-3 使用 9094,并分别公开这些端口。那么你的引导服务器就是:

localhost:9092, localhost:9093, localhost:9094

您也可以设置多个侦听器,因此您可以有一个端口用于 localhost 访问,一个用于内部网络 DNS 访问(在 docker-compose 内),另一个用于远程访问,并更改每种类型的安全设置。 This link provides more information on that.

【讨论】:

  • 这个答案假设使用的图像接受那些环境变量
  • 感谢您的回答。如果我需要任何进一步的说明,我会尝试实施并回复您。
猜你喜欢
  • 2020-04-22
  • 2018-06-07
  • 2020-09-12
  • 2016-12-18
  • 1970-01-01
  • 2021-07-21
  • 2022-11-18
  • 2018-07-25
  • 1970-01-01
相关资源
最近更新 更多