【问题标题】:Docker compose multi-container with zookeeper, kafka and python script on Azure container instances not able to connect to kafkaDocker在无法连接到kafka的Azure容器实例上使用zookeeper、kafka和python脚本编写多容器
【发布时间】:2021-08-19 19:36:56
【问题描述】:

我正在尝试获取 zookeeper/kafka 非集群设置,以便能够使用 python 脚本与容器通信。我希望能够运行一个 zookeeper/kafka 容器和 2 个或多个带有与 zookeeper/kafka 通信的 python 脚本的容器,它们都在 Azure 上的容器或容器组中运行。

为了测试这一点,我创建了下面的 docker 容器组,其中 zookeeper 和 kafka 作为 2 个服务和第 3 个服务,它启动一个简单的 python 脚本来为 kafka 主题生成稳定的消息。我使用的 docker-compose.yml 如下:

version: '2'
services:
  zookeeper:
    image: confluentinc/cp-zookeeper:latest
    container_name: zookeeper
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
    ports:
      - 22181:2181
    networks:
      - my-network

  kafka:
    image: confluentinc/cp-kafka:latest
    container_name: kafka
    depends_on:
      - zookeeper
    ports:
      - 29092:29092
    networks:
      - my-network
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
  kafka_producer:
    build: ../kafka_producer
    image: annabotkafka.azurecr.io/kafka_producer:v1
    container_name: kafka_producer
    depends_on:
      - kafka
    volumes:
      - .:/usr/src/kafka_producer
    networks:
      - my-network
    environment:
      KAFKA_SERVERS: kafka:9092
networks:
  my-network:
    driver: bridge

kafka_producer.py脚本如下:

import os
from time import sleep
import json
from confluent_kafka import Producer

def acked(err, msg):
    if err is not None:
        print("Failed to deliver message: {0}: {1}"
              .format(msg.value(), err.str()))
    else:
        print("Message produced: {0}".format(msg.value()))

# Function to send a status message out on the status topic
def send_status(producer,counter):
    msg = {'counter':counter}
    json_dump = json.dumps(msg)
    producer.produce("counter", json_dump.encode('utf-8'), callback=acked)
    producer.poll()

# Define kafkaProducer to push messages to the status topic
producer = Producer({'bootstrap.servers': 'kafka:9092'})

for j in range(9999):
    print("Iteration", j)
    send_status(producer, j)
    sleep(2)

当我在我的 Ubuntu 20.04 开发机器上 'docker-compose up' 时,我得到了预期的行为:一个稳定的消息流发送到 kafka 生产者。

在我将其“docker-compuse push”到 Azure 容器实例并在 Azure 中使用映像创建容器后,kafka_producer 脚本似乎不再能够连接到位于 kafka:9092 的 kafka 代理。

这些是容器组启动后的日志:

Iteration 0
%3|1629363616.468|FAIL|rdkafka#producer-1| [thrd:kafka:9092/bootstrap]: kafka:9092/bootstrap: Failed to resolve 'kafka:9092': Name or service not known (after 25ms in state CONNECT)
%3|1629363618.465|FAIL|rdkafka#producer-1| [thrd:kafka:9092/bootstrap]: kafka:9092/bootstrap: Failed to resolve 'kafka:9092': Name or service not known (after 22ms in state CONNECT, 1 identical error(s) suppressed)
Iteration 1
Iteration 2

我知道容器组位于同一网络子网和单个主机上,因此我希望它与本地开发机器上的操作相同。

我的下一步将是拥有带有不同 python 脚本的单独容器,我希望在这个容器组中与 kafka 进行通信。将生产者脚本放在同一个容器组中并不是我的长期期望,但我相信这种更简单的设置应该可行。

对我哪里出错有什么建议吗?

【问题讨论】:

  • 您在 Azure 中实际在哪里运行 Kafka?我非常怀疑您是否在容器中运行它(或者至少,您绝对不应该,因为它的数据不是持久的)。无论如何你都应该阅读这篇文章confluent.io/blog/kafka-listeners-explained
  • @OneCricketeer 我确实在容器实例中运行它。在我的用例中,kafka 在多个脚本之间提供异步消息传递。在这种情况下,缺乏持久性不是问题。我会尽快查看您分享的链接。
  • 当然,但我的观点是,您可以/应该在实际的持久性 VM 实例/AKS 中运行 Kafka,或者在 Kafka 模式下使用事件中心

标签: apache-kafka docker-compose apache-zookeeper azure-container-instances


【解决方案1】:

来自 Azure 文档

在容器组内,容器实例可以在任何端口上通过 localhost 相互访问,即使这些端口未在组的 IP 地址或容器外部公开。

这听起来像是容器正在使用主机网络,而不是像您在 Compose 中设置的 Docker 网桥(您的代码可以正常工作)

因此,你应该联系localhost:29092

如果您实际上不需要消息持久性,那么我建议您在脚本之间通过 HTTP、gRPC 或 Zeromq 使用套接字,而不是使用 Kafka 容器

【讨论】:

  • 感谢您的良好反馈。一直在探索事件中心,这看起来是比使用 zookeeper 和 kafka 创建容器更好的解决方案。
猜你喜欢
  • 2019-10-23
  • 2020-02-09
  • 1970-01-01
  • 2020-01-30
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 2018-06-23
  • 2020-11-02
相关资源
最近更新 更多