Kafka Docker - 无法从 docker 容器外部生产或消费
Posted
技术标签:
【中文标题】Kafka Docker - 无法从 docker 容器外部生产或消费【英文标题】:Kafka Docker - Can't produce or consume from outside of docker container 【发布时间】:2017-01-26 08:12:33 【问题描述】:Kafka 在 docker 容器中运行良好。我可以使用docker exec -it [container name] [kafkascript]
并成功创建主题、生成/使用消息,但是当我使用本地 kafka 脚本从 docker 容器外部尝试时,我只能创建和列出主题。生产和消费消息会引发错误:
制作:
~/development/lib/kafka/kafka_2.11-0.10.0.0$ bin/kafka-console-producer.sh --broker-list $(docker-machine ip kafka):9092 --topic test
asdf
[2016-09-18 10:13:48,999] ERROR Error when sending message to topic test with key: null, value: 4 bytes with error: (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
org.apache.kafka.common.errors.TimeoutException: Batch containing 1 record(s) expired due to timeout while requesting metadata from brokers for test-0
消费:
~/development/lib/kafka/kafka_2.11-0.10.0.0$ bin/kafka-console-consumer.sh --zookeeper $(docker-machine ip kafka):2181 --topic test --from-beginning
[2016-09-18 09:57:10,389] WARN Fetching topic metadata with correlation id 0 for topics [Set(test)] from broker [BrokerEndPoint(0,ba762186182f,9092)] failed (kafka.client.ClientUtils$)
java.nio.channels.ClosedChannelException
at kafka.network.BlockingChannel.send(BlockingChannel.scala:110)
at kafka.producer.SyncProducer.liftedTree1$1(SyncProducer.scala:80)
at kafka.producer.SyncProducer.kafka$producer$SyncProducer$$doSend(SyncProducer.scala:79)
at kafka.producer.SyncProducer.send(SyncProducer.scala:124)
at kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:59)
at kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:94)
at kafka.consumer.ConsumerFetcherManager$LeaderFinderThread.doWork(ConsumerFetcherManager.scala:66)
at kafka.utils.ShutdownableThread.run(ShutdownableThread.scala:63)
[2016-09-18 09:57:10,392] WARN [console-consumer-34526_3c15c2c24040-1474210630122-9404562b-leader-finder-thread], Failed to find leader for Set([test,0]) (kafka.consumer.ConsumerFetcherManager$LeaderFinderThread)
kafka.common.KafkaException: fetching topic metadata for topics [Set(test)] from broker [ArrayBuffer(BrokerEndPoint(0,ba762186182f,9092))] failed
at kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:73)
at kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:94)
at kafka.consumer.ConsumerFetcherManager$LeaderFinderThread.doWork(ConsumerFetcherManager.scala:66)
at kafka.utils.ShutdownableThread.run(ShutdownableThread.scala:63)
Caused by: java.nio.channels.ClosedChannelException
at kafka.network.BlockingChannel.send(BlockingChannel.scala:110)
at kafka.producer.SyncProducer.liftedTree1$1(SyncProducer.scala:80)
at kafka.producer.SyncProducer.kafka$producer$SyncProducer$$doSend(SyncProducer.scala:79)
at kafka.producer.SyncProducer.send(SyncProducer.scala:124)
at kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:59)
... 3 more
我正在使用 spotify/docker-kafka ,但我将其升级到 0.10.0.0 并使用了来自 jshark 的一些建议,这些建议设置了 ads.listeners。我在 Mac 上运行。我创建了一个名为 kafka 的 docker 机器。这是我的 docker 运行:
docker run -p 2181:2181 -p 9092:9092 --env ADVERTISED_HOST=`docker-machine ip kafka` --env ADVERTISED_PORT=9092 kafka
这是我的 dockerfile:
# Kafka and Zookeeper
FROM java:openjdk-8-jre
ENV DEBIAN_FRONTEND noninteractive
ENV SCALA_VERSION 2.11
ENV KAFKA_VERSION 0.10.0.0
ENV KAFKA_HOME /opt/kafka_"$SCALA_VERSION"-"$KAFKA_VERSION"
# Install Kafka, Zookeeper and other needed things
RUN apt-get update && \
apt-get install -y zookeeper wget supervisor dnsutils && \
rm -rf /var/lib/apt/lists/* && \
apt-get clean && \
wget -q http://apache.mirrors.spacedump.net/kafka/"$KAFKA_VERSION"/kafka_"$SCALA_VERSION"-"$KAFKA_VERSION".tgz -O /tmp/kafka_"$SCALA_VERSION"-"$KAFKA_VERSION".tgz && \
tar xfz /tmp/kafka_"$SCALA_VERSION"-"$KAFKA_VERSION".tgz -C /opt && \
rm /tmp/kafka_"$SCALA_VERSION"-"$KAFKA_VERSION".tgz
ADD scripts/start-kafka.sh /usr/bin/start-kafka.sh
# Supervisor config
ADD supervisor/kafka.conf supervisor/zookeeper.conf /etc/supervisor/conf.d/
# 2181 is zookeeper, 9092 is kafka
EXPOSE 2181
EXPOSE 9092
CMD ["supervisord", "-n"]
scripts/start-kafka.sh
【问题讨论】:
【参考方案1】:这对我有用:https://***.com/a/37655203/1839580
我的总结:spotify/kafka
容器中的ADVERTISED_HOST
环境变量需要根据你的服务是在容器内部还是外部运行而改变。我使用 Docker for Mac,并且我的 docker 网络设置为桥接。在 Docker 之外,ADVERTISED_HOST
需要设置为 localhost,在 docker 内部,它被设置为 myproject_kafka_1
或者它最终在你的系统上。为了修复它,我在我的 MacOS 主机文件中添加并输入了将 127.0.0.1
映射到 myproject_kafka_1
的条目。我不喜欢弄乱我的主机文件,但它为我解决了这个问题。
127.0.0.1 localhost
127.0.0.1 myproject_kafka_1
【讨论】:
【参考方案2】:在将以下条目添加到 server.properties 之前,我无法从容器外部与 Kafka 交互:
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
我发布了更完整的答案here。希望其他人不会像我那样花太多时间在这上面。
【讨论】:
【参考方案3】:更简洁的方法是设置 advertised.listeners=host-ip:port
,因为 advertised.host.name
和 advertised.port
在 Kafka server.properties
文件中已弃用。
如果将host-ip
设置为0.0.0.0
,它将监听来自任何地方的请求。但它是不安全的。
【讨论】:
以上是关于Kafka Docker - 无法从 docker 容器外部生产或消费的主要内容,如果未能解决你的问题,请参考以下文章
无法从通过intellij运行的spring boot应用程序连接到我在docker上运行的kafka
在 dockerized 环境中无法从 Flask 连接到 Kafka
带有 Kafka 的 Docker 集群无法与客户端容器建立连接