从docker主机外部与kafka docker容器交互[重复]

Posted

技术标签:

【中文标题】从docker主机外部与kafka docker容器交互[重复]【英文标题】:Interact with kafka docker container from outside of docker host [duplicate] 【发布时间】:2015-11-24 23:14:32 【问题描述】:

我已经构建了一个 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$1(SyncProducer.scala:73)
    at kafka.producer.SyncProducer.kafka$producer$SyncProducer$$doSend(SyncProducer.scala:72)
    at kafka.producer.SyncProducer$$anonfun$send$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(SyncProducer.scala:103)
    at kafka.producer.SyncProducer$$anonfun$send$1$$anonfun$apply$mcV$sp$1.apply(SyncProducer.scala:103)
    at kafka.producer.SyncProducer$$anonfun$send$1$$anonfun$apply$mcV$sp$1.apply(SyncProducer.scala:103)

This is my kafka docker example on github 包含上述问题。

那么,有没有人遇到同样的问题并且可以以任何方式帮助我?

其他信息

(只需从 ches/kafka 分叉并为 docker-compose 修改一些内容):

【问题讨论】:

【参考方案1】:

在 Kafka 服务器属性中,您需要将 advertised.listeners 设置为正在运行的容器的 ip/port,然后它应该可以工作。

【讨论】:

我认为这不是问题。因为我仍然从我的本地主机创建主题。有什么关于 java.rmi.... 的吗? 这对我非常相似的症状有用。我可以从 localhost 或其他容器创建主题,但在设置 advertised.host.name 之前不会发布任何消息 我们应该把什么作为advertised.host.name?面临同样的问题 advertised.host.name 现在已弃用,我不得不使用advertised.listener。【参考方案2】:

您需要输入部署 docker 实例的主机名称。您还需要将端口从 docker 主机(公共)映射到 docker 容器实例(私有)。

【讨论】:

还要确保你没有在 server.properties 中设置任何相关的属性 抱歉输入太早了。 # The id of the broker. This must be set to a unique integer for each broker. broker.id=0 #listeners=PLAINTEXT://localhost:9092 #advertised.listeners=PLAINTEXT://localhost:9092 #advertised.host.name=localhost #advertised.port=9092 请原谅我第一次使用。 server.properties 中设置的值优先,根据我的经验,端口默认为 9092。我在同一个 Kafka 中运行 dev 和 qa docker Kafka。没有在任何地方设置端口,而是使用来自 docker 容器的公开端口作为 9092。将这些端口映射到公共/docker 主机端口,分别为 dev 和 qa 的 9092 和 9192。【参考方案3】:

TL;DR 在主机上公开端口 9092 并将其映射到 9092 容器端口以访问容器外的 kafka 代理。有关详细信息,请参阅docker-compose 文档。

我认为问题在于您没有将端口 9092 暴露在容器外。根据您的 docker ps 列表,您的 9092 容器端口被动态映射到主机的端口范围 32882-32884。 当您连接到以这种方式配置的代理时,您会收到包含用于广告的端口 9092 的元数据。使用此元数据生产者尝试通过端口 9092 执行其他请求并失败。

【讨论】:

【参考方案4】:

为了记录,让我的本地 kafka 消费者与 Docker 容器内的远程代理通信的另一种方法是在我的 /etc/hosts 中添加一个条目:docker-host-ip -address docker-kafka-container-hostname

无论如何,Lundahl 的解决方案对我来说效果很好,而且看起来更干净。更简洁的方法是设置 advertised.listeners=host-ip:portadvertised.host.nameadvertised.port 已弃用。

【讨论】:

【参考方案5】:

这是我的两分钱,因为我很难弄清楚这一点。

我的 $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 并输入一条消息

我希望这对其他人有所帮助

【讨论】:

以上是关于从docker主机外部与kafka docker容器交互[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Kafka Docker - 无法从 docker 容器外部生产或消费

从 docker 主机外部远程连接到在 docker 容器上运行的 oracle 数据库

Docker搭建Kafka测试集群

避免Kafka客户端无法连接Docker上运行的Kafka,又名:Docker如何添加hosts映射

Docker:Docker实现同Ip网段联通

尝试从 docker 容器访问共享内存时出现“权限被拒绝”,即使 --ipc 设置为“主机”