Docker在Azure容器示例上使用zookeeper、Kafka和python脚本编写多容器,无法连接到kafka

wwodge7n  于 2022-12-09  发布在  Apache
关注(0)|答案(1)|浏览(140)

我正在尝试获得一个zookeeper/Kafka非集群设置,以便能够与带有python脚本的容器进行通信。我希望能够运行一个zookeeper/kafka容器和两个或更多个带有python脚本的容器与zookeeper/kafka进行通信,所有这些都在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'这个时,我得到了预期的行为:源源不断地发送给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进行通信。在同一个容器组中使用producer脚本并不是我的长期期望,但我相信这个简单的设置应该可以工作。
对于我哪里出错有什么建议吗?

i2loujxw

i2loujxw1#

从Azure文档
在容器组中,容器示例可以通过任何端口上的localhost相互访问,即使这些端口没有在组的IP地址或容器上公开。
这听起来像是容器使用的是主机网络,而不是像您在Compose中设置的Docker网桥(您的代码在这里可以正常工作)
因此,您应该连接localhost:29092
如果您实际上不需要消息持久性,那么我建议在脚本之间通过HTTP、gRPC或Zeromq使用套接字,而不是Kafka容器

相关问题