【运维笔记】kafka跨域通信代理

2023-11-14

在项目部署过程中遇到kafka需要走代理跨域通信的情景,搭建了一套环境模拟实验,以此记录。

场景描述

两套kafka集群KafkaS和KafkaC分别位于两个不互通的网络域,跨域互访需要经过nginx代理机,现需要确认nginx、kafka的配置。

模拟思路

利用docker在一台虚拟机上创建两个网络不互通的kafka集群,同时在宿主机上部署nginx。

模拟环境说明

基础环境

1、宿主机:Ubuntu 22.10
2、工具:docker、docker-compose

kafka版本

1、kafka镜像/zookeeper镜像:wurstmeister/zookeeper、wurstmeister/kafka
2、实验时版本:zookeeper

环境部署

基础软件安装

安装docker、docker-compose、nginx

sudo apt install docker.io docker-compose nginx -y

编写kafka的docker-compose.yml文件

1、网络配置

networks:
  kafka_server_net:
    ipam:
      config:
        - subnet: 172.33.0.0/16
  kafka_client_net:
    ipam:
      config:
        - subnet: 172.34.0.0/16

2、zookeeper配置

  zookeeperS:
    image: wurstmeister/zookeeper
    container_name: zookeeperS
    restart: always
    networks:
      kafka_server_net:
        ipv4_address: 172.33.0.10

zookeeperC的配置类似。

3、kafka配置

  kafkaS1:
    image: wurstmeister/kafka
    depends_on: [ zookeeperS ]
    container_name: kafkaS1
    environment:
      HOSTNAME: kafkaS1
      KAFKA_BROKER_ID: 0
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafkaS1:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeperS:2181/kafka
    # extra_hosts可以把地址映射添加到hosts文件里,后面有用。其中,统一集群的kafka映射为容器的IP地址,不同集群的kafka映射为宿主机地址,72.130是宿主机IP。
    extra_hosts:
      kafkaS1: 172.33.0.11
      kafkaS2: 172.33.0.12
      kafkaS3: 172.33.0.13
      kafkaC1: 192.168.72.128
      kafkaC2: 192.168.72.128
      kafkaC3: 192.168.72.128
    networks:
      kafka_server_net:
        ipv4_address: 172.33.0.11
        

kafkaC的配置类似

4、完整的docker-compose文件

version: '3.8'

services:
# kafkaS && zookeeperS
  zookeeperS:
    image: wurstmeister/zookeeper
    container_name: zookeeperS
    restart: always
    networks:
      kafka_server_net:
        ipv4_address: 172.33.0.10

  kafkaS1:
    image: wurstmeister/kafka
    depends_on: [ zookeeperS ]
    container_name: kafkaS1
    environment:
      HOSTNAME: kafkaS1
      KAFKA_BROKER_ID: 10
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafkaS1:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeperS:2181/kafka
    networks:
      kafka_server_net:
        ipv4_address: 172.33.0.11
    extra_hosts:
      kafkaS1: 172.33.0.11
      kafkaS2: 172.33.0.12
      kafkaS3: 172.33.0.13
      kafkaC1: 192.168.72.128
      kafkaC2: 192.168.72.128
      kafkaC3: 192.168.72.128

  kafkaS2:
    image: wurstmeister/kafka
    depends_on: [ zookeeperS ]
    container_name: kafkaS2
    environment:
      HOSTNAME: kafkaS2
      KAFKA_BROKER_ID: 11
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafkaS2:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeperS:2181/kafka
    networks:
      kafka_server_net:
        ipv4_address: 172.33.0.12
    extra_hosts:
      kafkaS1: 172.33.0.11
      kafkaS2: 172.33.0.12
      kafkaS3: 172.33.0.13
      kafkaC1: 192.168.72.128
      kafkaC2: 192.168.72.128
      kafkaC3: 192.168.72.128

  kafkaS3:
    image: wurstmeister/kafka
    depends_on: [ zookeeperS ]
    container_name: kafkaS3
    environment:
      HOSTNAME: kafkaS3
      KAFKA_BROKER_ID: 12
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafkaS3:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeperS:2181/kafka
    networks:
      kafka_server_net:
        ipv4_address: 172.33.0.13
    extra_hosts:
      kafkaS1: 172.33.0.11
      kafkaS2: 172.33.0.12
      kafkaS3: 172.33.0.13
      kafkaC1: 192.168.72.128
      kafkaC2: 192.168.72.128
      kafkaC3: 192.168.72.128

# kafkaC && zookeeperC

  zookeeperC:
    image: wurstmeister/zookeeper
    container_name: zookeeperC
    restart: always
    networks:
      kafka_client_net:
        ipv4_address: 172.34.0.10

  kafkaC1:
    image: wurstmeister/kafka
    depends_on: [ zookeeperC ]
    container_name: kafkaC1
    environment:
      HOSTNAME: kafkaC1
      KAFKA_BROKER_ID: 20
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafkaC1:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeperC:2181/kafka
    networks:
      kafka_client_net:
        ipv4_address: 172.34.0.11
    extra_hosts:
      kafkaS1: 192.168.72.128
      kafkaS2: 192.168.72.128
      kafkaS3: 192.168.72.128
      kafkaC1: 172.34.0.11
      kafkaC2: 172.34.0.12
      kafkaC3: 172.34.0.13

  kafkaC2:
    image: wurstmeister/kafka
    depends_on: [ zookeeperC ]
    container_name: kafkaC2
    environment:
      HOSTNAME: kafkaC2
      KAFKA_BROKER_ID: 21
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafkaC2:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeperC:2181/kafka
    networks:
      kafka_client_net:
        ipv4_address: 172.34.0.12
    extra_hosts:
      kafkaS1: 192.168.72.128
      kafkaS2: 192.168.72.128
      kafkaS3: 192.168.72.128
      kafkaC1: 172.34.0.11
      kafkaC2: 172.34.0.12
      kafkaC3: 172.34.0.13

  kafkaC3:
    image: wurstmeister/kafka
    depends_on: [ zookeeperC ]
    container_name: kafkaC3
    environment:
      HOSTNAME: kafkaC3
      KAFKA_BROKER_ID: 22
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafkaC3:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeperC:2181/kafka
    networks:
      kafka_client_net:
        ipv4_address: 172.34.0.13
    extra_hosts:
      kafkaS1: 192.168.72.128
      kafkaS2: 192.168.72.128
      kafkaS3: 192.168.72.128
      kafkaC1: 172.34.0.11
      kafkaC2: 172.34.0.12
      kafkaC3: 172.34.0.13

# networks
networks:
  kafka_server_net:
    ipam:
      config:
        - subnet: 172.33.0.0/16
  kafka_client_net:
    ipam:
      config:
        - subnet: 172.34.0.0/16

环境验证

docker-compose up -d启动所有容器后,开始验证环境是否符合要求。
1、网络连通性验证
本场景应当kafkaS和kafkaC集群间不能互访,内部三个节点可以互访;宿主机和两个集群可以互访。
1-1、kafka集群内部互访
先进入容器内:

docker -exec -it kafkaS1 bash

kafka容器没有telnet、ping等工具测试网络,但我们可以用nc:

nc -vz kafkaS2 9092
nc -vz zookeeperS 2181

测试结果1

以上测试应该会回显succeed

1-2、kafka集群间验证

nc -vz kafkaC1 9092

测试结果2

测试结果是refused,是否与我们预期不一样?别慌,这是因为kafkaC1被映射为宿主机的地址,因此是正常的,要测试kafka集群间连通性,应该直接用ip测试,这次结果就是超时了。

nc -vz 172.34.0.11 9092

测试结果3

1-3、代理(宿主机)与kafka的连通性验证
上一部分已经验证过,也可以在宿主机上Telnet端口,正常情况是通的。

2、kafka可用性验证
2-1、分别在两个kafka集群测试统一集群内kafka能否成功收发消息。

# 进入kafka测试脚本所在目录
cd /opt/kafka/bin/
# 创建主题
kafka-topics.sh --create --zookeeper zookeeperS:2181/kafka --replication-factor 1 --partitions 2 --topic testtopic
# 模拟生产消息
kafka-console-producer.sh --topic=testtopic --broker-list kafkaS1:9092,kafkaS2:9092,kafkaS3:9092
# 随便输入内容进行测试
# 进入另一个kafka容器,模拟消费
kafka-console-consumer.sh --bootstrap-server kafka01:9092,kafka02:9092,kafka03:9092 --from-beginning --topic testtopic

消费的窗口能看到生产的消息,则验证通过。测试结果4
至此,模拟环境搭建完成,下面记录如何实现跨域通信。

解决方案

Kafka通信机制

kafka通过二次交互建立会话:服务端在第一次交互时会返回一个地址供客户端建立会话,这个交互机制可以防止中间人攻击,但对走代理的场景来说,配置就比较麻烦了。
一个kafka服务端会提供给多个客户端访问(含不经代理的访问),配置为返回代理地址不太合适,

解决思路

kafka返回相同值给客户端,客户端却需要识别成各不相同、自己能连接的地址,这个问题很自然地就能想到用hosts解决。
docker-compose配置里已经给kafka节点都加上了extra_hosts,并根据连通性做好主机名和IP的映射。

代理配置

映射加上之后,只需要再把nginx代理配好就能成功互访了。
这里我用四层代理进行转发。
在nginx.conf文件里新建stream块,和http同级。
在这里插入图片描述
在nginx配置目录下新建kafkaproxy.conf,具体如下:

# 新建配置文件
sudo nano /etc/nginx/conf.d/stream/kafkaproxy.conf

配置内容:

upstream KAFKA_SERVER
{
server 172.33.0.11:9092;
server 172.33.0.12:9092;
server 172.33.0.13:9092;
}
server {
listen *:9092;
proxy_pass KAFKA_SERVER;
proxy_connect_timeout 2s;
proxy_timeout 1m;
}

# 配置完毕后重载配置
sudo nginx -s reload

验证是否满足要求

1、模拟发送消息
进入kafkaS任意节点,模拟发送消息

kafka-console-producer.sh --topic=testtopic --broker-list kafkaS1:9092,kafkaS2:9092,kafkaS3:9092

2、模拟接收消息

kafka-console-consumer.sh --bootstrap-server kafkaS1:9092,kafkaS2:9092,kafkaS3:9092 --from-beginning --topic testtopic

能相互通信
测试结果5
因为–from-beginning参数没去掉,所以有一些之前产生的消息。
但此时仍然是有问题的,通过代理访问kafka服务端的时候,有时会消费不到数据。这是负载均衡的问题,如果要避免,还是得配置多监听。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【运维笔记】kafka跨域通信代理 的相关文章

随机推荐

  • 从道法术三个层面理解区块链:术

    区块链对当下的大家来说 都还是盲人摸象的阶段 所以经常群里有各种争论 归结起来 都是有的摸到了大腿 有的摸到了耳朵 相互之间就难以说服对方 各自有各自的认知 笔者尝试从道法术这三个层面来解读下区块链 以便让大家有个更全面的了解 也知道自己的
  • Linux设备驱动-procfs

    在Linux中 procfs是进程文件系统 file system 的缩写 包含一个伪文件系统 启动时动态生成的文件系统 可用于内核层和用户层交互信息 这个文件系统通常被挂载到 proc 目录 由于 proc 不是一个真正的文件系统 它也就
  • 排序算法-----插入排序

    目录 前言 插入排序 原理图 代码实现 分析总结 二分法插入排序 代码实现 前言 嗨嗨 米娜桑 今天我们继续学习排序算法中的插入排序 激不激动 兴不兴奋呢 好了废话不多说 下面请看正文 插入排序 插入排序 一般也被称为直接插入排序 对于少量
  • SSHException: Incompatible ssh peer (no acceptable kex algorithm)

    使用公司维护助手 python开发 执行巡检 导入主机信息时 发现无法连接 报错信息如下 2015 12 22 15 41 12 983 15004 ERROR paramiko transport Exception Incompatib
  • vscode 在标签的src引入别名路径_Typescript项目别名(alias)配置清单

    综述 新手写Typescript项目 别名配置是经常出问题的环节 有的人遇到这种问题 如果一时半会儿解决不了 干脆就不用别名了 这显然是不合理的 本文给出一个Typescript项目各种环节的别名配置清单 如果遇到问题 可以对照着检查一下
  • hudi 编译

    编译hudi 下载hudi git clone https github com apache incubator hudi git cd incubator hudi 编译 mvn clean install DskipTests Dsk
  • python-认识(第二段)

    1 条件表达式 关系运算符特点 可以连用 例 a b 10 50 对于 0
  • games103 物理模拟第三节笔记补充

    矩阵求逆直接法 1 LU分解 2 LDLT分解法 3 Cholesky分解 4 QR分解 5 SVD分解 6 Jordan分解 关于LU分解 LU分解的矩阵稀疏性与矩阵A的排列顺序有关 在这个领域 matlab提供了一套较好的解决方案 LU
  • docker学习1-基本概念

    Docker jar包 环境 镜像 镜像存在docker仓库中 随用随取 无需现配环境 docker通过隔离机制 各个镜像之间互不干扰 docker比vm轻量化 每次只需运行镜像即可 镜像占内存小启动快 虚拟机启动慢 占内存较大 docke
  • oracle一个事务的完整流程分析

    author skate time 2010 09 01 在oracle客户端与服务端建立连接的 并把请求提交给oracle服务端以前分析过 参考如下 http blog csdn net wyzxg archive 2010 08 16
  • 夜莺监控V6初探

    目标 客户用产品可能是功能设计好 也可能是因为响应快稳定可靠 例如滴滴用不了用高德 券商app故障受罚 微信凌晨服务崩溃 所以稳定性建设工作价值是保障客户体验 避免资损 社会负面舆论 故障生命周期处理 围绕故障生命周期 在整个故障定位体系
  • 文件上传漏洞靶场upload-labs学习(pass11-pass15)

    Upload Labs关卡 0x00 Pass11 str ireplace复写绕过 0x01 Pass12 GET方式 00截断 0x02 Pass13 POST方式 00截断 0x03 Pass14 文件头截取判断 0x04 Pass1
  • 游戏测试和软件测试有什么区别?

    针对手游而言 游戏测试的本质是APP 所以不少手游的测试方式与APP测试异曲同工 然而也有所不同 APP更多的是具有一种工具 一款APP好不好用不重要 关键点在于实用 而游戏则具有一种玩具属性 它并不见得实用 但他要符合玩家的好恶 要能让玩
  • 华为OD机试 - 寻找相似单词(Java)

    题目描述 给定一个可存储若干单词的字典 找出指定单词的所有相似单词 并且按照单词名称从小到大排序输出 单词仅包括字母 但可能大小写并存 大写不一定只出现在首字母 相似单词说明 给定一个单词X 如果通过任意交换单词中字母的位置得到不同的单词Y
  • python3 pickle.load 读python2 文件报错, UnicodeDecodeError 和 TypeError

    pickle持久化文件用 python2 7 pickle dump产生 程序升级后用python3 6 读文件报错 UnicodeDecodeError ascii codec can t decode byte 0xc3 in posi
  • 【SVN】svn服务器访问失败【由于连接方在一段时间后没有反应】

    可以很清楚的告诉你 是由于服务器的端口未打开或者你的服务根本没有运行 环境 1 服务器windows2012 2 本机电脑win7 3 svn本地的版本和服务器的版本一致 分为以下两种情况 1 在服务器上可以进行svn的操作 2 在服务器上
  • HTTP Status 500 - Request processing failed; nested exception is java.lang.NullPointerException

    做青橙电商项目的时候 发布项目后登录发现直接报空指针异常 仔细检查代码后发现是dubbo远程框架中service远程调用失败 问题是导包倒错了 报错如下 HTTP Status 500 Request processing failed n
  • 博客第一天>>>>梦开始了

    简单的自我介绍一下哈 新码农上任三把活 gt 自我介绍 大哥大佬牛逼的人们好 我来自广西一所三本大学 当一个想要月入过万的小小码农 梦先慢慢积累 语言目标 从c开始学起 第一个月要把c语言的大概 流程做一遍 先学到会看懂一些C语言代码 其间
  • 串联型PI和并联型PI调节器的比较

    一 PI调节器的种类 图3 4 仿真波形变化情况 串联型PI调节器 1500r min 从图3 1到3 4比较可知 与并联型PI调节器相比 串联型PI调节器的超调量很小 速度环 且动态过程时间短 稳态过程的纹波也相对较小 综合可知 代入串联
  • 【运维笔记】kafka跨域通信代理

    kafka跨域通信代理 场景描述 模拟思路 模拟环境说明 基础环境 kafka版本 环境部署 基础软件安装 编写kafka的docker compose yml文件 环境验证 解决方案 Kafka通信机制 解决思路 代理配置 验证是否满足要