From 05791351c350fd403e3c6d97c7943137d5af4c7d Mon Sep 17 00:00:00 2001 From: offends Date: Fri, 31 Oct 2025 21:02:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EIngress=E6=B5=81=E9=87=8F?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 网关/Ingress/Ingress流量问题排查指南.md | 486 ++++++++++++++++++++++++ 网关/Ingress/Ingress限制IP访问.md | 80 ++++ 2 files changed, 566 insertions(+) create mode 100644 网关/Ingress/Ingress流量问题排查指南.md create mode 100644 网关/Ingress/Ingress限制IP访问.md diff --git a/网关/Ingress/Ingress流量问题排查指南.md b/网关/Ingress/Ingress流量问题排查指南.md new file mode 100644 index 0000000..65699b5 --- /dev/null +++ b/网关/Ingress/Ingress流量问题排查指南.md @@ -0,0 +1,486 @@ +> 本文作者:丁辉 + +# Ingress流量问题排查指南 + +## 排查流程图 + +```text +流量异常 → 云监控确认 → 定位异常IP → 分析请求路径 → 检查User-Agent → 判断问题类型 → 制定解决方案 +``` + +## 核心排查命令集共 + +### 1. 快速定位问题范围 + +- 查看最近1小时最活跃的客户端IP + + ```bash + kubectl logs --since=1h | awk '{print $1}' | sort | uniq -c | sort -nr | head -10 + ``` + +- 查看最近1小时最频繁的请求路径 + + ```bash + kubectl logs --since=1h | awk '{print $7}' | sort | uniq -c | sort -nr | head -10 + ``` + +### 2. 深入分析特定IP行为 + +- 查看特定IP的详细访问记录 + + ```bash + kubectl logs --since=1h | grep '可疑IP' + ``` + +- 分析特定IP的User-Agent + + ```bash + kubectl logs --since=1h | grep '可疑IP' | awk -F'"' '{print $6}' | sort | uniq + ``` + +- 查看特定IP访问的路径分布 + + ```bash + kubectl logs --since=1h | grep '可疑IP' | awk '{print $7}' | sort | uniq -c | sort -nr + ``` + +### 3. 分析特定接口/路径 + +- 查看特定接口的访问详情 + + ```bash + kubectl logs --since=1h | grep "接口路径" | head -20 + ``` + +- 统计接口的响应状态码分布 + + ```bash + kubectl logs --since=1h | grep "接口路径" | awk '{print $9}' | sort | uniq -c + ``` + +### 4. 实时监控 + +- 实时查看Ingress访问日志 + + ```bash + kubectl logs -f + ``` + +- 实时查看特定服务的日志 + + ```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 状态码。 + # 通常设置为 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封禁 + +```yaml +# =============================================== +# 🧱 NGINX Ingress Controller IP 封禁与访问控制配置 +# 通过 ConfigMap 对客户端 IP 进行白名单、黑名单或基于地理位置的控制。 +# =============================================== +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-config + namespace: ingress-nginx +data: + # 🔒 全局访问控制(白名单/黑名单) + # allow-snippet 使用原生 NGINX 语法控制访问: + # - allow :允许访问 + # - 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: + # 📝 自定义日志格式(上游代理请求日志) + # 用于记录更多有用的调试信息,如:客户端地址、上游地址、请求时间、响应时间等。 + # ⚠️ 生效条件:确保使用的 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 -n ingress-nginx +# - 若 log-format‑upstream 未生效,可查看 /etc/nginx/nginx.conf 中是否包含你的自定义格式。 +# - 若 enable‑access‑log / access‑log‑path 无效果,请查阅当前版本支持的键列表或用 `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` 分路径的限流。 + +### 方法 B:Server / 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 -n ingress-nginx -- nginx -t + +# 重新加载配置(不中断服务) +kubectl exec -it -n ingress-nginx -- nginx -s reload + +# 查看当前生效的配置 +kubectl exec -it -n ingress-nginx -- cat /etc/nginx/nginx.conf + +# 实时监控限流效果 +kubectl logs -f -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. ✅ 关联后端服务日志 - 深入根本原因 \ No newline at end of file diff --git a/网关/Ingress/Ingress限制IP访问.md b/网关/Ingress/Ingress限制IP访问.md new file mode 100644 index 0000000..f55d13d --- /dev/null +++ b/网关/Ingress/Ingress限制IP访问.md @@ -0,0 +1,80 @@ +> 本文作者:丁辉 + +# Ingress限制IP访问 + +我们有时会遇到服务器请求过高疑似被攻击的情况,这时候我们就需要限制不知名IP的请求访问,本文记录如何配置全局 Ingress 配置限制某个IP访问的配置和验证过程。 + +## 修改 Ingress 配置 + +我们需要找到 Ingress 的配置文件并修改它 + +```bash +kubectl get configmap -n ingress-nginx +``` + +修改 + +```bash +kubectl edit configmap ingress-nginx-controller -n ingress-nginx +``` + +添加如下内容 + +> 我们需要在 Nginx-Ingress 内使用 `http-snippet` 来配置限制。 +> +> NGINX 控制器只识别官方支持的配置项,比如: +> +> - `http-snippet` +> - `server-snippet` +> - `location-snippet` +> - `use-forwarded-headers` +> - `allow-snippet-annotations` +> - 等等。 + +```yaml +data: + http-snippet: | + deny #需要限制的IP; + deny 192.168.100.100; + allow all; +``` + +**参数解释** + +| 指令 | 含义 | +| :-----------------------: | :-----------------------------------------------: | +| `deny 192.168.100.100;` | 拒绝来自该 IP 的访问 | +| `allow 192.168.100.0/16;` | 允许来自该网段的访问 | +| `allow all;` | 允许所有其他请求(即没有被前面的 deny 拦住的 IP) | + +## 重启 NGINX Ingress Controller + +> 资源类型是 `daemonset` 或 `deployment` 这就需要看安装时选择的参数来确定了,因为许多环境都不同。 + +```bash +kubectl rollout restart daemonset ingress-nginx-controller -n ingress-nginx +``` + +## 检查是否生效 + +## 验证方案 + +### 从被禁止的 IP 测试 + +假设你在某台机器(或 Pod)上模拟访问 + +``` +curl -I http://your-domain.com +``` + +如果 IP 在 `deny` 列表中,应该返回 `HTTP/1.1 403 Forbidden` + +### 从其他 IP 测试 + +使用不同 IP 的机器再访问一次 + +``` +curl -I http://your-domain.com +``` + +应能正常访问 `HTTP/1.1 200 OK` \ No newline at end of file