Files
Deploy-Laboratory/docs/01-06-openwrt-haproxy.md
2026-03-29 09:08:01 +08:00

146 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 01-06 OpenWrt HAProxy 负载均衡
> 在 OpenWrt 上安装并配置 HAProxy将 80/443 流量转发到 K3s 集群节点Traefik 入口),实现单一入口与负载均衡。
## 契约与真源HAProxy 配置文件)
**HAProxy 示例配置的唯一真源**:本仓库 **[`ansible/files/01-06/`](../ansible/files/01-06/)**(与文档、脚本共用;上 OpenWrt 前请按实际节点 IP/端口改 `server``bind`)。
| 文件 | 说明 |
|------|------|
| [`haproxy-no-check.cfg`](../ansible/files/01-06/haproxy-no-check.cfg) | 最简无健康检查HTTP 18080 + TCP 443 透传 18443见 §2 |
| [`haproxy-http.cfg`](../ansible/files/01-06/haproxy-http.cfg) | 80 明文 HTTP 健康检查(`option httpchk`§3.2 |
| [`haproxy-tls.cfg`](../ansible/files/01-06/haproxy-tls.cfg) | 443 `mode tcp` + TLS 握手检查§3.3 |
| [`haproxy-https.cfg`](../ansible/files/01-06/haproxy-https.cfg) | 443 应用层 HTTPS 检查HAProxy 终结 TLS 场景§3.4 |
| [`haproxy-proxy-http-tls.cfg`](../ansible/files/01-06/haproxy-proxy-http-tls.cfg) | HTTP/TLS 检查 + `send-proxy-v2`§5 |
OpenWrt 上实际生效路径多为 **`/etc/haproxy.cfg`** 或 **`/etc/haproxy/haproxy.cfg`**,以 **`/etc/init.d/haproxy`** 为准;将上述文件**复制过去**或合并片段后执行 `haproxy -c -f <路径>` 校验。
## TL;DR
- **HAProxy 配置**:见上表 **[`ansible/files/01-06/`](../ansible/files/01-06/)** `*.cfg`
- **自动化验收**`./ansible/bin/verify.sh run 01-06`
- **关键前置**:按本文「前置条件」准备环境变量/Secret/入口 IP
- **成功判据**:达到本文「预期」且 playbook 断言通过
- **排障**:见本文「排障」
## 前置条件
- OpenWrt 与 K3s 节点同网段(如 192.168.2.0/24OpenWrt 通常为网关(如 192.168.2.1
- 已完成 `01-02-k3s-工作节点.md``01-05`Traefik 入口 80/443 已在各节点可达
## 1. 安装 HAProxy
```bash
opkg update
opkg install haproxy
```
若使用 LuCI可在「系统」→「软件包」中搜索 `haproxy` 安装。
## 2. 配置(原生)
编辑 `/etc/haproxy.cfg` 或包提供的配置路径(部分 OpenWrt 使用 `/etc/haproxy/haproxy.cfg`)。可在 `/etc/init.d/haproxy` 中查看实际配置文件路径。
**配置目录说明与「cfg 是否正确」的验证层次**:见 `ansible/files/01-06/`**仅语法**`./scripts/01-06-verify-haproxy.sh --cfg-only`)。
**无健康检查最简配置**`ansible/files/01-06/haproxy-no-check.cfg`(与 Ansible 共用,可复制到 OpenWrt 或通过 playbook 下发)。将 `192.168.2.61``192.168.2.64` 按实际 K3s 节点 IP 修改。如需健康检查见第 3 节;如需真实客户端 IP 见第 5 节 PROXY Protocol。
## 3. 健康检查
分四类:**TCP**、**HTTP**、**TLS**、**HTTPS**,由浅到深。
| 类型 | 说明 | 适用端口 |
|------|------|----------|
| TCP | `server ... check`,端口能连即通过 | 80、443 等 |
| HTTP | `option httpchk`,明文 HTTP 请求 | 80 |
| TLS | `option ssl-hello-chk`TLS 握手层 | 443`mode tcp` |
| HTTPS | `option httpchk` + `server ... ssl`HTTP over TLS | 443`mode http` |
说明443 业务若为 **TCP 透传**backend 是 `mode tcp`,只能选 TCP 或 TLS若需 HTTPS 级检查,需另建 `mode http` 的 backend。
### 3.1 TCP
`haproxy-no-check.cfg` 基础上,各 `server` 行末尾加 `check` 即可。
### 3.2 HTTP80 明文)
完整配置:`ansible/files/01-06/haproxy-http.cfg``backend k3s_http` 开头加 `option httpchk GET /``k3s_https` 仍为 TCP 检查。
### 3.3 TLS443 握手,`mode tcp`
完整配置:`ansible/files/01-06/haproxy-tls.cfg``backend k3s_https` 中加 `option ssl-hello-chk`,做 TLS 握手层检查。
### 3.4 HTTPS443 应用层,`mode http` + `ssl`
完整配置:`ansible/files/01-06/haproxy-https.cfg`。适用于 **HAProxy 在 443 终结 TLS由 HAProxy 提供证书)** 的场景frontend 需 `bind *:443 ssl crt ...`)。需与 Traefik 路由匹配的 `Host`;自签/内网 CA 用 `verify none`,生产建议 `ca-file`。若仍为 TCP 透传,用 3.3 即可。
## 4. 启动与验证
**一键部署**uhttpd 80/443 + HAProxy 18080/18443`./scripts/01-06-deploy-openwrt-haproxy.sh`。将 uhttpd 恢复监听 80/443IPv4+IPv6HAProxy 部署到 18080/18443与 LuCI 共存。
```bash
/etc/init.d/haproxy enable
/etc/init.d/haproxy restart
```
验证:从内网访问 `http://<OpenWrt-IP>:18080/``http://<OpenWrt-IP>:18080/demo-m1/`(家庭私网常用 18080/18443应能到达 Traefik 与后端。
**验证**:经 **Linux 工作机**(本环境如 **`ylc65`**,在 `ansible/env/.env.verify` 里用 **`WORKSTATION_SSH`** 配置一行 `ssh user@ylc65 …`)发起 curl验证 `http://<OpenWrt-IP>:18080``https://<域名>:18443`HTTPS 需正确设置 Host/SNI例如 `curl --https-hosts ...`)。不部署、不改端口;需 OpenWrt HAProxy 已按 18080/18443 配置。
验证通过后,建议你在本篇文档中**手工**补充状态与备注(环境/日期/覆盖范围)。
## 5. PROXY Protocol可选
若 Traefik 需获取真实客户端 IP可在 HAProxy 后端每个 `server` 行添加 `send-proxy-v2`,并在 Traefik 配置 `trustedIPs` 包含 OpenWrt 网段(见 `03-02-k3s-traefik-acme.md`)。
**完整配置**`ansible/files/01-06/haproxy-proxy-http-tls.cfg`HTTP 检查 + TLS 检查 + PROXY
Traefik 端需启用 PROXY protocol 监听并信任 OpenWrt 的 IP否则会报错。UCI 配置需参考 OpenWrt HAProxy 文档中的相应选项。
## 6. 端口与防火墙
**80/443 被封**:家庭网络若被运营商封禁 80/443可改用 18080/18443 等非标准端口,供直接访问或配合 Cloudflare CDN 端口转发。将 frontend 的 `bind *:80``bind *:443` 改为 `bind *:18080``bind *:18443` 即可Traefik 入口及后端保持不变。
**防火墙**:确保 OpenWrt 放行实际监听端口80/443 或 18080/18443 等)入站,或将 HAProxy 监听接口加入相应 zone。
## 7. 故障排除
| 现象 | 可能原因 | 排查与处理 |
|------|----------|------------|
| HAProxy 启动失败 | 配置语法错误、端口被占用 | `haproxy -c -f /etc/haproxy.cfg` 校验;用 `netstat -tlnp``ss -tlnp` 查端口占用 |
| curl 到网关 80 返回 LuCI | **uhttpd** 占 80HAProxy 若用 80 会冲突 | 家庭私网建议 HAProxy 用 18080/18443与 LuCI 共存 |
| 502 Bad Gateway / 后端全部 down | K3s 节点不可达、健康检查过严 | `curl http://<节点IP>/` 直连节点;放宽 `check` 或改用 TCP 检查 |
| HTTP 可达但 HTTPS 不通 | TLS 透传与检查类型不匹配 | 443 若为 `mode tcp`,用 TCP 或 TLS 检查;`mode http` 时用 HTTPS 检查并核对 Host |
| 日志显示 PROXY protocol 错误 | Traefik 未启用或未信任 OpenWrt | 确认 Traefik 入口启用 PROXY、`trustedIPs` 含 OpenWrt 网段;或暂时去掉 `send-proxy-v2` |
| 修改配置后无效果 | 未重启、配置路径错误 | `/etc/init.d/haproxy restart`;确认 `/etc/init.d/haproxy` 中读取的 cfg 路径 |
| 外网访问不到 | 运营商封 80/443、防火墙未放行 | 改用 18080/18443 或配合 Cloudflare检查 `firewall` 规则与 zone 配置 |
**常用命令**
```bash
# 校验配置
haproxy -c -f /etc/haproxy.cfg
# 手动前台启动便于看输出、init.d 不可用时)
haproxy -f /etc/haproxy.cfg
# 查看 HAProxy 状态(若使用 init.d
/etc/init.d/haproxy status
# 直连 K3s 节点验证
curl -v http://192.168.2.61/
```
## 相关文档
- `01-02-k3s-工作节点.md`Traefik 入口与 LB 基线
- `02-05-nginx-验证矩阵-一键部署.md`:验证矩阵(按入口 IP 访问)
- `03-02-k3s-traefik-acme.md`PROXY protocol、trustedIPs
## 排障
- **先看 playbook 输出**:失败时先定位是 deploy/wait/http_check 哪一步。
- **集群侧总览**`kubectl get nodes -o wide``kubectl -n kube-system get pods -o wide`
- **事件与日志**`kubectl -n <ns> describe ...``kubectl -n <ns> logs ... --tail=200`