从 docker 主机外部与 kafka docker 容器交互
Interact with kafka docker container from outside of docker host
我构建了一个 kafka docker 容器并使用 docker-compose 对其进行编排。
调用 docker ps
我得到以下输入:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5bde6f76246e hieutrtr/docker-kafka:0.0.1 "/start.sh" About an hour ago Up About an hour 7203/tcp, 0.0.0.0:32884->9092/tcp dockerkafka_kafka_3
be354f1b8cc0 hieutrtr/docker-ubuntu:devel "/usr/bin/supervisor About an hour ago Up About an hour 22/tcp producer1
50d3203af90e hieutrtr/docker-kafka:0.0.1 "/start.sh" About an hour ago Up About an hour 7203/tcp, 0.0.0.0:32883->9092/tcp dockerkafka_kafka_2
61b285f39615 hieutrtr/docker-kafka:0.0.1 "/start.sh" 2 hours ago Up 2 hours 7203/tcp, 0.0.0.0:32882->9092/tcp dockerkafka_kafka_1
20c9c5ccec05 jplock/zookeeper:3.4.6 "/opt/zookeeper/bin/ 2 hours ago Up 2 hours 2888/tcp, 3888/tcp, 0.0.0.0:32881->2181/tcp dockerkafka_zookeeper_1
我可以在 docker 容器内 运行 一个生产者和一个消费者,但它在 docker 网络之外无法工作。
例如:
我 运行 我的本地主机上有一个 kafka 生产者,出现以下错误:
$ kafka_2.9.1-0.8.2.1: bin/kafka-console-producer.sh --topic test --broker-list $DOCKER_HOST:32884
[2015-08-31 06:55:15,450] WARN Property topic is not valid (kafka.utils.VerifiableProperties)
to
[2015-08-31 06:55:20,214] WARN Failed to send producer request with correlation id 2 to broker 1 with data for partitions [test,0] (kafka.producer.async.DefaultEventHandler)
java.nio.channels.ClosedChannelException
at kafka.network.BlockingChannel.send(BlockingChannel.scala:100)
at kafka.producer.SyncProducer.liftedTree1(SyncProducer.scala:73)
at kafka.producer.SyncProducer.kafka$producer$SyncProducer$$doSend(SyncProducer.scala:72)
at kafka.producer.SyncProducer$$anonfun$send$$anonfun$apply$mcV$sp.apply$mcV$sp(SyncProducer.scala:103)
at kafka.producer.SyncProducer$$anonfun$send$$anonfun$apply$mcV$sp.apply(SyncProducer.scala:103)
at kafka.producer.SyncProducer$$anonfun$send$$anonfun$apply$mcV$sp.apply(SyncProducer.scala:103)
This is my kafka docker example on github 包含上述问题。
那么,有没有人遇到同样的问题并且可以以任何方式帮助我?
附加信息:
(只是从 ches/kafka 分叉并为 docker-compose 修改一些东西):
在 Kafka 服务器属性中,您需要将 advertised.listeners
设置为 运行 容器的 ip/port,然后它应该可以工作。
您需要输入部署了 docker 实例的主机名称。您还需要将端口从 docker 主机(public)映射到 docker 容器实例(私有)。
TL;DR 在主机上公开端口 9092 并将其映射到 9092 容器端口以访问容器外部的 kafka 代理。有关详细信息,请参阅 docker-compose 文档。
我认为问题在于您没有在容器外部公开端口 9092。根据您的 docker ps 列表,您的 9092 容器端口动态映射到主机的端口范围 32882-32884。
当您连接到以这种方式配置的代理时,您会收到包含用于广告的端口 9092 的元数据。使用此元数据生成器尝试通过端口 9092 执行其他请求但失败。
郑重声明,让我的本地 kafka 消费者与 Docker 容器内的远程代理通信的另一种方法是在我的 /etc/hosts[=21= 中添加一个条目] : docker-host-ip-address docker-kafka-container-hostname
无论如何,Lundahl 的解决方案对我来说效果很好,而且看起来更干净。更清洁的方法是设置 advertised.listeners=host-ip:port 因为advertised.host.name 和 advertised.port 已弃用。
这是我的两分钱,因为我很难弄清楚这一点。
我的 $KAFKA_HOME/config/server.properties 包含以下内容:
listener.security.protocol.map=INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
advertised.listeners=INSIDE://${container_ip}:9092,OUTSIDE://${outside_host_ip}:29092
listeners=INSIDE://:9092,OUTSIDE://:29092
inter.broker.listener.name=INSIDE
这将创建两个连接,一个在 docker 内部使用,另一个在外部使用。您必须为后者选择一个新端口,在我的例子中是 29092,确保此端口已公开并由 docker 映射。
如果环境中没有 ${outside_host_ip},我还无法找到解决方案,因此我将主机的 ip 作为环境变量提供。
测试:
- 进入Kafka容器并创建主题:
./kafka-topics.sh -zookeeper zookeeper:2181 --create --topic dummytopic --partitions 1 --replication-factor 1
- 从 Kafka 容器外部执行:
./kafka-console-producer.sh --broker-list 0.0.0.0:29092 --topic dummytopic
并输入消息
我希望这对其他人有帮助
我构建了一个 kafka docker 容器并使用 docker-compose 对其进行编排。
调用 docker ps
我得到以下输入:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5bde6f76246e hieutrtr/docker-kafka:0.0.1 "/start.sh" About an hour ago Up About an hour 7203/tcp, 0.0.0.0:32884->9092/tcp dockerkafka_kafka_3
be354f1b8cc0 hieutrtr/docker-ubuntu:devel "/usr/bin/supervisor About an hour ago Up About an hour 22/tcp producer1
50d3203af90e hieutrtr/docker-kafka:0.0.1 "/start.sh" About an hour ago Up About an hour 7203/tcp, 0.0.0.0:32883->9092/tcp dockerkafka_kafka_2
61b285f39615 hieutrtr/docker-kafka:0.0.1 "/start.sh" 2 hours ago Up 2 hours 7203/tcp, 0.0.0.0:32882->9092/tcp dockerkafka_kafka_1
20c9c5ccec05 jplock/zookeeper:3.4.6 "/opt/zookeeper/bin/ 2 hours ago Up 2 hours 2888/tcp, 3888/tcp, 0.0.0.0:32881->2181/tcp dockerkafka_zookeeper_1
我可以在 docker 容器内 运行 一个生产者和一个消费者,但它在 docker 网络之外无法工作。
例如:
我 运行 我的本地主机上有一个 kafka 生产者,出现以下错误:
$ kafka_2.9.1-0.8.2.1: bin/kafka-console-producer.sh --topic test --broker-list $DOCKER_HOST:32884
[2015-08-31 06:55:15,450] WARN Property topic is not valid (kafka.utils.VerifiableProperties)
to
[2015-08-31 06:55:20,214] WARN Failed to send producer request with correlation id 2 to broker 1 with data for partitions [test,0] (kafka.producer.async.DefaultEventHandler)
java.nio.channels.ClosedChannelException
at kafka.network.BlockingChannel.send(BlockingChannel.scala:100)
at kafka.producer.SyncProducer.liftedTree1(SyncProducer.scala:73)
at kafka.producer.SyncProducer.kafka$producer$SyncProducer$$doSend(SyncProducer.scala:72)
at kafka.producer.SyncProducer$$anonfun$send$$anonfun$apply$mcV$sp.apply$mcV$sp(SyncProducer.scala:103)
at kafka.producer.SyncProducer$$anonfun$send$$anonfun$apply$mcV$sp.apply(SyncProducer.scala:103)
at kafka.producer.SyncProducer$$anonfun$send$$anonfun$apply$mcV$sp.apply(SyncProducer.scala:103)
This is my kafka docker example on github 包含上述问题。
那么,有没有人遇到同样的问题并且可以以任何方式帮助我?
附加信息:
(只是从 ches/kafka 分叉并为 docker-compose 修改一些东西):
在 Kafka 服务器属性中,您需要将 advertised.listeners
设置为 运行 容器的 ip/port,然后它应该可以工作。
您需要输入部署了 docker 实例的主机名称。您还需要将端口从 docker 主机(public)映射到 docker 容器实例(私有)。
TL;DR 在主机上公开端口 9092 并将其映射到 9092 容器端口以访问容器外部的 kafka 代理。有关详细信息,请参阅 docker-compose 文档。
我认为问题在于您没有在容器外部公开端口 9092。根据您的 docker ps 列表,您的 9092 容器端口动态映射到主机的端口范围 32882-32884。 当您连接到以这种方式配置的代理时,您会收到包含用于广告的端口 9092 的元数据。使用此元数据生成器尝试通过端口 9092 执行其他请求但失败。
郑重声明,让我的本地 kafka 消费者与 Docker 容器内的远程代理通信的另一种方法是在我的 /etc/hosts[=21= 中添加一个条目] : docker-host-ip-address docker-kafka-container-hostname
无论如何,Lundahl 的解决方案对我来说效果很好,而且看起来更干净。更清洁的方法是设置 advertised.listeners=host-ip:port 因为advertised.host.name 和 advertised.port 已弃用。
这是我的两分钱,因为我很难弄清楚这一点。
我的 $KAFKA_HOME/config/server.properties 包含以下内容:
listener.security.protocol.map=INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
advertised.listeners=INSIDE://${container_ip}:9092,OUTSIDE://${outside_host_ip}:29092
listeners=INSIDE://:9092,OUTSIDE://:29092
inter.broker.listener.name=INSIDE
这将创建两个连接,一个在 docker 内部使用,另一个在外部使用。您必须为后者选择一个新端口,在我的例子中是 29092,确保此端口已公开并由 docker 映射。
如果环境中没有 ${outside_host_ip},我还无法找到解决方案,因此我将主机的 ip 作为环境变量提供。
测试:
- 进入Kafka容器并创建主题:
./kafka-topics.sh -zookeeper zookeeper:2181 --create --topic dummytopic --partitions 1 --replication-factor 1
- 从 Kafka 容器外部执行:
./kafka-console-producer.sh --broker-list 0.0.0.0:29092 --topic dummytopic
并输入消息
我希望这对其他人有帮助