基于KRaft的Docker Compose中init-kafka无法连接Kafka的修复方案
问题解决思路
核心原因
你遇到的问题是Kafka的advertised.listeners配置不正确,导致init-kafka容器请求主题列表时,Kafka返回的是localhost:9092而非容器间可访问的服务地址。在init-kafka容器内部,localhost指向容器自身,而非kafka容器,因此无法建立连接。
解决方案
1. 修正Kafka容器的监听配置
在Docker Compose的kafka服务中,必须明确设置LISTENERS和ADVERTISED_LISTENERS,区分容器间通信和主机通信的地址:
LISTENERS:指定Kafka监听的端口和地址,0.0.0.0表示监听所有网卡ADVERTISED_LISTENERS:告诉客户端(包括init-kafka容器)应该使用哪个地址连接Kafka
示例配置:
environment: KAFKA_NODE_ID: 1 KAFKA_PROCESS_ROLES: controller,broker KAFKA_CONTROLLER_QUORUM_VOTERS: 1@dotnetbus-kafka:9093 # 监听配置 KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093,PLAINTEXT_HOST://0.0.0.0:29092 KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://dotnetbus-kafka:9092,PLAINTEXT_HOST://localhost:29092 KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT # 其他KRaft必要配置 KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1 KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
2. 用健康检查替代固定sleep
不要用sleep 1000等待Kafka启动,而是通过Docker的healthcheck确保Kafka完全就绪后,再执行init-kafka的命令:
dotnetbus-kafka: # ...其他配置 healthcheck: test: ["CMD", "kafka-topics.sh", "--bootstrap-server", "localhost:9092", "--list"] interval: 10s timeout: 5s retries: 5 init-kafka: image: apache/kafka:3.8.0 depends_on: dotnetbus-kafka: condition: service_healthy command: > sh -c " # 创建主题示例 kafka-topics.sh --bootstrap-server dotnetbus-kafka:9092 --create --topic your-topic --partitions 1 --replication-factor 1 --if-not-exists; # 验证连接 kafka-topics.sh --bootstrap-server dotnetbus-kafka:9092 --list; # 可选:保持容器运行以便调试 sleep infinity "
3. 验证修复效果
重新启动Docker Compose后,进入init-kafka容器执行命令:
/opt/kafka/bin/kafka-topics.sh --bootstrap-server dotnetbus-kafka:9092 --list
此时应该能正常列出Kafka主题,不会再出现连接localhost失败的错误。
内容的提问来源于stack exchange,提问作者Grant Birchmeier
相关产品推荐
相关产品推荐

