wsl 中 docker-compose 搭建 kafka 集群出现的外部访问错误
在 wsl 中用 docker-compose 搭建了一台 zookeeper + 三台 broker 的 kafka 集群,使用的镜像是 bitnami/kafka,在按照镜像文档运行容器后,发现运行在宿主机里的客户端程序无法正确的推送/消费消息,研究后发现镜像文档只适用于客户端程序和 kafka 集群同属于一个 docker 网段,外部访问还需要一些额外的配置,过程中出现过以下几个主要的错误:
- dial tcp: lookup 333be5d4e335 on 172.30.96.1:53: no such host
- kafka: client has run out of available brokers to talk to: dial tcp 127.0.0.1:19092: connect: connection refused
- [Controller id=1, targetBrokerId=3] Client requested connection close from node 3 (org.apache.kafka.clients.NetworkClient)
这里先贴一个可以用的 docker-compose.yml 配置,后面对其中的关键配置做一个解释,最后再解释出现上面错误的原因,文件最后的 kafka-ui 是一个可视化管理界面,可以不要
version: "3"
services:
zookeeper:
container_name: kafka_zookeeper
image: bitnami/zookeeper
user: root
ports:
- "2181:2181"
environment:
- ALLOW_ANONYMOUS_LOGIN=yes
volumes:
- ./zookeeper:/bitnami/zookeeper
broker1:
container_name: kafka_broker1
image: bitnami/kafka
user: root
ports:
- "19092:9092"
environment:
- KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_BROKER_ID=1
- KAFKA_LISTENERS=INTERNAL://0.0.0.0:9000,EXTERNAL://0.0.0.0:9092
- KAFKA_ADVERTISED_LISTENERS=INTERNAL://broker1:9000,EXTERNAL://localhost:19092
- KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
- KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL
volumes:
- ./broker1:/bitnami/kafka
depends_on:
- zookeeper
broker2:
container_name: kafka_broker2
image: bitnami/kafka
user: root
ports:
- "29092:9092"
environment:
- KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_BROKER_ID=2
- KAFKA_LISTENERS=INTERNAL://0.0.0.0:9000,EXTERNAL://0.0.0.0:9092
- KAFKA_ADVERTISED_LISTENERS=INTERNAL://broker2:9000,EXTERNAL://localhost:29092
- KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
- KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL
volumes:
- ./broker2:/bitnami/kafka
depends_on:
- broker1
broker3:
container_name: kafka_broker3
image: bitnami/kafka
user: root
ports:
- "39092:9092"
environment:
- KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_BROKER_ID=3
- KAFKA_LISTENERS=INTERNAL://0.0.0.0:9000,EXTERNAL://0.0.0.0:9092
- KAFKA_ADVERTISED_LISTENERS=INTERNAL://broker3:9000,EXTERNAL://localhost:39092
- KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
- KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL
volumes:
- ./broker3:/bitnami/kafka
depends_on:
- broker2
kafka-ui:
container_name: kafka-ui
image: provectuslabs/kafka-ui
ports:
- "8080:8080"
restart: always
environment:
- KAFKA_CLUSTERS_0_NAME=broker1
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=broker1:9000
- KAFKA_CLUSTERS_1_NAME=broker2
- KAFKA_CLUSTERS_1_BOOTSTRAPSERVERS=broker2:9000
- KAFKA_CLUSTERS_2_NAME=broker3
- KAFKA_CLUSTERS_2_BOOTSTRAPSERVERS=broker3:9000
depends_on:
- broker3
其中几个容易搞错的关键配置如下:
ports:
- "19092:9092"
environment:
- KAFKA_LISTENERS=INTERNAL://0.0.0.0:9000,EXTERNAL://0.0.0.0:9092
- KAFKA_ADVERTISED_LISTENERS=INTERNAL://broker1:9000,EXTERNAL://localhost:19092
参数 KAFKA_LISTENERS 和 KAFKA_ADVERTISED_LISTENERS 的作用:
- KAFKA_LISTENERS 代表 broker 的监听地址,kafka客户端首先需要与这个地址建立连接,完成必要的认证工作
- KAFKA_ADVERTISED_LISTENERS 代表 broker 的数据传输地址,这里配置的地址会注册到 zookeeper 中,在客户端完成身份认证后会从 zk 原封不动地获得这里配置的 ip+port 用于消息推送/消费
在上面的配置中,KAFKA_ADVERTISED_LISTENERS 的 EXTERNAL 配置了 localhost:19092,这是因为我的客户端程序运行在 wsl 中,而 19092 端口已经映射到了容器的 9092 端口上所以可以正确访问,如果 kafka 集群和客户端程序运行在两个不同的服务器上,这里应该配置 kfaka 集群所在的主机 ip,只需要记住这一串地址的 ip+port 部分是原封不动的传给客户端的,想想客户端程序所在的机器能不能解析它吧
另外,关于 KAFKA_LISTENERS 中 port 的配置与上面 ports 属性中的端口映射的关系是:先有端口监听后有端口映射,这个地方没理解清楚的话就很容易对这两个配置项感到迷惑,例如上面配置了 9000 和 9092 两个监听端口,然后将 9092 映射到了宿主机的 19092,9000 作为未公开的端口只有同属一个 docker 网络的机器才能访问
一开始出现的几个主要错误也都是由这几个配置引起:
- dial tcp: lookup 333be5d4e335 on 172.30.96.1:53: no such host
未配置 KAFKA_LISTENERS 的情况下默认是该 broker 容器的主机名+9092,未配置 KAFKA_ADVERTISED_LISTENERS 的情况下该值等于 KAFKA_LISTENERS,这种情况下宿主机的程序建立连接后拿到了一个未知的主机名 333be5d4e335 发送消息,当然行不通(宿主机无法将该主机名转换成 ip 访问)
- kafka: client has run out of available brokers to talk to: dial tcp 127.0.0.1:19092: connect: connection refused
端口配置没有理解清楚,KAFKA_LISTENERS 中对外的监听端口必须是被映射出去的 9092 本身,否则宿主机无法访问
- [Controller id=1, targetBrokerId=3] Client requested connection close from node 3 (org.apache.kafka.clients.NetworkClient)
端口配置没有理解清楚,brokers 之间的通信是内部通信,内部监听端口可以不公开映射出去,但是流程是一样的
另外在配置项变更后,最好删除容器,并删除各个目录里面的 data 目录里面的文件再重新创建容器,不确定是哪一个配置变更会出现以下错误:
- org.apache.zookeeper.KeeperException$NodeExistsException: KeeperErrorCode = NodeExists
wsl 中 docker-compose 搭建 kafka 集群出现的外部访问错误的更多相关文章
- 用 Docker 快速搭建 Kafka 集群
开源Linux 一个执着于技术的公众号 版本 •JDK 14•Zookeeper•Kafka 安装 Zookeeper 和 Kafka Kafka 依赖 Zookeeper,所以我们需要在安装 Kaf ...
- Docker实战之Kafka集群
1. 概述 Apache Kafka 是一个快速.可扩展的.高吞吐.可容错的分布式发布订阅消息系统.其具有高吞吐量.内置分区.支持数据副本和容错的特性,适合在大规模消息处理场景中使用. 笔者之前在物联 ...
- docker-compose 搭建kafka集群
docker-compose搭建kafka集群 下载镜像 1.wurstmeister/zookeeper 2.wurstmeister/kafka 3.sheepkiller/kafka-manag ...
- 大数据平台搭建-kafka集群的搭建
本系列文章主要阐述大数据计算平台相关框架的搭建,包括如下内容: 基础环境安装 zookeeper集群的搭建 kafka集群的搭建 hadoop/hbase集群的搭建 spark集群的搭建 flink集 ...
- centos7搭建kafka集群-第二篇
好了,本篇开始部署kafka集群 Zookeeper集群搭建 注:Kafka集群是把状态保存在Zookeeper中的,首先要搭建Zookeeper集群(也可以用kafka自带的ZK,但不推荐) 1.软 ...
- Kafka学习之(六)搭建kafka集群
想要搭建kafka集群,必须具备zookeeper集群,关于zookeeper集群的搭建,在Kafka学习之(五)搭建kafka集群之Zookeeper集群搭建博客有说明.需要具备两台以上装有zook ...
- 什么是kafka以及如何搭建kafka集群?
一.Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据. Kafka场景比喻 接下来我大概比喻下Kafka的使用场景 消息中间件:生产者和消费者 妈妈:生产 ...
- 利用新版本自带的Zookeeper搭建kafka集群
安装简要说明新版本的kafka自带有zookeeper,其实自带的zookeeper完全够用,本篇文章以记录使用自带zookeeper搭建kafka集群.1.关于kafka下载kafka下载页面:ht ...
- docker容器中搭建kafka集群环境
Kafka集群管理.状态保存是通过zookeeper实现,所以先要搭建zookeeper集群 zookeeper集群搭建 一.软件环境: zookeeper集群需要超过半数的的node存活才能对外服务 ...
- docker搭建kafka集群(高级版)
1. 环境docker, docker-compose 2.zookeeper集群 /data/zookeeper/zoo1/config/zoo.cfg # The number of millis ...
随机推荐
- iOS 为 textView 添加 placeholder
OC : //自定义一个 placeholder 样式的 label UILabel *placeholder = [UILabel new]; placeholder.text = @"请 ...
- 4组-Beta冲刺-1/5
一.基本情况 队名:摸鲨鱼小队 组长博客:https://www.cnblogs.com/smallgrape/p/15590583.html github链接:https://github.com/ ...
- [api自动化]快速导出接口到jmeter脚本
[场景]在项目做接口自动化的时候,大家一般找接口文档或者其他接口资料,逐一编写脚本.这样效率低,且容易由于文档未更新导致接口调试不通 [解决方案]页面上操作对应功能,直接捕获用到的接口,导出到jmet ...
- JS Math与一些原始类型
镇楼图 Pixiv:DSマイル 一.值属性.函数 globalThis JS有全局对象,但是在不同环境中全局对象均不同.在Web环境中,window.self.frames取得全局对象,在Web Wo ...
- 理解 Linux 文件权限
理解 Linux 文件权限 缺乏安全性的系统不是完整的系统.系统中必须有一套能够保护文件免遭非授权用户浏览或修改的机制.Linux 沿用了 Unix 文件权限的办法,即允许用户和组根据每个文件和目录的 ...
- web后端之连接mysql
1建立java enterprise项目 2在WEB-INF目录下建立lib目录把jdbc用的mysql-connector-java.jar包复制过来 3添加依赖 4编写class 或在 ...
- Java中多态相关知识点
多态 1.多态概述 同一个对象在不同时刻表现出的不同形态 多态的前提和体现: 有继承/实现关系 有方法重写 有父类引用指向子类对象(Animal a = new Cat();) 2.多态中的成员访问特 ...
- 十大经典排序之归并排序(C++实现)
归并排序 思路:(分而治之的思想) 1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列: 2.设定两个指针,最初位置分别为两个已经排序序列的起始位置: 3.比较两个指针所指向的元 ...
- 安装 TensorFlow 参考过的资料
anaconda 的新环境创建 https://blog.csdn.net/yandajiangjun/article/details/102615912
- css3样式pointer-events,点击穿透和海市蜃楼的效果
css样式pointer-events pointer-events 是CSS3的一个属性,支持的值非常多,其中大部分都是和SVG有关.目前只了解 none 这个值, 其他值后续要补上. pointe ...