Kafka访问docker内外

Posted

技术标签:

【中文标题】Kafka访问docker内外【英文标题】:Kafka access inside and outside docker 【发布时间】:2019-04-14 07:28:48 【问题描述】:

我正在尝试使用 docker-compose 启动一个 kafka 服务,它应该可以在 docker 内部和外部访问。因此,应该在内外设置合适的广告商:

version: '3'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"
  kafka:
    image: wurstmeister/kafka
    ports:
      - "9094:9092"
    environment:
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_LISTENERS: INSIDE://:9092,OUTSIDE://127.0.0.1:9094
      KAFKA_ADVERTISED_LISTENERS: INSIDE://:9092,OUTSIDE://127.0.0.1:9094
      KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE

问题是当我尝试从集群外部连接时,我得到的不是 127.0.0.1 作为节点的名称,而是内部主机名:

$ kafkacat -L -b 127.0.0.1:9094
Metadata for all topics (from broker -1: 127.0.0.1:9092/bootstrap):
 1 brokers:
  broker 1001 at 91588ea968d4:9092
 28 topics:
 ...

KAFKA_ADVERTISED_LISTENERS 和 KAFKA_LISTENERS 的目的不就是处理这种情况吗?我尝试设置 KAFKA_ADVERTISED_HOST_NAME 但它被忽略了(一份文档说它已被弃用,另一份说它仍然处于活动状态),但这似乎不是答案,因为我想要两个不同的广告主机名用于两个不同的网络。

我猜老问题仍然存在:如何让 kafka 在 docker-compose 内外工作?

【问题讨论】:

你能链接到你提到的两个不一致的文档吗?如果有歧义,最好修复它们。 它在hub.docker.com/r/wurstmeister/kafka“监听器配置”部分。这不是 kafka 文档,而是 wurstmeister docker 映像:“Kafka 的更高版本已弃用 Advertisementd.host.name 和 Advertisementd.port。注意:advertising.host.name 和 Advertisementd.port 仍然按预期工作,但在配置时不应使用听众。” 对了。 FWIW Confluent 这里有全套 Kafka 镜像:hub.docker.com/u/confluentinc 【参考方案1】:

我需要做的是将 LISTENERS 声明为绑定到所有接口,然后以不同的方式通告它们 - 一个到 docker 网络,一个到主机:

services:
  zookeeper:
    image: confluentinc/cp-zookeeper
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_SYNC_LIMIT: 2
  kafka:
    image: confluentinc/cp-kafka
    ports:
      - 9094:9094
    depends_on:
      - zookeeper
    environment:
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENERS: INTERNAL://0.0.0.0:9092,OUTSIDE://0.0.0.0:9094
      KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka:9092,OUTSIDE://localhost:9094
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL

【讨论】:

KAFKA_LISTENERS 中有一个冒号而不是一个点:INTERNAL://0.0 : 0.0:9092,OUTSIDE://0.0.0.0:9094 应该是:INTERNAL: //0.0.0.0.9092,OUTSIDE://0.0.0.0:9094【参考方案2】:

您的侦听器配置看起来正确,问题出在您的 Docker Compose:

ports:
  - "9094:9092"

您将9094(“外部”)映射回9092(“内部”),因此当您连接时,您将连接到“内部”侦听器。如果您删除这行配置,那么您的侦听器设置应该按预期工作。

欲了解更多信息,请参阅http://rmoff.net/2018/08/02/kafka-listeners-explained/

【讨论】:

我已经读了很多遍了那个帖子,但我仍然无法让它工作。如果我在“HOW TO”下使用 docker-compose sn-p,它会给出错误“缺少环境变量 KAFKA_LISTENERS。必须在使用 KAFKA_ADVERTISED_LISTENERS 时指定”。所以我添加了相应的 KAFKA_LISTENERS,它说“每个侦听器必须有一个不同的端口”。我将外部端口更改为9094,我无法连接到localhost:9094,而是连接到:9092,使用“经纪人地址”元数据“kafka9:9092”,因此发送消息失败。 @daniu 在 *** 上用你的 Docker Compose 文件和你使用它时遇到的错误开始一个新问题,我们可以从那里修复它。 当我发现它时,它几乎完成了。您的帖子缺少最相关的行,即 KAFKA_LISTENERS。你需要在此处将两者都设置为kafka主机(“INTERNAL://kafka:9092,OUTSIDE://kafka:9094”),然后可以不同地宣传它们(“INTERNAL://kafka:9092,OUTSIDE://本地主机:9094")。 @daniu 我很乐意添加它 - 它缺少哪个部分? “如何:在 Docker 上连接到 Kafka”? 是的,docker-compose sn-p,低于environment(顺便说一句,其值也没有正确缩进)。【参考方案3】:

同意@Robin Moffatt 的回答,即外部端口9094 映射到容器的9092

除了从 docker-compose.yml 中删除该配置之外,外部端口 9094 应该映射到容器的 9094

ports:
  - "9094:9094"

PS:我无法将此作为评论添加到以前的答案中,因此将其添加为新答案。

【讨论】:

以上是关于Kafka访问docker内外的主要内容,如果未能解决你的问题,请参考以下文章

Kafka 云服务器分别配置内外网访问

docker prometheus 无法访问 docker kafka_exporter

搭建基于 docker 的 Kafka 集群及 Spring Boot 应用访问

解决 spring boot 访问 docker kafka 失败

从本地 Docker For Mac 中部署的服务访问本地 Kafka(包括 Kubernetes 扩展)

kafka的Docker镜像使用说明(wurstmeister/kafka)