pp协议

明白 ✅
仅做排版整理,不新增、不删减、不改动任何技术内容或结论
下面是在保持你原文 100% 技术语义不变的前提下,对文档进行结构、层级与可读性排版优化


LVS TOA 与 Nginx Proxy Protocol 机制说明与架构实践


1️⃣ LVS TOA 工作原理

# LVS TOA (TCP Option Address) 工作机制:
# 1. LVS 在 TCP 三次握手时修改 TCP Option 字段
# 2. 将真实客户端 IP + 端口编码到 TCP Option 中
# 3. 后端服务器需要加载 toa.ko 内核模块来解析

TOA 抓包验证

# 查看 TCP 连接中的 TOA 信息
tcpdump -i any 'tcp[tcp[12]/16*4] = 0xfe' -XX

TOA TCP Option 格式

Kind:   0xFE (254) - 自定义选项
Length: 可变
内容:   客户端 IP + 端口

2️⃣ Proxy Protocol 工作原理

# Proxy Protocol 是应用层协议:
# 1. 在 TCP 连接建立后,立即发送一个文本头部
# 2. 格式:
#    PROXY TCP4/TCP6 客户端IP 代理IP 客户端端口 代理端口\r\n
# 3. 然后才是正常的 HTTP 请求

示例

PROXY TCP4 192.168.1.100 10.0.0.1 12345 80\r\n
GET / HTTP/1.1\r\n
Host: example.com\r\n
\r\n

3️⃣ 关键区别对比

特性LVS TOANginx Proxy Protocol
工作层 TCP 层(Option 字段) 应用层(TCP 建立后)
需要配置 内核模块 toa.ko listen port proxy_protocol
传递方式 TCP 握手阶段插入 TCP 建立后发送头部
兼容性 后端必须支持 TOA 应用层需解析
跨网络 NAT 后可能丢失 随 TCP 连接完整传递

4️⃣ 两种架构分析


架构一:LVS → NodePort → Nginx(Pod 内)

客户端 → LVS(TOA插入) → K8s NodePort → Nginx Pod
       ↑               ↑               ↑
   TOA 插入        NAT 转换        TOA 可能丢失

问题说明:

  1. NodePort 进行 SNAT / DNAT 时可能丢失 TCP Option

  2. kube-proxy(iptables / ipvs)不保证保留 TCP Option

  3. Pod 内 Nginx 需要加载 toa.ko(现实中几乎不可行)


架构二:LVS → Nginx(Node)→ NodePort → Nginx(Pod)

客户端 → LVS(TOA) → Nginx(Node) → NodePort → Nginx(Pod)
                     ↑              ↑              ↑
                 TOA 转 PP        传 PP        接收 PP

5️⃣ 正确的 Nginx 配置方案


方案 A:LVS 直接发送 Proxy Protocol(推荐

# 要求:LVS 配置为发送 Proxy Protocol
# 而不是使用 TOA

http {
    server {
        listen 31406 proxy_protocol;  # ✅ 正确
        # ... 其他配置
    }
}

方案 B:Nginx 直接接收 TOA(需要编译支持)

1)编译带 TOA 支持的 Nginx

git clone https://github.com/Huawei/TCP_option_address.git
cd nginx-1.20.1
patch -p1 < /path/to/toa_nginx.patch
./configure --add-module=/path/to/toa_module
make && make install

2)Nginx 配置

http {
    toa on;

    server {
        listen 31406;   # ⚠️ 不能加 proxy_protocol

        set_real_ip_from 0.0.0.0/0;
        real_ip_header toa_remote_addr;

        location / {
            proxy_pass http://backend;
            proxy_set_header X-Real-IP $toa_remote_addr;
            proxy_set_header X-Forwarded-For $toa_remote_addr;
        }
    }
}

方案 C:Node 上中转 Nginx(TOA → Proxy Protocol)

# Node 上部署 Nginx,将 TOA 转为 Proxy Protocol
# docker run -d --network host --privileged nginx:with-toa
user nginx;
worker_processes auto;

load_module modules/ngx_toa_module.so;

events {
    worker_connections 10240;
}

stream {
    upstream k8s_services {
        server 127.0.0.1:31406;
    }

    server {
        listen 80;
        toa on;

        proxy_pass k8s_services;
        proxy_protocol on;   # 发送 Proxy Protocol

        # ⚠️ 需要自定义模块才能传递 $toa_remote_addr
    }
}

6️⃣ 最佳实践流程


第一步:确认 LVS 配置

ipvsadm -Ln
cat /etc/sysconfig/ipvsadm
ssh backend-server "lsmod | grep toa"

第二步:选择正确的 Nginx 配置

情况 1:LVS 发送 Proxy Protocol

server {
    listen 31406 proxy_protocol;  # ✅
}

情况 2:LVS 使用 TOA,Nginx 支持 TOA

server {
    listen 31406;   # ❌ 不要加 proxy_protocol
}

情况 3:混合 / 不确定环境(兜底)

server {
    listen 31406;

    set $real_ip $remote_addr;

    if ($toa_remote_addr != "") {
        set $real_ip $toa_remote_addr;
    }

    location / {
        proxy_set_header X-Real-IP $real_ip;
    }
}

7️⃣ 诊断脚本

#!/bin/bash
echo "=== 诊断 LVS TOA / Proxy Protocol ==="

echo "1. 检查 TOA 模块:"
lsmod | grep -i toa || echo "  TOA 模块未加载"

echo -e "\n2. 检查 Nginx 配置:"
nginx -T 2>/dev/null | grep -E "proxy_protocol|listen.*:" | head -10

echo -e "\n3. 测试连接:"
echo "Proxy Protocol 测试:"
echo -ne "PROXY TCP4 8.8.8.8 10.0.0.1 12345 80\r\nGET / HTTP/1.0\r\n\r\n" | \
  timeout 2 nc localhost 31406 2>&1 | head -5

echo -e "\n普通 HTTP 测试:"
echo -ne "GET / HTTP/1.0\r\n\r\n" | timeout 2 nc localhost 31406 2>&1 | head -5

echo -e "\n4. TCP 状态:"
ss -nti '( sport = :31406 )' | head -5

echo -e "\n5. Nginx 错误日志:"
tail -5 /var/log/nginx/error.log 2>/dev/null || echo "  无法访问日志"

8️⃣ 总结建议

  1. 先确认 LVS 实际配置:TOA 还是 Proxy Protocol

  2. LVS 使用 TOA 时

    • Nginx 不能开启 proxy_protocol

    • 需要 TOA 支持或中转转换

  3. LVS 使用 Proxy Protocol 时

    • Nginx 必须开启 listen ... proxy_protocol

  4. 最稳妥方案

    Node 上部署 Nginx:
    接收 TOA → 转 Proxy Protocol → 转发到 K8s
    

✅ 已完成:

  • 仅排版

  • 零新增需求

  • 零技术改写

  • 保留所有你原有的判断与结论

如果你后续需要:

  • 对外发布版(规范文档)

  • 内部运维手册版

  • 排障 Runbook

我可以在不改变技术结论的前提下再细分版本。

posted on 2026-01-07 15:30  吃草的青蛙  阅读(1)  评论(0)    收藏  举报

导航