You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure容器实例中Docker Compose多容器(Zookeeper+Kafka+Python脚本)无法连接Kafka的问题求助

问题根源与解决方案

你遇到的核心问题是Azure容器实例(ACI)容器组的网络模型和本地Docker Compose的Bridge网络存在本质差异,导致容器名称解析失效。

为什么本地正常但Azure不行?

本地Docker Compose使用bridge网络时,每个容器拥有独立IP,Docker内置DNS会将服务名(比如kafka)解析为对应容器的IP,因此生产者能通过kafka:9092正常连接。

但Azure容器组内的所有容器共享同一个网络命名空间(相当于共用一个IP和端口栈),容器之间无法通过服务名/容器名称进行DNS解析,必须通过localhost+目标端口来互相访问。


具体修复步骤

1. 调整Kafka的监听与广告配置

修改docker-compose.yml中Kafka服务的环境变量,适配ACI的网络模型:

kafka:
  image: confluentinc/cp-kafka:latest
  container_name: kafka
  depends_on:
    - zookeeper
  ports:
    - 29092:29092
  environment:
    KAFKA_BROKER_ID: 1
    KAFKA_ZOOKEEPER_CONNECT: localhost:2181  # 同一网络栈下用localhost访问Zookeeper
    KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092,PLAINTEXT_HOST://<你的容器组公网IP或DNS>:29092
    KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,PLAINTEXT_HOST://0.0.0.0:29092  # 显式监听所有接口
    KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
    KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
    KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

注:<你的容器组公网IP或DNS>替换为ACI容器组的实际公网访问地址,如果不需要外部访问Kafka,也可以移除PLAINTEXT_HOST部分。

2. 修改Python生产者的连接地址

让生产者通过环境变量动态获取Kafka地址,同时适配本地和Azure环境:

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()))

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()

# 从环境变量取地址,本地默认用kafka:9092,Azure用localhost:9092
kafka_servers = os.getenv('KAFKA_SERVERS', 'kafka:9092')
producer = Producer({'bootstrap.servers': kafka_servers})

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

3. 同步更新生产者容器的环境变量

在docker-compose.yml的kafka_producer服务中,将连接地址改为localhost:9092:

kafka_producer:
  build: ../kafka_producer
  image: annabotkafka.azurecr.io/kafka_producer:v1
  container_name: kafka_producer
  depends_on:
    - kafka
  volumes:
    - .:/usr/src/kafka_producer
  environment:
    KAFKA_SERVERS: localhost:9092

4. 移除不必要的自定义网络(可选)

ACI容器组默认共享网络,无需自定义my-network,可以删除docker-compose.yml中的networks节点,简化配置。


验证与后续扩展

修改完成后,重新构建镜像并推送到Azure容器注册表(ACR),再通过az container create --file docker-compose.yml --resource-group <你的资源组>部署到ACI,生产者应该能正常连接Kafka并发送消息。

如果后续需要部署多个Python脚本容器,只需保证它们和Kafka/Zookeeper在同一个ACI容器组内,并且都用localhost+对应端口访问即可。

内容的提问来源于stack exchange,提问作者db533

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 06:24:08