裸金属 Nginx + Keepalived + HAProxy 企业级网关方案

本方案用于在裸金属主机上部署一套企业级 Web 网关,适用于前后端分离系统。

裸金属 Nginx + Keepalived + HAProxy 企业级网关方案

1. 背景与目标

本方案用于在裸金属主机上部署一套企业级 Web 网关,适用于前后端分离系统。

核心目标如下:

  • 使用 Nginx 提供前端静态资源访问;
  • 前端直接访问网关地址;
  • 后端接口统一通过 /api 路径区分;
  • 使用 HAProxy 管理后端 API 服务节点池;
  • 使用 Keepalived + VIP 实现网关入口高可用;
  • 支持前端运行时动态配置;
  • 支持后端节点动态维护;
  • 支持 Nginx / HAProxy / Keepalived 配置导出,方便迁移;
  • 支持部署、发布、回滚、校验、重载的脚本化;
  • 支持企业级日志、监控、安全和运维标准化。

2. 总体架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
用户浏览器
│
▼
VIP:10.0.0.100
│
▼
Keepalived 主备漂移
│
▼
Nginx 网关节点
├── / 前端静态资源
├── /index.html SPA 入口
├── /assets/* 静态资源缓存
├── /env.js 前端运行时动态配置
└── /api/* 转发到本机 HAProxy
│
▼
HAProxy API 后端池
├── app-01:8080
├── app-02:8080
└── app-03:8080

推荐部署两台网关节点:

节点 角色 部署组件
gateway-01 MASTER Nginx + HAProxy + Keepalived
gateway-02 BACKUP Nginx + HAProxy + Keepalived

两台机器保持配置一致,VIP 只绑定在当前 MASTER 节点上。当 MASTER 异常时,VIP 自动漂移到 BACKUP 节点。


3. 组件职责划分

3.1 Nginx 职责

Nginx 负责 Web 入口层能力,包括:

  • 监听 80 / 443;
  • 提供前端静态资源;
  • 支持 React / Vue / Angular 等 SPA 路由刷新;
  • 将 /api 请求统一转发到 HAProxy;
  • 处理 gzip / brotli 压缩;
  • 处理静态资源缓存;
  • 处理 HTTPS 证书;
  • 输出访问日志和错误日志;
  • 处理限流、Header 透传、跨域策略;
  • 支持配置校验和 reload。

Nginx 在本方案中不直接管理复杂的后端节点池,避免职责过重。

3.2 HAProxy 职责

HAProxy 负责 API 后端池,包括:

  • API 后端负载均衡;
  • 后端服务健康检查;
  • 后端节点上下线;
  • 后端节点摘流;
  • 后端节点权重调整;
  • 连接超时、请求超时、响应超时控制;
  • API 层访问日志;
  • 后端池动态维护。

HAProxy 是后端服务流量治理的核心,不建议让 Nginx 同时承担复杂后端池维护职责。

3.3 Keepalived 职责

Keepalived 只负责网关入口高可用:

  • VIP 漂移;
  • MASTER / BACKUP 切换;
  • 网关节点健康检查;
  • Nginx / HAProxy 异常时降权;
  • 当前 MASTER 节点异常时释放 VIP。

Keepalived 不做业务负载均衡,只负责 VIP 高可用。


4. 请求路由设计

4.1 前端访问

用户访问:

1
2
3
https://www.example.com/
https://www.example.com/login
https://www.example.com/dashboard

全部进入 Nginx。

Nginx 处理逻辑:

1
2
3
先查找真实静态资源
如果资源存在,直接返回
如果资源不存在,回退到 /index.html

该方式适合前端 history 路由模式。

4.2 后端接口访问

用户访问:

1
2
https://www.example.com/api/user/list
https://www.example.com/api/order/create

请求链路如下:

1
2
3
4
Nginx /api/*
-> http://127.0.0.1:18080/*
-> HAProxy
-> app 后端节点池

建议 Nginx 转发时保留以下 Header:

1
2
3
4
5
Host
X-Real-IP
X-Forwarded-For
X-Forwarded-Proto
X-Request-Id

后端服务可以根据这些 Header 获取真实客户端 IP、链路追踪 ID、原始协议等信息。


5. 高可用设计

5.1 VIP 规划

示例规划:

1
2
3
gateway-01: 10.0.0.11
gateway-02: 10.0.0.12
VIP: 10.0.0.100

用户只访问 VIP 或绑定到 VIP 的域名:

1
2
https://10.0.0.100
https://www.example.com

DNS 指向 VIP,不直接指向某一台网关机器。

5.2 Keepalived 主备策略

推荐优先级:

1
2
gateway-01 priority 120
gateway-02 priority 100

正常情况下:

1
2
gateway-01 持有 VIP
gateway-02 处于 BACKUP 状态

当 gateway-01 异常时:

1
2
3
gateway-01 priority 降低或释放 VIP
gateway-02 接管 VIP
gateway-02 开始承载流量

5.3 健康检查内容

Keepalived 的健康检查建议覆盖:

  • Nginx 进程是否存活;
  • Nginx 端口是否监听;
  • Nginx 本地健康检查是否成功;
  • HAProxy 进程是否存活;
  • HAProxy API 代理端口是否监听;
  • HAProxy 后端池是否至少存在一个可用节点;
  • 磁盘空间是否充足;
  • 系统负载是否异常。

健康检查不要过度激进,避免因为短时间抖动导致 VIP 频繁漂移。


6. 动态配置设计

动态配置分为三层:

  • 前端运行时配置;
  • 后端节点动态配置;
  • 网关模板化配置。

6.1 前端运行时配置

前端不要把环境信息、API 地址、功能开关写死在构建包中。

推荐在发布时生成:

1
/env.js

内容示例:

1
2
3
4
5
6
window.__APP_CONFIG__ = {
API_BASE_URL: "/api",
ENV: "prod",
APP_NAME: "example-web",
ENABLE_SSO: true
};

前端 index.html 引入:

1
<script src="/env.js"></script>

这样可以做到:

  • 同一份前端构建包部署到不同环境;
  • 切换 API 地址不需要重新 build;
  • 修改功能开关不需要重新发布前端;
  • 环境信息可以通过脚本动态生成。

6.2 后端节点动态配置

维护一个后端节点清单:

1
2
3
app-01 10.0.20.11 8080 weight=100
app-02 10.0.20.12 8080 weight=100
app-03 10.0.20.13 8080 weight=100

通过脚本渲染为 HAProxy backend 配置。

建议支持以下操作:

操作 说明
add 新增后端节点
remove 删除后端节点
drain 摘流节点
enable 恢复节点
weight 调整节点权重
list 查看节点列表
render 重新渲染 HAProxy 配置
reload 校验并重载 HAProxy

需要区分两类变更:

类型 说明 是否持久化
临时变更 Runtime API 摘流、恢复、权重调整 不一定
持久变更 修改节点清单并重新渲染配置 是

企业场景建议所有持久变更都写入配置文件,并纳入导出和审计。

6.3 网关模板化配置

Nginx、HAProxy、Keepalived 配置建议采用模板化方式维护。

核心文件:

1
2
3
4
5
6
7
nginx.conf.tpl
nginx-site.conf.tpl
haproxy.cfg.tpl
keepalived.conf.tpl
gateway.env
backends.list
frontend-runtime.env

配置生成流程:

1
2
3
4
5
6
7
8
9
修改 gateway.env / backends.list
↓
渲染 Nginx / HAProxy / Keepalived 配置
↓
执行配置校验
↓
校验通过后 reload
↓
校验失败则保留旧配置

关键原则:

1
2
任何配置变更必须先校验,再重载。
校验失败不能覆盖线上正在使用的配置。

7. 部署目录规范

建议统一部署到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/opt/web-gateway
├── bin
│ ├── deploy.sh
│ ├── install-packages.sh
│ ├── render-config.sh
│ ├── validate-reload.sh
│ ├── deploy-frontend.sh
│ ├── rollback-frontend.sh
│ ├── backend.sh
│ ├── export-config.sh
│ ├── restore-config.sh
│ └── healthcheck.sh
├── config
│ ├── gateway.env
│ ├── frontend-runtime.env
│ └── backends.list
├── templates
│ ├── nginx.conf.tpl
│ ├── nginx-site.conf.tpl
│ ├── haproxy.cfg.tpl
│ └── keepalived.conf.tpl
├── releases
│ ├── 20260707100000
│ ├── 20260707113000
│ └── current -> 20260707113000
├── logs
├── backups
└── exports

系统实际配置位置:

1
2
3
4
/etc/nginx/nginx.conf
/etc/nginx/conf.d/web-gateway.conf
/etc/haproxy/haproxy.cfg
/etc/keepalived/keepalived.conf

说明:

  • /opt/web-gateway/config 保存业务化配置;
  • /opt/web-gateway/templates 保存模板;
  • /opt/web-gateway/bin 保存运维脚本;
  • /opt/web-gateway/releases 保存前端历史版本;
  • /opt/web-gateway/exports 保存导出包;
  • /etc/* 保存各组件最终生效配置。

8. 前端发布与回滚方案

8.1 发布流程

1
2
3
4
5
6
7
8
9
10
11
12
13
上传前端 dist 包
↓
解压到 releases/时间戳目录
↓
生成 env.js
↓
更新 current 软链接
↓
执行 nginx -t 校验
↓
reload Nginx
↓
执行健康检查

8.2 回滚流程

1
2
3
4
5
6
7
8
9
10
11
查看 releases 历史版本
↓
选择上一个可用版本
↓
切换 current 软链接
↓
执行 nginx -t 校验
↓
reload Nginx
↓
执行健康检查

8.3 发布原则

  • 不直接覆盖线上目录;
  • 每次发布生成独立 release 目录;
  • current 永远指向当前生效版本;
  • 至少保留最近 5 个前端版本;
  • 发布失败自动回退到旧版本;
  • Nginx 配置校验失败时禁止 reload。

9. HAProxy 后端池设计

9.1 后端服务清单

建议使用独立文件维护:

1
/opt/web-gateway/config/backends.list

格式示例:

1
2
3
4
# name host port weight maxconn
app-01 10.0.20.11 8080 100 2000
app-02 10.0.20.12 8080 100 2000
app-03 10.0.20.13 8080 100 2000

9.2 健康检查策略

建议后端服务提供:

1
2
/api/health
/actuator/health

HAProxy 健康检查建议:

1
2
3
inter 2s
fall 3
rise 2

含义:

  • 每 2 秒检查一次;
  • 连续 3 次失败则摘除;
  • 连续 2 次成功则恢复。

9.3 负载均衡策略

推荐策略:

策略 适用场景
roundrobin 普通无状态 API
leastconn 长连接或响应时间差异较大场景
source 需要基于来源 IP 做简单会话保持

默认推荐:

1
roundrobin

如果后端有长请求或连接占用明显,可以改为:

1
leastconn

10. 配置导出与迁移方案

10.1 导出内容

配置导出包应包含:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
gateway.env
frontend-runtime.env
backends.list
Nginx 当前生效配置
HAProxy 当前生效配置
Keepalived 当前生效配置
templates 模板目录
bin 脚本目录
服务版本信息
服务状态信息
主机 IP 信息
VIP 信息
证书路径说明
最近一次前端 release 信息

导出包命名:

1
web-gateway-export-20260707-103000.tar.gz

10.2 不建议直接导出的内容

以下内容建议谨慎处理:

  • TLS 私钥;
  • 内部账号密码;
  • HAProxy stats 密码;
  • Runtime API socket 敏感权限;
  • 生产环境真实密钥。

如果必须导出,需要加密保存,并限制权限。

10.3 迁移流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
新机器安装基础依赖
↓
上传导出包
↓
解压恢复 /opt/web-gateway
↓
检查 gateway.env 中的网卡名、VIP、节点 IP
↓
检查证书路径
↓
重新渲染配置
↓
执行 Nginx / HAProxy / Keepalived 配置校验
↓
启动服务
↓
验证 VIP
↓
验证前端页面
↓
验证 /api 接口

迁移时必须重点检查:

  • 网卡名称是否一致;
  • VIP 是否属于当前网段;
  • 防火墙是否允许 80、443、VRRP;
  • 后端服务 IP 是否在新环境可达;
  • 证书路径是否正确;
  • DNS 是否需要调整。

11. 脚本规划

本方案建议提供以下脚本。

11.1 部署脚本

1
deploy.sh

职责:

  • 初始化目录;
  • 检查系统环境;
  • 安装 Nginx / HAProxy / Keepalived;
  • 初始化配置文件;
  • 渲染配置;
  • 校验配置;
  • 启动服务;
  • 设置 systemd 开机自启。

11.2 配置渲染脚本

1
render-config.sh

职责:

  • 读取 gateway.env;
  • 读取 backends.list;
  • 渲染 Nginx 配置;
  • 渲染 HAProxy 配置;
  • 渲染 Keepalived 配置;
  • 生成前端运行时 env.js。

11.3 校验与重载脚本

1
validate-reload.sh

职责:

  • 执行 nginx -t;
  • 执行 haproxy -c;
  • 校验 Keepalived 配置;
  • 校验通过后 reload;
  • 校验失败时阻止配置生效。

11.4 前端发布脚本

1
deploy-frontend.sh

职责:

  • 接收前端 dist 包;
  • 解压到 release 目录;
  • 生成 env.js;
  • 切换 current 软链接;
  • reload Nginx;
  • 执行健康检查。

11.5 前端回滚脚本

1
rollback-frontend.sh

职责:

  • 展示历史 release;
  • 切换到指定 release;
  • reload Nginx;
  • 执行健康检查。

11.6 后端节点维护脚本

1
backend.sh

职责:

  • 新增节点;
  • 删除节点;
  • 查看节点;
  • 摘流节点;
  • 恢复节点;
  • 调整权重;
  • 重新渲染 HAProxy 配置;
  • reload HAProxy。

11.7 配置导出脚本

1
export-config.sh

职责:

  • 导出业务配置;
  • 导出模板;
  • 导出脚本;
  • 导出当前生效配置;
  • 导出服务状态;
  • 导出版本信息;
  • 生成迁移包。

11.8 配置恢复脚本

1
restore-config.sh

职责:

  • 解压导出包;
  • 恢复 /opt/web-gateway;
  • 恢复模板和配置;
  • 提醒人工检查网卡、VIP、证书、后端 IP;
  • 渲染并校验配置。

11.9 健康检查脚本

1
healthcheck.sh

职责:

  • 检查 Nginx;
  • 检查 HAProxy;
  • 检查后端池;
  • 检查本地端口;
  • 检查磁盘空间;
  • 返回 Keepalived 可识别的状态码。

12. 日志设计

12.1 Nginx 日志字段

建议记录:

1
2
3
4
5
6
7
8
9
10
11
12
time
request_id
remote_addr
method
uri
status
request_time
upstream_addr
upstream_status
upstream_response_time
http_referer
user_agent

12.2 HAProxy 日志字段

建议关注:

1
2
3
4
5
6
7
8
9
10
11
frontend
backend
server
status_code
bytes_read
request_time
queue_time
connect_time
response_time
retries
termination_state

12.3 Keepalived 日志字段

建议关注:

1
2
3
4
5
MASTER / BACKUP 切换
priority 变化
VIP 绑定
VIP 释放
healthcheck 失败原因

13. 监控与告警设计

13.1 Nginx 监控

建议指标:

  • QPS;
  • 状态码分布;
  • 4xx 比例;
  • 5xx 比例;
  • 请求耗时;
  • upstream 响应耗时;
  • 当前连接数;
  • 日志错误数。

13.2 HAProxy 监控

建议指标:

  • backend up/down 状态;
  • backend 当前连接数;
  • backend 队列长度;
  • 每个 server 请求数;
  • 每个 server 错误率;
  • 每个 server 响应时间;
  • 健康检查失败次数。

13.3 Keepalived 监控

建议指标:

  • 当前 MASTER 节点;
  • VIP 当前所在机器;
  • VIP 漂移次数;
  • 最近一次切换时间;
  • healthcheck 失败原因。

13.4 系统监控

建议指标:

  • CPU 使用率;
  • 内存使用率;
  • 磁盘使用率;
  • 磁盘 inode 使用率;
  • 网卡流量;
  • TCP 连接数;
  • 文件句柄数;
  • 系统负载。

14. 安全设计

14.1 Nginx 安全

建议:

  • 只开放 80 / 443;
  • HTTP 自动跳转 HTTPS;
  • 配置 TLS;
  • 禁止访问 .git、.env、备份文件等敏感路径;
  • 配置安全响应头;
  • 限制上传大小;
  • 设置合理的请求超时;
  • 对 /api 设置必要限流;
  • CORS 不要直接使用全量 *;
  • 静态资源设置合理缓存策略。

14.2 HAProxy 安全

建议:

  • HAProxy API 代理端口只监听本机或内网;
  • stats 页面必须加认证;
  • Runtime Socket 限制权限;
  • 后端服务只允许网关机访问;
  • 健康检查接口不要返回敏感信息。

14.3 Keepalived 安全

建议:

  • 固定 VRRP 网卡;
  • 明确 VIP 所在网段;
  • 防火墙允许 VRRP;
  • 主备节点时间同步;
  • 健康检查脚本权限收紧;
  • 避免频繁漂移;
  • 避免主备双主。

15. 故障处理设计

故障场景 处理方式
Nginx 进程异常 Keepalived 降权,VIP 漂移
HAProxy 进程异常 Keepalived 降权,VIP 漂移
单个 API 节点异常 HAProxy 健康检查摘除节点
gateway-01 宕机 gateway-02 接管 VIP
前端发布失败 回滚到上一个 release
配置渲染失败 保留旧配置,不 reload
Nginx 配置校验失败 阻止 reload
HAProxy 配置校验失败 阻止 reload
VIP 频繁漂移 检查 healthcheck、网络抖动、系统负载
后端全部不可用 HAProxy 返回错误页或统一 503

16. 灰度与摘流方案

16.1 后端摘流

后端服务发布前:

1
2
3
4
5
6
7
8
9
从 HAProxy 中 drain 指定节点
↓
等待存量连接处理完成
↓
发布后端服务
↓
健康检查通过
↓
恢复节点流量

16.2 权重灰度

新版本服务上线后,可以先设置较低权重:

1
2
app-new weight=10
app-old weight=100

观察稳定后逐步提高权重。

16.3 前端灰度

裸金属 Nginx 前端灰度可以按以下方式实现:

  • 基于不同域名灰度;
  • 基于 Cookie 灰度;
  • 基于 Header 灰度;
  • 基于 IP 白名单灰度;
  • 使用独立灰度 release 目录。

如果前端灰度需求复杂,建议后续引入统一网关或 Ingress 层能力,不要在 Nginx 配置里堆太多业务规则。


17. 企业级落地步骤

建议按阶段落地,不要一口气把所有能力都堆上去。

第一阶段:单机前后端分离

目标:

1
2
Nginx 提供前端静态资源
Nginx /api 转发到后端服务

完成内容:

  • Nginx 安装;
  • 前端静态资源部署;
  • /api 反向代理;
  • 基础日志;
  • 基础配置校验;
  • 前端发布脚本。

第二阶段:引入 HAProxy

目标:

1
2
Nginx /api 转发到 HAProxy
HAProxy 管理后端服务节点池

完成内容:

  • HAProxy 安装;
  • backend 节点池;
  • 健康检查;
  • 节点摘流;
  • 节点维护脚本;
  • HAProxy 日志。

第三阶段:引入 Keepalived + VIP

目标:

1
2
双网关节点高可用
VIP 自动漂移

完成内容:

  • gateway-01 / gateway-02 部署;
  • Keepalived 安装;
  • VIP 配置;
  • 健康检查脚本;
  • 主备切换验证;
  • 防火墙和网络检查。

第四阶段:完善动态配置

目标:

1
2
3
配置模板化
前端运行时配置动态化
后端节点维护动态化

完成内容:

  • gateway.env;
  • frontend-runtime.env;
  • backends.list;
  • 模板渲染;
  • 配置校验;
  • reload 流程。

第五阶段:完善导出和迁移

目标:

1
2
3
配置可导出
环境可迁移
故障可恢复

完成内容:

  • 配置导出;
  • 配置恢复;
  • 迁移检查清单;
  • 敏感配置处理;
  • 版本信息导出。

第六阶段:接入监控和告警

目标:

1
2
3
网关层可观测
异常可告警
故障可定位

完成内容:

  • Nginx 日志采集;
  • HAProxy 状态采集;
  • Keepalived 状态采集;
  • 系统指标采集;
  • 告警规则;
  • 运维看板。

第七阶段:安全加固

目标:

1
满足企业生产安全基线

完成内容:

  • HTTPS;
  • 安全 Header;
  • CORS 策略;
  • 防火墙;
  • stats 认证;
  • Runtime Socket 权限;
  • 敏感文件访问限制;
  • 日志脱敏。

18. 推荐最终形态

最终推荐架构:

1
2
3
4
5
6
7
8
9
Keepalived VIP
+ Nginx Web Gateway
+ HAProxy API Backend Pool
+ 模板化配置
+ 脚本化部署
+ 前端 release 版本化
+ 后端节点动态维护
+ 配置导出迁移
+ 日志监控告警

核心原则:

1
2
3
4
5
6
Nginx 管入口和前端
HAProxy 管后端节点池
Keepalived 管 VIP 漂移
脚本管部署、发布、导出、回滚
配置文件管持久化
Runtime API 只做临时运维动作

这种方案的优势:

  • 职责清晰;
  • 容易排障;
  • 容易迁移;
  • 容易回滚;
  • 适合裸金属;
  • 不强依赖 Kubernetes;
  • 后续可以平滑迁移到容器化或云原生网关。

19. 后续扩展方向

后续可以继续扩展:

  • 接入 Prometheus + Grafana;
  • 接入 Loki / ELK 日志平台;
  • 接入 Ansible 做批量部署;
  • 接入 GitOps 管理配置;
  • 接入 Vault / KMS 管理证书和密钥;
  • 接入 WAF;
  • 支持多域名、多站点;
  • 支持蓝绿发布;
  • 支持基于 Header / Cookie 的灰度发布;
  • 支持自动证书续期;
  • 支持灾备机房切换。

20. 总结

本方案适合企业在裸金属环境下建设前后端分离网关。

设计重点不是单纯把 Nginx、HAProxy、Keepalived 装起来,而是把以下能力标准化:

  • 网关入口高可用;
  • 前端资源版本化发布;
  • 后端服务节点池治理;
  • 配置模板化与动态化;
  • 配置导出与迁移;
  • 校验、重载、回滚流程;
  • 日志、监控、安全和告警。

最终形成一套可部署、可迁移、可回滚、可排障、可扩展的企业级裸金属 Web 网关方案。


裸金属 Nginx + Keepalived + HAProxy 企业级网关方案
https://allendericdalexander.github.io/2026/10/07/devops/infra/nginx_keepalived_haproxy_gateway_solution/
作者
AtLuoFu
发布于
2026年10月7日
许可协议