mirror of
https://github.com/eunomia-bpf/bpf-developer-tutorial.git
synced 2026-11-03 06:04:04 +08:00
Fix curl hanging in XDP load balancer: backend servers reject mismatched Host headers (#198)
* Initial plan * Add simple HTTP server and update docs to fix curl hanging issue Co-authored-by: yunwei37 <34985212+yunwei37@users.noreply.github.com> * Fix code review issues: remove unnecessary shutdown() and fix spacing Co-authored-by: yunwei37 <34985212+yunwei37@users.noreply.github.com> * Add test script to verify HTTP servers handle mismatched Host headers Co-authored-by: yunwei37 <34985212+yunwei37@users.noreply.github.com> * Add comprehensive solution documentation for curl hanging issue Co-authored-by: yunwei37 <34985212+yunwei37@users.noreply.github.com> * Co-authored-by: yunwei37 <34985212+yunwei37@users.noreply.github.com> * Update src/42-xdp-loadbalancer/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: 云微 <1067852565@qq.com> * Update src/42-xdp-loadbalancer/README.zh.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: 云微 <1067852565@qq.com> * Update src/42-xdp-loadbalancer/SOLUTION.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: 云微 <1067852565@qq.com> * Delete src/42-xdp-loadbalancer/__pycache__/simple_http_server.cpython-312.pyc Signed-off-by: 云微 <1067852565@qq.com> * Delete src/42-xdp-loadbalancer/SOLUTION.md Signed-off-by: 云微 <1067852565@qq.com> --------- Signed-off-by: 云微 <1067852565@qq.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: yunwei37 <34985212+yunwei37@users.noreply.github.com> Co-authored-by: 云微 <1067852565@qq.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -463,13 +463,25 @@ Press Ctrl+C to exit...
|
||||
|
||||
### 测试设置
|
||||
|
||||
您可以通过在两个后端命名空间(`h2` 和 `h3`)启动 HTTP 服务器,并从本地机器向负载均衡器发送请求来测试设置:
|
||||
您可以通过在两个后端命名空间(`h2` 和 `h3`)启动 HTTP 服务器, 并从本地机器向负载均衡器发送请求来测试设置:
|
||||
|
||||
在 `h2` 和 `h3` 上启动服务器:
|
||||
|
||||
**重要提示(监听地址)**:在本实验环境中,HTTP 服务器应绑定到 `0.0.0.0`,这样它会在该网络命名空间中的所有本地地址上监听,从而能够接受通过后端 IP 转发过来的连接。
|
||||
|
||||
**重要提示(Host 头)**:负载均衡器对外暴露的虚拟 IP 地址是 `10.0.0.10`,并以该地址作为目标 IP 转发 HTTP 请求,因此请求中的 Host 头将类似于 `Host: 10.0.0.10:8000`,这与后端命名空间内实际分配给服务器进程的本地 IP 不同。是否接受这样的 Host 头由具体的 HTTP 服务器实现决定,与是否绑定到 `0.0.0.0` 无关;本教程中使用的 `simple_http_server.py` 和 `python -m http.server` 默认都会接受这种 Host 头,无需额外配置。
|
||||
**选项 1**:使用提供的简单 HTTP 服务器(推荐):
|
||||
|
||||
```sh
|
||||
sudo ip netns exec h2 python3 -m http.server
|
||||
sudo ip netns exec h3 python3 -m http.server
|
||||
sudo ip netns exec h2 python3 simple_http_server.py &
|
||||
sudo ip netns exec h3 python3 simple_http_server.py &
|
||||
```
|
||||
|
||||
**选项 2**:使用 Python 内置的 http.server 并显式绑定:
|
||||
|
||||
```sh
|
||||
sudo ip netns exec h2 python3 -m http.server --bind 0.0.0.0 &
|
||||
sudo ip netns exec h3 python3 -m http.server --bind 0.0.0.0 &
|
||||
```
|
||||
|
||||
然后,向负载均衡器 IP 发送请求:
|
||||
@@ -480,6 +492,8 @@ curl 10.0.0.10:8000
|
||||
|
||||
负载均衡器将根据哈希函数将流量分配到后端服务器(`h2` 和 `h3`)。
|
||||
|
||||
> **注意**:如果您使用 `curl` 时遇到请求挂起的问题,请确保后端 HTTP 服务器绑定到 `0.0.0.0` 并接受任何 Host 头的请求。XDP 负载均衡器在第 3/4 层(IP/TCP)运行,不会修改 HTTP 头,因此请求中的 Host 头仍将显示 `10.0.0.10:8000`,即使数据包被转发到后端 IP(10.0.0.2 或 10.0.0.3)。
|
||||
|
||||
### 使用 `bpf_printk` 进行监控
|
||||
|
||||
您可以通过查看 `bpf_printk` 日志来监控负载均衡器的活动。BPF 程序在处理每个数据包时会打印诊断消息。您可以使用以下命令查看这些日志:
|
||||
@@ -504,6 +518,24 @@ sudo cat /sys/kernel/debug/tracing/trace_pipe
|
||||
|
||||
### 调试问题
|
||||
|
||||
#### Curl 请求挂起
|
||||
|
||||
如果对负载均衡器的 `curl` 请求挂起且永不完成,最可能的原因是后端 HTTP 服务器拒绝了具有不匹配 Host 头的请求。
|
||||
|
||||
**问题**:当您运行 `curl 10.0.0.10:8000` 时,HTTP 请求包含设置为 `10.0.0.10:8000` 的 Host 头。XDP 负载均衡器在第 3/4 层(IP/TCP)将数据包转发到后端服务器(10.0.0.2 或 10.0.0.3),但 HTTP 头保持不变。如果后端 HTTP 服务器验证 Host 头并期望它与自己的 IP 地址匹配,它可能会拒绝或丢弃该请求。
|
||||
|
||||
**解决方案**:确保后端 HTTP 服务器绑定到 `0.0.0.0` 并接受任何 Host 头的请求:
|
||||
- 使用 `python3 simple_http_server.py`(在此目录中提供),或
|
||||
- 使用 `python3 -m http.server --bind 0.0.0.0`
|
||||
|
||||
**验证**:检查后端服务器日志以查看是否收到请求。您还可以在后端命名空间中使用 `tcpdump` 验证数据包是否到达:
|
||||
|
||||
```sh
|
||||
sudo ip netns exec h2 tcpdump -i veth2 -n port 8000
|
||||
```
|
||||
|
||||
#### XDP 数据包转发问题
|
||||
|
||||
某些系统可能会因为类似于此[博客文章](https://fedepaol.github.io/blog/2023/09/11/xdp-ate-my-packets-and-how-i-debugged-it/)中描述的问题而导致数据包丢失或转发失败。您可以使用 `bpftrace` 跟踪 XDP 错误进行调试:
|
||||
|
||||
```sh
|
||||
|
||||
Reference in New Issue
Block a user