首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >nginx 反向代理 kafka, 顺便实践了下nginx ip白名单知识点

nginx 反向代理 kafka, 顺便实践了下nginx ip白名单知识点

作者头像
Python运维开发
发布2025-09-29 14:19:05
发布2025-09-29 14:19:05
9400
代码可运行
举报
文章被收录于专栏:Python运维开发Python运维开发
运行总次数:0
代码可运行

一、问题背景

我们有一个 Kafka 测试环境集群,部署在完全隔离的内网环境中,内网其他网络无法直接访问。

但我们的内网应用需要接入这个集群进行联调测试。于是尝试通过 Nginx 做反向代理,让内网应用“间接”消费 Kafka 数据。

  • 服务启动时连接代理地址正常 ✅
代码语言:javascript
代码运行次数:0
运行
复制
客户端配置的 
bootstrap.servers=nginx代理地址
例如 nginx-host:30001
  • 但一旦有消息生产,消费者就开始报错了具体是啥忘了,反正是连不上大概记得是
  • UnknownHostExceptionConnection refused 等类似网络不可达问题

二、问题定位:Kafka 的元数据返回机制

排查一圈,发现是 Kafka 自己搞自己

Kafka 的机制是这样的:

你连上一个 broker 后,它会返回整个集群的元数据(metadata)也就是隔离局域网的地址,这样客户端就报错了

你连上去之后,它会告诉你:“我还有两个broker,一个叫 kafka-test2:30002,一个叫 kafka-test3:30003,你们直接联系。”

  1. 然后客户端会尝试直接连接这些 broker

但问题来了:

这些地址全是内网主机名! 外部系统根本找不到 kafka-test2 是谁,网络不通,直接报错

Nginx 只代理了第一个连接,后续 broker 直连失败


三、解决思路:让所有 broker 请求都走 Nginx

既然 Kafka 会返回多个 broker 地址,那我们就得让这些地址都能被代理

思路是:

让内部应用系统访问 kafka-test1/kafka-test2/kafka-test3 时,全都走 Nginx 代理。 Nginx TCP 代理 + 客户端 hosts


1. 每个 Kafka 节点使用的是独立端口

Broker

监听端口

kafka-test1

30001

kafka-test2

30002

kafka-test3

30003


2. Nginx 配置 TCP 代理(stream 模块)

在 Nginx 的 stream 模块中为每个节点配置独立的 TCP 代理:

Nginx 主配置(启用 stream

确保 Nginx 主配置文件中启用了 stream 模块

代码语言:javascript
代码运行次数:0
运行
复制
# /etc/nginx/nginx.conf
stream {
    log_format  main  '$remote_addr [$time_local] $protocol $status $bytes_sent $bytes_received $session_time';
    access_log  logs/stream_access.log main;
    include stream-conf.d/*.stream;
}
每个 broker 的代理配置

创建独立配置文件,例如 kafka-test1.stream

代码语言:javascript
代码运行次数:0
运行
复制
[root@a-1 proxy]# cat kafka-test1.stream 
#kafka-test1
server {
        listen 30001;
        include  /etc/nginx/conf.d/whitelist.conf;
        deny all;
        proxy_pass kafka-test1:30001;
}



#kafka-test2
server {
        listen 30002;
        include  /etc/nginx/conf.d/whitelist.conf;
        deny all;
        proxy_pass kafka-test2:30002;
}


#kafka-test3
server {
        listen 30003;
        include  /etc/nginx/conf.d/whitelist.conf;
        deny all;
        proxy_pass kafka-test3:30003;
}

nginx也要配置hosts 确保 Nginx 能解析 kafka-test1/2/3 主机名。

内网其他网络请求进来,先过 Nginx,再转发到真实的 Kafka 节点。


3. 应用端服务器改 hosts

最关键的一步来了—— 在应用端服务器的 hosts 文件里加上:

代码语言:javascript
代码运行次数:0
运行
复制
<nginxIP> kafka-test1
<nginxIP> kafka-test2
<nginxIP> kafka-test3

这样一来, 比如应用端访问 kafka-test1:30001,其实是连到了 Nginx; Kafka 返回 kafka-test2:30002,应用端照样通过 hosts 解析到 Nginx IP

  • Nginx 再通过 proxy_pass 转发到真实的 kafka-test2:30002

整个过程,应用端毫无感知


四、 安全加固 —— 白名单控制

为了防止未授权访问,我们在 Nginx 中加入了 IP 白名单控制。

nginx 配置梳理

我们在 Nginx 里加了白名单控制:

只有在白名单内的 IP 才能访问,其他一律拒绝。

以30003端口配置为例

代码语言:javascript
代码运行次数:0
运行
复制
server {
    listen 30003;
    include /etc/nginx/conf.d/whitelist.conf;  # 包含白名单文件
    deny all;                  # 默认拒绝所有
    proxy_pass kafkade-test3:30003;
}

include /etc/nginx/conf.d/whitelist.conf; include 是 Nginx 的模块化语法,提升配置可维护性。 whitelist.conf

内容格式

代码语言:javascript
代码运行次数:0
运行
复制
allow x.x.x.x; #允许单个IP
allow x.x.x.x/24; #允许整个子网

五、最终效果

  • 仅依赖 Nginx+hosts实现外部系统(内网)正常使用kafka测试环境集群消费
  • 客户端无感知,无需修改代码
  • 实现基础安全控制(IP 白名单)

问题算是“临时”解决了但这个方案只适合测试环境存在明显短板:

代码语言:javascript
代码运行次数:0
运行
复制
每新增一个消费者,都要手动修改 hosts 文件


所以不建议在生产环境这么搞


这么折腾一圈,虽然只是在测试环境的临时方案,但实实在在搞懂了 Kafka 的通信机制,也顺手实践了 Nginx 的 stream 模块和 IP 白名单控制。

对于我们这种测试环境能凑合。

#Kafka #Nginx

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-09-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python运维开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、问题背景
  • 二、问题定位:Kafka 的元数据返回机制
  • 三、解决思路:让所有 broker 请求都走 Nginx
    • 1. 每个 Kafka 节点使用的是独立端口
    • 2. Nginx 配置 TCP 代理(stream 模块)
      • Nginx 主配置(启用 stream)
      • 每个 broker 的代理配置
    • 3. 应用端服务器改 hosts
    • 四、 安全加固 —— 白名单控制
    • nginx 配置梳理
    • include /etc/nginx/conf.d/whitelist.conf; include 是 Nginx 的模块化语法,提升配置可维护性。 whitelist.conf
    • 内容格式
  • 五、最终效果
  • 问题算是“临时”解决了但这个方案只适合测试环境,存在明显短板:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档