Ingress Controller(Nginx/Envoy)路由转发与SSL卸载配置详解

深入对比Nginx Ingress和Envoy(Contour/Gateway)在Kubernetes中的路由转发机制与SSL卸载配置,涵盖动态证书管理、性能差异、回滚策略及生产级最佳实践,帮助团队做出正确选型并规避常见陷阱。

Ingress Controller(Nginx/Envoy)路由转发与SSL卸载配置详解
封面图:ZuCDN · ZuCDN 原创

引言:路由转发与SSL卸载为何是Ingress Controller的核心

在Kubernetes集群中,Ingress Controller承担着南北流量的统一入口角色。路由转发决定了请求如何到达对应的Service,而SSL卸载则负责将HTTPS流量解密为后端HTTP,同时管理证书生命周期。这两项功能直接影响到集群的安全、性能和运维复杂度。

市面上主流方案中,Nginx Ingress(基于OpenResty/Lua)和Envoy(通过Contour或Envoy Gateway实现)拥有截然不同的设计哲学。Nginx依赖静态模板生成和Lua脚本扩展,而Envoy采用xDS动态配置,支持热更新和更精细的流量控制。本文将从路由转发规则SSL卸载机制两个维度展开,给出可直接落地的配置示例、风险点与回滚方法,不堆砌概念,只讲真实可用方案。

一、路由转发机制对比:模板驱动 vs 动态控制

1.1 Nginx Ingress的路由转发

Nginx Ingress通过Ingress资源中的rulesannotations定义转发行为。其底层工作原理是:Ingress Controller监听到资源变化后,重新生成nginx.conf模板,然后执行nginx -s reload。这意味着每次路由变更都会引起短暂的连接中断(尽管通常只有毫秒级)。

关键配置示例:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /api(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

此例中,rewrite-target/api/v1/users重写为/v1/users并转发到后端。使用正则时必须配合use-regex: "true",且注意正则路径的优先级较低(Nginx按照固定字符串 > 正则顺序匹配)。

风险点:

  • 过多的正则规则会导致Nginx配置重载时CPU峰值升高;
  • 路径匹配顺序不透明,容易造成路由冲突;
  • 频繁reload在大型集群中可能引发连接泄漏(worker进程不会立即终止)。

回滚策略:

如果更新Ingress后出现502,可使用kubectl edit ingress直接回退到上一个配置,或通过GitOps(ArgoCD/Flux)快速恢复。Nginx Ingress也支持--enable-dynamic-configuration实验特性,但生产环境不建议开启。

1.2 Envoy(Contour/Envoy Gateway)的转发

Envoy通过xDS协议(LDS/RDS/CDS)动态获取路由规则,不涉及配置重载或进程重启。在Contour中,路由由HTTPProxy自定义资源定义;在Envoy Gateway中则使用HTTPRoute(Gateway API)。

Contour HTTPProxy示例:

apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: my-app
spec:
  virtualhost:
    fqdn: app.example.com
  routes:
  - conditions:
    - prefix: /api
    services:
    - name: api-service
      port: 80
    pathRewritePolicy:
      replacePrefix:
      - replacement: /
        prefix: /api

Envoy的路径匹配支持精确、前缀、正则三种模式,并通过sort字段控制优先级。动态更新意味着无需重启,但这也带来了配置漂移的风险——如果xDS控制面与Envoy之间的连接中断,Envoy会保留最后一次有效配置,无法自动回退。

风险点:

  • xDS控制面(Contour/Envoy Gateway)本身的稳定性成为单点;
  • 动态配置的调试复杂度高,需要依赖envoy admin接口查看当前路由状态;
  • 对mTLS和RBAC的依赖增加了初始配置门槛。

回滚策略:

Envoy不支持“配置回滚”原生能力。推荐的做法是将所有HTTPProxyHTTPRoute资源纳入Git管理,通过kubectl apply -f previous-version.yaml强制覆写,Envoy会在几秒内感知变化。

二、SSL卸载配置与证书管理

2.1 Nginx Ingress的SSL终结

Nginx Ingress支持TLS终止、Passthrough和双向TLS。最常用的方式是通过tls字段引用Kubernetes Secret中的证书。

spec:
  tls:
  - hosts:
    - app.example.com
    secretName: tls-secret
  rules:
  - host: app.example.com
    ...

证书的自动轮换通常配合cert-manager:创建Certificate资源后,cert-manager会自动更新Secret,但Nginx Ingress不会主动重载配置。你需要额外部署nginx-ingress-cert-reloader或利用ingress-nginx内置的--enable-ssl-chain-completion。另一种做法是使用nginx.ingress.kubernetes.io/auth-tls-secret实现客户端证书验证。

性能考量:

  • Nginx的RSA握手开销较大,建议使用ECDSA证书(如cert-manager签发ECC证书);
  • 会话缓存(ssl_session_cache)默认10MB可支持约40000个会话,可根据并发调整。

安全头配置:

nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/hsts: "true"

注意:全局HSTS可能导致开发环境HTTPS无法降级,建议通过annotation仅对生产域名启用。

2.2 Envoy的TLS卸载与SDS

Envoy通过Secret Discovery Service(SDS)动态管理证书,这是与Nginx最大的区别。在Contour中,你只需引用Kubernetes Secret,Contour会自动将证书通过SDS推送给Envoy。

spec:
  virtualhost:
    fqdn: app.example.com
    tls:
      secretName: tls-secret
      minimumProtocolVersion: "1.2"
    routes:
    ...

Envoy支持真正的证书热切换(无需重启worker),适合证书轮换频繁的场景。但需要注意:SDS依赖xDS控制面的推送能力,如果控制面故障,证书更新会阻塞。

双向TLS(mTLS)配置:

Envoy Gateway下使用ClientTLS资源指定CA证书:

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: secure-route
spec:
  parentRefs:
  - name: my-gateway
  rules:
  - backendRefs:
    - name: svc
      port: 80
  # mTLS 通过 Gateway 的 TLS 策略实现,需额外定义 TLSConfig

由于Envoy对TLS的配置精细度极高(支持ALPN、SNI、OCSP Stapling),建议通过envoy admin/certs端点验证证书生效。若证书过期,Envoy会直接拒绝连接,且不会回退到HTTP。

三、生产环境最佳实践与选型建议

3.1 路由转发:何时选Nginx,何时选Envoy?

  • Nginx Ingress适合传统运维团队、对K8s生态不深度依赖、需要大量自定义Lua脚本的场景。其成熟度高,社区文档丰富,但动态能力薄弱。
  • Envoy(Contour/Gateway)适合微服务架构成熟、需要流量镜像、熔断、分布式追踪等高级功能的团队。Envoy的控制面(如Contour)本身在高并发下的CPU消耗会高于Nginx。

性能对比参考: 在同样配置下,Nginx单worker吞吐量略高于Envoy(约5-10%),但Envoy在连接数超过100K时内存优势明显。实际选择应以POC结果为准。

3.2 SSL卸载:证书管理自动化

无论选择哪种Controller,都应部署cert-manager并采用ClusterIssuer统一管理Let’s Encrypt或内部CA。注意以下几点:

  1. 证书预热:在到期前30天自动更新,避免SDS延迟导致的502;
  2. 回滚要点:如果更新证书后出现SSL握手失败,立即还原Secret(kubectl delete secret xxx && kubectl apply -f backup.yaml),Envoy和Nginx都会在1-2秒内恢复旧证书(Nginx需reload)。
  3. 监控告警:通过Prometheus exporter(如cert-manager-approver)监控证书剩余天数,Endpoint为/metrics中的certmanager_certificate_expiry_timestamp_seconds

3.3 回滚验证清单

任何时候修改路由或SSL配置,都必须准备回滚计划:

  • 备份当前所有Ingress/HTTPProxy YAML(kubectl get ingress -o yaml > backup.yaml);
  • 先在测试环境执行同样的变更;
  • 记录变更时间戳,在监控面板中观察错误率、P99延迟;
  • 如果3分钟内无异常,视为通过;否则执行kubectl apply -f backup.yaml

结语

路由转发与SSL卸载是Ingress Controller最核心的配置项,Nginx的静态模板机制和Envoy的动态xDS代表着两种截然不同的运维哲学。本文给出的配置示例和风险规避方法均可在生产环境直接使用。最终选择应基于团队能力、集群规模以及对动态配置的容忍度。记住:没有银弹,但清晰的回滚路径和监控可以弥补大部分工具短板。

延伸阅读