一、当你的Ingress开始"堵车"时

想象一下早晚高峰期的城市主干道,当Kubernetes集群的Ingress流量暴增时,你的控制器就像被堵在十字路口的交警,手忙脚乱地处理着不断涌来的请求。最近我们生产环境就遇到了这样的场景:

  • 每天上午9点API请求量激增3倍
  • 响应延迟从50ms飙升到1200ms
  • Nginx Ingress Pod的CPU使用率长期保持在80%红线
# 诊断用的Ingress资源示例(技术栈:Kubernetes + Nginx Ingress)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-gateway
  annotations:
    nginx.ingress.kubernetes.io/limit-rps: "100"  # 漏桶限流
    nginx.ingress.kubernetes.io/proxy-buffering: "on"  # 启用缓冲
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

注释说明:

  1. limit-rps 像交通信号灯控制车流
  2. proxy-buffering 相当于在路口设置临时停车带

二、拆解Ingress的"发动机"

2.1 性能瓶颈的四大"罪魁祸首"

  1. 规则爆炸:当你有300+条Ingress规则时,Nginx需要重新加载的配置文件可能超过5MB
  2. TLS握手:就像每次过安检都要重新验证身份证,频繁的HTTPS连接会消耗大量CPU
  3. 日志洪水:访问日志以每秒2000条的速度写入磁盘
  4. 缓冲区不足:默认的8KB缓冲区在高并发下就像用吸管喝珍珠奶茶
# 查看Nginx Ingress性能指标(技术栈:Prometheus + Grafana)
sum(rate(nginx_ingress_controller_requests[1m])) by (host)  # 按主机统计QPS
histogram_quantile(0.95, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket[1m])) by (le))  # 95分位延迟

2.2 对症下药的优化方案

方案A:启用动态TLS证书

# 使用Cert-Manager自动续期证书(技术栈:Kubernetes Cert-Manager)
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: api-cert
spec:
  secretName: api-tls
  duration: 2160h  # 90天有效期
  renewBefore: 360h # 到期前15天续期
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
  - "api.example.com"

方案B:日志采样策略

# Ingress Controller的Nginx配置片段(技术栈:Nginx Lua)
log_format json_log escape=json
    '{"time":"$time_iso8601",'
    '"host":"$host",'
    '"status":"$status"}';

map $request_uri $loggable {
    ~^/healthz 0;    # 健康检查不记录
    default 1;
}

access_log /var/log/nginx/access.log json_log if=$loggable;

三、实战调优五步走

3.1 第一步:给Ingress Controller"减负"

# 将Ingress Controller的部署改为DaemonSet(技术栈:Kubernetes)
kubectl patch deploy nginx-ingress -n ingress-nginx -p '{"spec":{"strategy":{"rollingUpdate":{"maxUnavailable":1}}}}'

# 设置资源限制
resources:
  limits:
    cpu: "2"
    memory: 2Gi
  requests:
    cpu: "500m"
    memory: 512Mi

3.2 第二步:启用HTTP/2和Gzip

# Ingress注解配置(技术栈:Kubernetes Annotations)
annotations:
  nginx.ingress.kubernetes.io/http2: "true"
  nginx.ingress.kubernetes.io/gzip: "on"
  nginx.ingress.kubernetes.io/gzip-types: "application/json, text/css"

3.3 第三步:连接池优化

# Nginx配置模板调整(技术栈:Nginx Template)
upstream backend {
    server api-service:80 max_fails=3 fail_timeout=5s;
    keepalive 32;  # 保持长连接
    keepalive_requests 1000;  # 单个连接最大请求数
    keepalive_timeout 60s;  # 空闲超时
}

四、进阶优化与避坑指南

4.1 使用全局速率限制

# 自定义Lua限流脚本(技术栈:OpenResty Lua)
local limit_req = require "resty.limit.req"
local limiter = limit_req.new("my_limit_store", 100, 50)  # 100req/s + 50突发

local delay, err = limiter:incoming(key, true)
if not delay then
    if err == "rejected" then
        return ngx.exit(503)
    end
    return ngx.exit(500)
end

4.2 避免的五个常见错误

  1. 在Ingress层启用SSL终止却忘记更新密码套件
  2. 使用默认的负载均衡算法(round-robin)处理长短连接混合场景
  3. 忽略内核参数调优(如增大somaxconn)
  4. 在单个Ingress Controller中混用生产/测试流量
  5. 没有为Prometheus指标设置合适的采集间隔
# 关键内核参数调整(技术栈:Linux sysctl)
sysctl -w net.core.somaxconn=32768
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_max_syn_backlog=8096

五、效果验证与未来规划

经过上述优化后,我们的API网关表现出显著改善:

  • 平均延迟从1200ms降至180ms
  • P99延迟从5s降至800ms
  • Ingress Pod的CPU使用率降至35%
# 使用wrk进行压力测试(技术栈:性能测试工具)
wrk -t12 -c400 -d30s https://api.example.com/api/v1/users 
--latency  # 查看延迟分布

未来我们还计划:

  1. 尝试Envoy作为Ingress Controller
  2. 实现基于地理位置的路由分流
  3. 部署边缘计算节点减少回源流量