kafka 内外网分流(frp,云服务器)

目的

在本地电脑虚拟机上装了三个kafka容器,然后通过frp映射,别的电脑可以通过访问云服务器端口来访问虚拟机,从而连接kafka

基础信息

云服务器公网IP:119.XXX.XXX.113

虚拟机hostname:ubuntu

三台容器的hostname:k01,k02,k03

云服务器涉及到的端口最好都开放入规则和出规则(没有试验是否有些可以不开放)

9092 19092 9093 19093 9094 19094

云服务器端口与虚拟机端口通过frp的映射关系

9092->9092,9093->9093,9094->9094 19092->19092,19093->19093,19094->19094

这样其他电脑访问云服务器特定端口就相当于访问虚拟机特定端口

docker容器与虚拟机的端口映射:

9092->k01:9092,19092->k01:19092

9093->k02:9092,19093->k02:19093

9094->k03:9092,19094->k03:19094

前提

最起码在这之前要在虚拟机里能跑通消费者和生产者程序,,,,

比如在虚拟机上同时启动

sudo docker exec -it k01 bin/kafka-console-producer.sh --bootstrap-server k01:9092 --topic test


sudo dockerr exec -it k01 bin/kafka-console-consumer.sh --bootstrap-server k01:9092 --topic test

然后生产者发消息看消费者能不能接受到

listener

要实现内外网分流实际上就是看三个kafka容器的config/server.properties里怎么配置不同的listener相关的配置

listener用来规定此kafka容器要监听哪个网卡的哪个端口,.0.0.0.0:9092默认监听所有网卡的9092端口(当然还有其他的知识,比如listener如果要设置0.0.0.0,则advertised.listener必须要写,但是这些知识与我要做的操作无关,如果需要了解,请访问别的帖子,比如Kafka配置内外网分流以及常见通信配置详解 - 知乎)

advertised.listeners:这个kafka容器要对外发布的监听器地址,因为kafka本身不知道兄弟节点地址,比如java程序里参数写:prop.setProperty("bootstrap.servers", "k01:9092"),那程序会连接k01,但是k01不知道k02和k03的ip和对应的开放端口,这时候需要知道k02和k03的ip:端口(因为数据在三个容器里,如果消费者要消费,必然是需要知道所有broker的地址的),此时k01会去zookeeper里寻找三个容器的地址(每个上线的kafka都会在/brokers/ids/序列号下注册临时节点,get /brokers/ids/数字可以得到信息),然后得到的每个容器的ip:port其实是每个容器config/server.properties里配置的advertised.listeners参数里的ip:port,即本参数,然后根据得到的每个容器的地址去连接每个容器

还有两个参数,在下面用到的时候会提

分析

只有内网

先分析一个容器k02且只在内网即虚拟机上进行生产消费的完善配置,

此时k02容器需要监听的端口只有9092,所以listener可写(不填ip也相当于监控所有网卡)

listeners=INTERNAL://:9092

即知道最终访问k02的9092端口就可以连接kafka(注意,这里不是填ubuntu映射的端口9093,因为ubuntu端口其实也只是一系列映射端口中的一个,不是最终的容器端口)

INTERNAL为INTERNAL://:9092这个监听器的名称,下面有用

然后我们在虚拟机上连接k02的broker的途径就是,连接ubuntu:9093,然后ubuntu:9093和k02:9092是映射关系,所以最终访问k02的9092端口,然后配置的listener就可以监控到数据了或者sudo docker exec -it k01 bin/kafka-console-producer.sh --bootstrap-server k02:9092 --topic test直接在容器里执行了

如果是sudo docker ....这种方式,那从zookeeper里取过来的发布的地址要为k02:9092,然后程序连接k02:9092从而成功访问kafka,如果是第一种方式,那zookeeper里发布的地址要为ubuntu:9093,从而程序接下来连接ubuntu:9093从而访问k02:9092,成功连接kafka

sudo docker...方式(第一种方式类似,没有写的必要,因为最终配置没用到)的advertised.listeners配置(监听器名字和listeners里的要相同,不相同有什么问题那就没有实验过了,直觉来说肯定有问题)

advertised.listeners=INTERNAL://k02:9092

如果是默认监听器不需要声明,非默认的(比如上面写的INTERNAL)需要声明

listener.security.protocol.map=INTERNAL:PLAINTEXT

PLAINTEXT是一种加密方式,想了解见上面引用的那个帖子

此时k02配置添加

listeners=INTERNAL://:9092
advertised.listeners=INTERNAL://k02:9092
listener.security.protocol.map=INTERNAL:PLAINTEXT

 k01,k03类似配置

# k01
listeners=INTERNAL://:9092
advertised.listeners=INTERNAL://k01:9092
listener.security.protocol.map=INTERNAL:PLAINTEXT
# k03
listeners=INTERNAL://:9092
advertised.listeners=INTERNAL://k03:9092
listener.security.protocol.map=INTERNAL:PLAINTEXT

外网

我们先分析一个外网访问kafka容器k01的途径

任意电脑先链接云服务器公开端口119.XXX.XXX.113:19092,然后通过frp映射到ubuntu:19092,然后ubuntu:19092通过docker映射到容器k01的k01:19092,

即访问119.XXX.XXX.113:19092最终访问k01:19092,那对容器k01来说,要做的事只是监控19092端口(因为最后要有两个监听器,所以要起不同的名字,而且别的帖子说不同监听器监听的端口要不同,这个没试验过)

listeners=EXTERNAL://:19092

外网能且只能通过119.XXX.XXX.113:19092访问k01:19092,那k01发布的地址就要是外网能访问的

advertised.listeners=EXTERNAL://119.XXX.XXX.113:19092

同时自定义监听器需声明

listener.security.protocol.map=EXTERNAL:PLAINTEXT

k01配置

listener.security.protocol.map=EXTERNAL:PLAINTEXT
listeners=EXTERNAL://:19092
advertised.listeners=EXTERNAL://119.XXX.XXX.113:19092

k02,k03配置分别为

listener.security.protocol.map=EXTERNAL:PLAINTEXT
listeners=EXTERNAL://:19093
advertised.listeners=EXTERNAL://119.XXX.XXX.113:19093
listener.security.protocol.map=EXTERNAL:PLAINTEXT
listeners=EXTERNAL://:19094
advertised.listeners=EXTERNAL://119.XXX.XXX.113:19094

其实如果把这两种监听器合并即可得到最终配置,不过两个监听器,broker之间相同通信用哪个呢,肯定是要用内网那个,因为可能其他情形下内网不能连接外网,所以有个参数可配置broker使用的监听器

inter.broker.listener.name=INTERNAL

最终配置

# k01/server.properties下
listener.security.protocol.map=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
listeners=INTERNAL://:9092,EXTERNAL://:19092
advertised.listeners=EXTERNAL://119.XXX.XXX.113:19092,INTERNAL://k01:9092
inter.broker.listener.name=INTERNAL

# k02/server.properties下
listener.security.protocol.map=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
listeners=INTERNAL://:9092,EXTERNAL://:19093
advertised.listeners=EXTERNAL://119.XXX.XXX.113:19093,INTERNAL://k02:9092
inter.broker.listener.name=INTERNAL

# k03/server.properties下
listener.security.protocol.map=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
listeners=INTERNAL://:9092,EXTERNAL://:19094
advertised.listeners=EXTERNAL://119.XXX.XXX.113:19094,INTERNAL://k03:9092
inter.broker.listener.name=INTERNAL

此时有个疑问,zookeeper里暴露的每个容器都有两个地址,它怎么知道选哪个呢,我猜是根据你请求的端口来提供对应的地址

配置kafka重启之后,最好看下zookeeper的/brokers/ids/0 /brokers/ids/1 /brokers/ids/2里的值里的地址是不是你配置的

此时就有两种连接kafka的途径了,第一种在容器里用k01:9092或k02:9092或k03:9092(不要搞些花里胡哨的,比如localhost:9092或者k01的ip,192.168.0.11:9092这种,严格按照advertised.listeners写的东西来)连接,比如

sudo docker exec -it k01 bin/kafka-console-producer.sh --bootstrap-server k01:9092 --topic test

第二种外网访问(frp中转这种情况与在阿里云里搭建docker容器,docker里搭建kafka容器没有区别,无论中间经过多少端口映射,只要listeners里监控的有最终访问的kafka容器端口,advertised.listeners有你能访问的ip地址,比如云服务器公网ip,都可以成功,中间映射的若干端口没有用)

比如用java走云服务器公网ip连接(还是那句话,别花里胡哨的写)

properties.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "119.X.XXX.113:19092");

至此,配置就结束了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值