首页 > 解决方案 > 无法从外部客户端连接到 kafka docker 容器(wurstmeister 图像)

问题描述

这个问题有很多答案,以至于我最终对如何从外部客户端连接到 Kafka docker 容器感到完全困惑。

我用这些命令创建了两台 docker 机器,一个 manager 和一个 worker:

docker-machine create manager
docker-machine create worker1

我在 docker swarm 中添加了这两个节点。

docker@manager:~$ docker node ls                                                                                                                                                                             
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
6bmovp3hr0j2w5irmexvvjgzq *   manager             Ready               Active              Leader              19.03.5
mtgbd9bg8d6q0lk9ycw10bxos     worker1             Ready               Active                                  19.03.5

docker-compose.yml

version: '3.2'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"
  kafka:
    image: wurstmeister/kafka:latest
    ports:
      - target: 9094
        published: 9094
        protocol: tcp
        mode: host
    environment:
      HOSTNAME_COMMAND: "hostname | awk -F'-' '{print $$2}'"
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_ADVERTISED_LISTENERS: INSIDE://:9092,OUTSIDE://_{HOSTNAME_COMMAND}:9094
      KAFKA_LISTENERS: INSIDE://:9092,OUTSIDE://:9094
      KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

从 docker 内部,一切正常。我可以创建主题,然后生成/使用消息。

我创建了一个 python 脚本来使用来自外部 docker 的消息。简单的代码如下所示:

from kafka import KafkaConsumer
import json

try:
    print('Welcome to parse engine')
    consumer = KafkaConsumer('streams-plaintext-input', bootstrap_servers='manager:9094')
    for message in consumer:
        print(message)
except Exception as e:
    print(e)
    # Logs the error appropriately. 
    pass

但是代码永远是堆栈的。连接不正确。谁能提供有关如何设置连接的任何帮助?

标签: dockerapache-kafkadockerfiledocker-machinekafka-python

解决方案


既然你正在使用docker-machine你必须要么

  1. 也在容器中运行您的代码(使用kafka:9092
  2. 在 VM 操作系统中运行您的代码(使用vm-host-name:9094
  3. 添加PLAINTEXT://localhost:9096到广告侦听器,将 9096 从 VM 公开到您的主机,然后localhost:9096在您的代码中使用(注意:9096 是一些随机端口)

要点是客户端必须能够连接到引导地址正在返回的广告地址。如果它无法连接到第二个,代码将超时。


推荐阅读