Files
Kubernetes/网关/Ingress/Ingress流量问题排查指南.md
offends 05791351c3
All checks were successful
continuous-integration/drone Build is passing
新增Ingress流量控制文档
2025-10-31 21:02:15 +08:00

486 lines
16 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.

> 本文作者:丁辉
# Ingress流量问题排查指南
## 排查流程图
```text
流量异常 → 云监控确认 → 定位异常IP → 分析请求路径 → 检查User-Agent → 判断问题类型 → 制定解决方案
```
## 核心排查命令集共
### 1. 快速定位问题范围
- 查看最近1小时最活跃的客户端IP
```bash
kubectl logs <ingress-controller-pod> --since=1h | awk '{print $1}' | sort | uniq -c | sort -nr | head -10
```
- 查看最近1小时最频繁的请求路径
```bash
kubectl logs <ingress-controller-pod> --since=1h | awk '{print $7}' | sort | uniq -c | sort -nr | head -10
```
### 2. 深入分析特定IP行为
- 查看特定IP的详细访问记录
```bash
kubectl logs <ingress-controller-pod> --since=1h | grep '可疑IP'
```
- 分析特定IP的User-Agent
```bash
kubectl logs <ingress-controller-pod> --since=1h | grep '可疑IP' | awk -F'"' '{print $6}' | sort | uniq
```
- 查看特定IP访问的路径分布
```bash
kubectl logs <ingress-controller-pod> --since=1h | grep '可疑IP' | awk '{print $7}' | sort | uniq -c | sort -nr
```
### 3. 分析特定接口/路径
- 查看特定接口的访问详情
```bash
kubectl logs <ingress-controller-pod> --since=1h | grep "接口路径" | head -20
```
- 统计接口的响应状态码分布
```bash
kubectl logs <ingress-controller-pod> --since=1h | grep "接口路径" | awk '{print $9}' | sort | uniq -c
```
### 4. 实时监控
- 实时查看Ingress访问日志
```bash
kubectl logs -f <ingress-controller-pod>
```
- 实时查看特定服务的日志
```bash
kubectl logs -f <后端服务pod>
```
## 日志字段解析指南
**关键字段说明:**
- `$1` - 客户端IP地址
- `$7` - 请求路径和参数
- `$9` - HTTP状态码
- 引号内第6个字段 - User-Agent
- 倒数第6个字段 - 请求处理时间(秒)
- 方括号内字段 - 转发的K8s服务
## 常见问题模式识别
### 1. 爬虫/自动化脚本特征
- 单一IP高频访问
- User-Agent包含`bot`、`crawler`、`python`、`go`等
- 规律的请求间隔
### 2. API滥用特征
- 针对特定API接口的高频调用
- 异常的POST/PUT请求模式
- 大量4xx状态码
### 3. 性能问题特征
- 请求处理时间普遍较长(>5秒
- 大量5xx状态码
- 特定的慢接口
### 4. 安全威胁特征
- 扫描行为(访问不存在的路径)
- 注入攻击特征SQL、XSS等
- 暴力破解(大量登录尝试)
## 解决方案工具箱
### 1. 紧急限流措施
```yaml
# ===============================================
# 🧱 Ingress 限流配置(通过注解实现)
# 使用 NGINX Ingress Controller 的内建限流功能,
# 可有效防止暴力请求、爬虫或瞬时流量过载。
# ===============================================
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
# 🎯 每秒请求数限制 (Requests Per Second)
# 定义每个客户端 IP 每秒允许的最大请求数。
# 超过该值的请求会被拒绝(返回 limit-status-code 指定的状态码)。
# ⚙️ 实现方式:使用 NGINX 的 limit_req_zone + limit_req。
# 💡 建议范围:
# - 普通API: 5~20
# - 静态资源: 50~200
nginx.ingress.kubernetes.org/limit-rps: "10"
# ⚡ 每秒连接数限制 (Connections Per Second)
# 定义每个客户端 IP 每秒可新建的最大连接数。
# 对于 HTTP/1.1 Keep-Alive 长连接影响较小,但能防御连接泛洪攻击。
# ⚙️ 实现方式:使用 limit_conn_zone + limit_conn。
# 💡 建议范围:
# - 一般网站: 10~50
# - 高并发API: 100+
nginx.ingress.kubernetes.org/limit-connections: "20"
# 🛡️ 白名单设置(免限流)
# 指定 IP 或网段不受限流影响。
# 可用于信任的反向代理、内部系统或监控探针。
# 支持单个 IP 或 CIDR逗号分隔
# ⚠️ 建议仅加入受信任来源,否则可能绕过防护。
nginx.ingress.kubernetes.org/limit-whitelist: "192.168.0.0/24,10.0.0.1"
# 🚀 突发请求缓冲(突发容忍)
# 允许在短时间内超出 limit-rps 的请求数量。
# 适用于偶发瞬时高峰(如页面资源集中加载)。
# ⚙️ 内部机制:令牌桶算法 (burst capacity)。
# 💡 建议burst 通常设为 limit-rps 的 2~3 倍。
nginx.ingress.kubernetes.org/limit-burst: "20"
# 🚫 限流响应码
# 当请求被限流时返回的 HTTP 状态码。
# 通常设置为 429Too Many Requests或 503Service Unavailable
# 💡 若你的客户端或上游依赖特定响应行为,可自定义此状态码。
nginx.ingress.kubernetes.org/limit-status-code: "503"
# ===============================================
# 📋 提示:
# - 若同一个 Ingress 使用多个路径,限流策略对整个 Ingress 生效。
# - 如需区分路径限流,可分别定义多个 Ingress。
# - 可配合 nginx.ingress.kubernetes.org/limit-rpm (每分钟请求数)。
# - 修改后执行:
# kubectl apply -f example-ingress.yaml
# kubectl describe ingress example-ingress
# 以确认注解生效。
# ===============================================
```
### 2. IP封禁
```yaml
# ===============================================
# 🧱 NGINX Ingress Controller IP 封禁与访问控制配置
# 通过 ConfigMap 对客户端 IP 进行白名单、黑名单或基于地理位置的控制。
# ===============================================
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: ingress-nginx
data:
# 🔒 全局访问控制(白名单/黑名单)
# allow-snippet 使用原生 NGINX 语法控制访问:
# - allow <IP/CIDR>:允许访问
# - deny all拒绝所有其他访问
# ⚙️ 使用场景:
# - 内网服务只允许特定网段访问
allow-snippet: |
allow 192.168.0.0/16;
allow 10.0.0.0/8;
deny all;
```
### 3. 优化配置
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-configuration
namespace: ingress-nginx
data:
# ================================
# 🌐 NGINX Ingress Controller 全局配置
# 此 ConfigMap 控制 ingress-nginx 控制器内 NGINX 实例的行为。
# 修改后通常需要重新加载 Ingress Controller 才会生效。
# ================================
# ⏱️ 连接超时时间(秒)
# 定义 NGINX 与上游后端Service Pod建立 TCP 连接的超时。
# 若上游响应缓慢或网络不稳定,可适当调大。
# 建议范围5~30秒
proxy-connect-timeout: "10"
# ⏱️ 读取超时时间(秒)
# 定义 NGINX 在与上游通信时,等待上游响应数据的最长时间。
# 超时后会返回 504 Gateway Timeout。
# 建议范围10~60秒取决于上游处理逻辑耗时。
proxy-read-timeout: "30"
# ⏱️ 发送超时时间(秒)
# 定义 NGINX 向上游发送请求数据的超时。
# 对上传大文件或慢速后端可适当调大。
# 建议与 proxy-read-timeout 一致。
proxy-send-timeout: "30"
# ⏱️ 客户端请求头超时
# 定义 NGINX 等待客户端(例如浏览器或负载均衡器)
# 发送完整请求头的超时时间。
# 过低可能影响慢速客户端,过高可能被滥用进行慢速攻击。
client-header-timeout: "10"
# 📦 客户端请求体大小限制
# 限制客户端请求体(例如上传文件)的最大大小。
# 超出时返回 413 Request Entity Too Large。
# 例如 "10m" 表示最大 10MB。
# 建议根据业务场景调整:普通 API 可设为 1~5m大文件上传可放宽。
proxy-body-size: "10m"
# 🔄 保持连接超时
# 定义客户端与 NGINX 之间的 keep-alive 持续时间(秒)。
# 影响 HTTP 连接复用性能和资源占用。
# 值过低会增加连接重建开销;过高可能导致空闲连接占用资源。
# 建议范围30~120秒。
keep-alive: "75"
# 📊 缓冲区设置
# 控制 NGINX 在代理上游响应时的内存缓冲。
# 调整这些值可优化大响应体(例如 JSON、大型页面的性能。
# proxy-buffer-size: 单个缓冲区大小。
# proxy-buffers-number: 缓冲区数量。
# 默认通常足够,除非你的后端返回非常大的头部或响应。
proxy-buffer-size: "8k"
proxy-buffers-number: "4"
# ====================================
# 🧩 补充说明:
# - 修改 ConfigMap 后需触发 ingress-nginx 控制器 reload。
# 可执行: kubectl rollout restart deployment ingress-nginx-controller -n ingress-nginx
# - 所有 timeout 值均为秒(字符串形式)。
# - 若使用 AWS/GCP LB还需确保 LB 层超时 >= 这些值。
# ====================================
```
## 4. 安全加固配置
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: ingress-nginx
data:
# 🔐 隐藏 NGINX 版本信息
# 设置为 "false" 可防止 NGINX 在响应头中显示 Server: nginx/版本号
# ⭐ 注意:部分版本可能仍在某些情况下显示 Server 字段,建议验证生成的 nginx.conf。
server-tokens: "false"
# 🔍 是否允许 HTTP 请求头中包含下划线 (_) 字符
# 若设置为 "false"Nginx 会拒绝或忽略带下划线的头部字段。
# 若你的客户端或上游服务使用 “X_Custom_Header” 这类头部,请设置为 "true"。
enable-underscores-in-headers: "false"
# 🔒 是否忽略无效的 HTTP 头部字段
# 设置为 "true" 时Nginx 遇到格式错误或不合法的头部,将会忽略而不是拒绝。
ignore-invalid-headers: "true"
# 🛡️ SSL 强化配置 — 协议版本
# 只启用 TLS v1.2 和 v1.3,禁用旧版本(如 TLS1.0/1.1)以提高安全性。
ssl-protocols: "TLSv1.2 TLSv1.3"
# 🛡️ SSL 强化配置 — 加密套件 (Cipher Suites)
# 指定特定的、安全性较强的加密套件。请参考你所用 NGINX 版本所支持的套件列表。
ssl-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256"
# 📋 提示:修改后请滚动重启 ingress-nginx 控制器 Pod例如
# kubectl rollout restart deployment ingress-nginx-controller -n ingress-nginx
# 并使用 kubectl exec 查看 /etc/nginx/nginx.conf 中是否包含你配置的指令。
```
## 5. 日志与监控配置
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: ingress-nginx
data:
# 📝 自定义日志格式(上游代理请求日志)
# 用于记录更多有用的调试信息,如:客户端地址、上游地址、请求时间、响应时间等。
# ⚠️ 生效条件:确保使用的 ingressnginx 版本支持 log-format-upstream并且正在使用该 ConfigMap。 :contentReference[oaicite:5]{index=5}
log-format-upstream: |
'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'upstream_addr: $upstream_addr '
'request_time: $request_time '
'upstream_response_time: $upstream_response_time'
# 📊 访问日志设置 — **需确认键是否被支持**
# enable-access-log: 若设置为 “true”希望启用访问日志。
# access-log-path: 指定访问日志文件路径(例如 /var/log/nginx/access.log
# ⚠️ 文档未明确将这两项列为标准 ConfigMap 键,实际生效需验证。
enable-access-log: "true"
access-log-path: "/var/log/nginx/access.log"
# 🔍 错误日志级别
# 可选值debug|info|notice|warn|error|crit|alert|emerg
# 推荐生产环境使用 “warn” 或 “error” 以减少噪声,调试期可用 “info” 或 “debug”。
error-log-level: "warn"
# 📋 提示:
# - 修改后需要滚动重启 ingressnginx 控制器 Podkubectl rollout restart deployment <controller> -n ingress-nginx
# - 若 log-formatupstream 未生效,可查看 /etc/nginx/nginx.conf 中是否包含你的自定义格式。
# - 若 enableaccesslog / accesslogpath 无效果,请查阅当前版本支持的键列表或用 `access-log-off`、`disable-access-log` 等键进行切换。
```
## 6. 高级限流策略
### 方法 A使用注解推荐
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
# 每个IP每秒最多10个请求
nginx.ingress.kubernetes.org/limit-rps: "10"
# 突发请求允许数量
nginx.ingress.kubernetes.org/limit-burst: "20"
# 并发连接限制
nginx.ingress.kubernetes.org/limit-connections: "5"
```
- 优点:官方支持,简单。
- 缺点:无法直接实现 `$request_uri` 分路径的限流。
### 方法 BServer / Configuration Snippet
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
limit_req_zone $binary_remote_addr zone=global:10m rate=10r/s;
limit_req_zone $request_uri zone=api:10m rate=5r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
```
- 这里可以写原生 NGINX 指令,并在 ingress-nginx 的 server 块中生效。
- 注意:需要确认你使用的 ingress-nginx 版本允许 `server-snippet` 注解。
## 7. 实际应用示例
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: protected-app
annotations:
# =========================================
# ⚡ 基础限流每个IP每秒允许的请求数
# nginx.ingress.kubernetes.org/limit-rps
# - 控制每个客户端 IP 的请求频率
# - 超过此速率的请求将被限流
# - 建议值5~20视业务请求量而定
nginx.ingress.kubernetes.org/limit-rps: "10"
# 🚀 突发流量允许值burst
# nginx.ingress.kubernetes.org/limit-burst
# - 短时间内允许超过 limit-rps 的请求数
# - 可缓解瞬时高峰流量
# - 建议值limit-rps 的 2~3 倍
nginx.ingress.kubernetes.org/limit-burst: "20"
# 🔗 并发连接限制
# nginx.ingress.kubernetes.org/limit-connections
# - 每个客户端 IP 的最大并发连接数
# - 防止单个IP占用过多连接导致资源耗尽
# - 建议值5~20视服务并发能力而定
nginx.ingress.kubernetes.org/limit-connections: "10"
# 🛡️ 白名单(免限流)
# nginx.ingress.kubernetes.org/limit-whitelist
# - 指定 IP 或网段不受限流影响
# - 可用于内部网络或可信代理
# - 支持逗号分隔的 CIDR 或单个 IP
nginx.ingress.kubernetes.org/limit-whitelist: "10.0.0.0/8,192.168.0.0/16"
# ⏱️ 超时设置:避免长连接占用资源
# nginx.ingress.kubernetes.org/proxy-read-timeout / proxy-send-timeout
# - 分别控制 NGINX 读取上游响应和发送请求的超时时间
# - 建议值10~60秒视后端响应时间而定
nginx.ingress.kubernetes.org/proxy-read-timeout: "30"
nginx.ingress.kubernetes.org/proxy-send-timeout: "30"
# 🚫 限流响应码
# nginx.ingress.kubernetes.org/limit-status-code
# - 当请求被限流时返回的 HTTP 状态码
# - 常用 429 (Too Many Requests) 或 503 (Service Unavailable)
nginx.ingress.kubernetes.org/limit-status-code: "429"
# =========================================
# 📋 使用提示:
# 1. 修改注解后无需修改 ConfigMap直接 kubectl apply -f ingress.yaml 即可生效。
# 2. 对于高峰业务,可适当调高 limit-burst 和 limit-rps避免误伤正常用户。
# 3. 白名单只应包含可信内部 IP防止绕过限流。
# 4. 若配合负载均衡器或 CDN确保 LB 层超时时间 >= proxy-read/send-timeout。
```
## 配验证命令
```bash
# 验证配置语法是否正确
kubectl exec -it <ingress-pod> -n ingress-nginx -- nginx -t
# 重新加载配置(不中断服务)
kubectl exec -it <ingress-pod> -n ingress-nginx -- nginx -s reload
# 查看当前生效的配置
kubectl exec -it <ingress-pod> -n ingress-nginx -- cat /etc/nginx/nginx.conf
# 实时监控限流效果
kubectl logs -f <ingress-pod> -n ingress-nginx | grep "limiting requests"
```
## 监控和告警设置
### 1. 关键监控指
- QPS每秒请求数
- 错误率4xx/5xx
- 响应时间P95/P99
- 带宽使用率
### 2. 告警阈值建议
```bash
# 异常流量检测规则示例
- QPS突增 > 50%
- 5xx错误率 > 5%
- 平均响应时间 > 3s
- 单一IP请求占比 > 20%
```
## 💡 经验总结
### 快速诊断清单:
1. ✅ 先看IP分布 - 找到异常源头
2. ✅ 再看请求路径 - 定位问题接口
3. ✅ 分析User-Agent - 判断请求性质
4. ✅ 检查响应时间和状态码 - 确认影响范围
5. ✅ 关联后端服务日志 - 深入根本原因