

wsl 中 docker-compose 搭建 kafka 集群出现的外部访问错误 - Assassin007
source link: https://www.cnblogs.com/Hui4401/p/17255319.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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
__EOF__
Recommend
-
13
为了部署有状态服务,需要给k8s提供一套可持久化存储的方案,我们使用ceph来做底层存储。一般k8s对接ceph有两种:- 通过rook部署和对接ceph,使用k8s提供ceph服务。rook官方文档非常详细,里面也有常见问题的fix版本,本人一路用下来非常顺利,这里不再赘述。文档...
-
8
漏洞概述 漏洞CVE-2020-8554是一个能够影响多用户Kubernetes群集的漏洞,如果潜在的攻击者可以创建或编辑服务和Pod,那么他们就可以拦...
-
13
Prometheus 监控外部 Kubernetes 集群 发表于 June 29, 2020 ...
-
13
kube-prometheus监控集群外部主机 发表于 2021-05-27...
-
8
由于开发有部份服务使用 GRPC 进行通讯,同时采用 Consul 进行服务发现;在微服务架构下可能会导致一些访问问题,目前解决方案就是打通开发环境网络与测试环境 Kubernetes 内部 Pod 网络;翻了好多资料发现都是 2.x 的,而目前测试集群 Calico 版本...
-
5
基于 Quorum 集群搭建讲解如何从 docker-compose 迁移到 Kubernetes0 条评论我们经常会遇到搭建多节点集群得需求, 例如摩根推出...
-
6
k8s集群service外部流量策略如何优雅的处理Pod终止过程中的流量丢失问题? 面试官:"k8s集群service外部流量策略如何优雅的处理Pod终止过程中的流量丢失问题?" ...
-
6
kafka镜像 zookeeper镜像 创建docker网络# 命...
-
8
Kafka 是一个开源的分布式事件流平台,依赖Zookeeper或者KRaft,本文基于Zookeeper。 服务器IP配置 本文使用三个服务器来做集群搭建,IP如下: nodeName IP ...
-
8
基于Docker-compose搭建Redis高可用集群-哨兵模式(Redis-Sentinel)首页 - Mac & Linux/2019-09-04
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK