16 KiB
16 KiB
本文作者:丁辉
Ingress流量问题排查指南
排查流程图
流量异常 → 云监控确认 → 定位异常IP → 分析请求路径 → 检查User-Agent → 判断问题类型 → 制定解决方案
核心排查命令集共
1. 快速定位问题范围
-
查看最近1小时最活跃的客户端IP
kubectl logs <ingress-controller-pod> --since=1h | awk '{print $1}' | sort | uniq -c | sort -nr | head -10 -
查看最近1小时最频繁的请求路径
kubectl logs <ingress-controller-pod> --since=1h | awk '{print $7}' | sort | uniq -c | sort -nr | head -10
2. 深入分析特定IP行为
-
查看特定IP的详细访问记录
kubectl logs <ingress-controller-pod> --since=1h | grep '可疑IP' -
分析特定IP的User-Agent
kubectl logs <ingress-controller-pod> --since=1h | grep '可疑IP' | awk -F'"' '{print $6}' | sort | uniq -
查看特定IP访问的路径分布
kubectl logs <ingress-controller-pod> --since=1h | grep '可疑IP' | awk '{print $7}' | sort | uniq -c | sort -nr
3. 分析特定接口/路径
-
查看特定接口的访问详情
kubectl logs <ingress-controller-pod> --since=1h | grep "接口路径" | head -20 -
统计接口的响应状态码分布
kubectl logs <ingress-controller-pod> --since=1h | grep "接口路径" | awk '{print $9}' | sort | uniq -c
4. 实时监控
-
实时查看Ingress访问日志
kubectl logs -f <ingress-controller-pod> -
实时查看特定服务的日志
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. 紧急限流措施
# ===============================================
# 🧱 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 状态码。
# 通常设置为 429(Too Many Requests)或 503(Service 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封禁
# ===============================================
# 🧱 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. 优化配置
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. 安全加固配置
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. 日志与监控配置
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: ingress-nginx
data:
# 📝 自定义日志格式(上游代理请求日志)
# 用于记录更多有用的调试信息,如:客户端地址、上游地址、请求时间、响应时间等。
# ⚠️ 生效条件:确保使用的 ingress‑nginx 版本支持 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"
# 📋 提示:
# - 修改后需要滚动重启 ingress‑nginx 控制器 Pod:kubectl rollout restart deployment <controller> -n ingress-nginx
# - 若 log-format‑upstream 未生效,可查看 /etc/nginx/nginx.conf 中是否包含你的自定义格式。
# - 若 enable‑access‑log / access‑log‑path 无效果,请查阅当前版本支持的键列表或用 `access-log-off`、`disable-access-log` 等键进行切换。
6. 高级限流策略
方法 A:使用注解(推荐)
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分路径的限流。
方法 B:Server / Configuration Snippet
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. 实际应用示例
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。
配验证命令
# 验证配置语法是否正确
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. 告警阈值建议
# 异常流量检测规则示例
- QPS突增 > 50%
- 5xx错误率 > 5%
- 平均响应时间 > 3s
- 单一IP请求占比 > 20%
💡 经验总结
快速诊断清单:
- ✅ 先看IP分布 - 找到异常源头
- ✅ 再看请求路径 - 定位问题接口
- ✅ 分析User-Agent - 判断请求性质
- ✅ 检查响应时间和状态码 - 确认影响范围
- ✅ 关联后端服务日志 - 深入根本原因