引言:路由转发与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资源中的rules和annotations定义转发行为。其底层工作原理是: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不支持“配置回滚”原生能力。推荐的做法是将所有HTTPProxy或HTTPRoute资源纳入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。注意以下几点:
- 证书预热:在到期前30天自动更新,避免SDS延迟导致的502;
- 回滚要点:如果更新证书后出现SSL握手失败,立即还原Secret(
kubectl delete secret xxx && kubectl apply -f backup.yaml),Envoy和Nginx都会在1-2秒内恢复旧证书(Nginx需reload)。 - 监控告警:通过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代表着两种截然不同的运维哲学。本文给出的配置示例和风险规避方法均可在生产环境直接使用。最终选择应基于团队能力、集群规模以及对动态配置的容忍度。记住:没有银弹,但清晰的回滚路径和监控可以弥补大部分工具短板。
延伸阅读
