☰
Kafka 跨跳板机 SSH 隧道 socat 端口转发部署
2026/10/20 19:58:26 网站建设 项目流程

一、问题背景

使用 Kafka 客户端连接远端 Kafka 集群,程序启动后持续报错:Disconnected while requesting ApiVersion: might be caused by incorrect security.protocol,broker 返回主机名为kafka1:9092,程序反复断开重连,无法正常消费生产消息。

现象:网络端口能通,但是客户端拿到 broker 返回的主机名kafka1,本机无法解析该域名,导致连接失败。 根本原因:Kafka 的advertised.listeners返回的是主机名而非 IP,本地机器 DNS /hosts 无法解析kafka1,客户端拿到域名后无法建立真实 TCP 连接。

二、现场拓扑简述

业务自研 Kafka 程序部署在自有服务器,无法直连内网 Kafka 集群,链路经过跳板机做 SSH 隧道转发。

约束:

  1. 跳板机 9092 端口被其他业务占用,跳板机 SSH 隧道使用9093映射内网 Kafka 的 9092 端口。
  2. 自有服务器无法访问外网,socat 需要在外网电脑下载源码,编译打包后上传至现场服务器离线部署。

完整链路: 自有服务器(自研 Kafka 转发程序) → socat 监听127.0.0.1:9092→ 转发至跳板机x.x.x.x:9093→ 跳板机 SSH 隧道 → 内网 Kafka 集群 9092

三、两种解决思路

方案 1:hosts 域名解析 + socat 端口转发

适用场景:无法修改远端 Kafka 服务端server.properties配置,不能改动线上 Kafka 集群,只能在业务应用侧做适配。

1)配置 /etc/hosts 域名映射

把 Kafka 广播返回的主机名映射到本机回环地址,让客户端解析kafka1指向本机。

echo "127.0.0.1 kafka1" >> /etc/hosts
2)socat 端口转发代理

利用 socat 做 TCP 端口转发:本地监听 端口,将流量转发到远端真实 Kafka 地址x.x.x.x:9093。 命令释义:

  • TCP-LISTEN:9092,bind=127.0.0.1:仅在本机 127.0.0.1 监听 9092 端口
  • fork:支持多客户端并发连接
  • reuseaddr:端口可快速复用,避免服务重启端口占用报错
  • TCP:x.x.x.x:9093:后端真实 Kafka 服务地址
# 临时前台后台运行 /opt/socat/bin/socat TCP-LISTEN:9092,bind=127.0.0.1,fork,reuseaddr TCP:x.x.x.x:9093 &

socat 编译部署步骤

  1. 下载socat源码包,上传至业务服务器/opt目录
  2. 编译安装
cd /opt tar -zxvf socat-1.8.0.0.tar.gz cd socat-1.8.0.0 ./configure --prefix=/opt/socat make -j4 make install # 验证版本 /opt/socat/bin/socat -V
  1. 打包部署包,方便多台机器分发
tar -czzf socat-deploy.tar.gz socat/
  1. 目标机器解压
cd /opt tar -xzvf socat-deploy.tar.gz

设置 systemd 开机自启常驻服务

编写socat-forward.service单元文件,实现开机自动端口转发,进程异常自动重启。

[Unit] Description=Socat Kafka TCP Forward After=network.target [Service] ExecStart=/opt/socat/bin/socat TCP-LISTEN:9092,bind=127.0.0.1,fork,reuseaddr TCP:x.x.x.x:9093 Restart=always [Install] WantedBy=multi-user.target

生效命令:

systemctl daemon-reload systemctl enable socat-forward.service systemctl start socat-forward.service

配置完成后,启动业务 Kafka 程序,连接本地kafka1:9092即可正常工作。

方案 2:治本方案(修改 Kafka 服务端 server.properties)

如果有权限修改 Kafka 服务端,优先改服务端,不需要 socat 转发。 修改server.properties中advertised.listeners,写业务服务器可以直接访问的真实 IP 地址。

关键点:advertised.listeners是 broker 返回给客户端的连接地址,客户端会拿这个地址去连接 broker。填域名,客户端必须能解析域名;填 IP,客户端直接使用 IP 连接。

四、问题根因总结

  1. Kafka 客户端连接流程:客户端连接 bootstrap 地址,broker 返回advertised.listeners配置的地址列表,客户端丢弃 bootstrap 地址,使用返回的地址列表真正建立连接。
  2. 当advertised.listeners配置为主机名(kafka1),应用服务器无法解析该主机名,就会出现ApiVersion请求断开、报 brokers are down。
  3. socat 方案属于应用侧兼容妥协,适合不能修改 Kafka 集群配置的生产现场;修改advertised.listeners是最优根治方案。

五、socat 简单科普

socat 全称 SOcket CAT,就是一个 Linux 命令行工具,作用很简单:把两个数据流打通,双向转发数据。它常被叫做 netcat 的增强版。作用:

端口转发:把本机某个端口收到的数据,转发到另一个 IP 和端口。

协议桥接:比如 TCP ↔ UDP、TCP ↔ Unix Socket、TCP ↔ 串口。

网络调试:模拟服务端、客户端,看数据能不能通。

文件/管道/设备转发:不只是网络,还能转发文件、管道、串口设备。

SSL 隧道:给普通 TCP 连接加一层加密。

远程 Shell:也能用来建立正向或反向 Shell,但运维现场一般只用它做转发。

注意:socat 端口转发会增加一层网络开销,生产环境评估性能;bind=127.0.0.1 限制只能本机访问转发端口,提升安全性。

# 本地端口转发(同主机端口映射) socat TCP-LISTEN:端口,bind=127.0.0.1,fork,reuseaddr TCP:目标IP:目标端口 # 双向管道简易测试(本地回环测试) socat - TCP:127.0.0.1:28080

六、踩坑清单

  1. 不要把报错might be caused by incorrect security.protocol当成一定是 SSL/SASL 配置错误,很多时候只是域名解析失败。
  2. advertised.listeners 和 listeners 区分:
    • listeners:broker 本机监听哪个网卡端口;
    • advertised.listeners:返回给外部客户端的访问地址。
  3. hosts 配置后确认是否生效,ping kafka1验证解析结果。
  4. socat 一定要配置fork,否则只能处理单个客户端连接。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询