Service Mesh mTLS 灰度:安全策略别一刀切上线
Service Mesh 落地时,mTLS 是高频诉求:服务间通信加密、身份认证、零信任。听起来很正,但生产环境最怕一刀切。mTLS 开关一开,旧服务、外部依赖、健康检查、批任务、跨命名空间调用都可能炸。安全策略要灰度,不要把全链路当实验场。
mTLS 上线的核心不是“开”,而是知道谁支持、谁不支持、谁必须例外、谁需要迁移窗口。
一、先盘点服务通信矩阵
flowchart TD A[Namespace A] --> B[Service B] A --> C[Legacy Service] B --> D[Database Proxy] C --> E[External API] F[Batch Job] --> B服务网格不是只管在线服务。CronJob、一次性迁移任务、外部回调、探针流量都要算进去。漏掉一个调用方,就可能在开启 STRICT 模式后直接 503。
二、从 PERMISSIVE 到 STRICT
Istio 里常见做法是先用 PERMISSIVE,让明文和 mTLS 都能通,再逐步切到 STRICT。
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: payments spec: mtls: mode: PERMISSIVE先观测真实流量,确认调用方都已经注入 sidecar 或支持 mTLS,再对小范围服务切 STRICT。别全命名空间一步到位。
三、用指标确认迁移状态
安全策略上线不能靠感觉。要看明文流量比例、mTLS 成功率、认证失败、目标服务 5xx。
sum(rate(istio_requests_total{connection_security_policy="mutual_tls"}[5m])) by (destination_service) sum(rate(istio_requests_total{response_code=~"4..|5.."}[5m])) by (destination_service) sum(rate(istio_tcp_connections_closed_total[5m])) by (destination_workload)如果某个服务明文流量长期存在,要查调用方是不是没注入 sidecar、是不是外部服务、是不是探针或批任务。
四、例外策略要有过期时间
生产里一定会有例外,但例外不能永久躺着。每个例外都要有 owner、原因和过期时间。
mtls_exception: service: legacy-report-worker reason: "runtime does not support sidecar yet" owner: "platform-team" expires_at: "2026-07-20" migration_plan: "move to mesh compatible base image"安全治理最怕“临时例外”变成永久后门。到期不处理,就应该进入风险清单。
五、总结
Service Mesh mTLS 要灰度上线:先盘点通信矩阵,再从 PERMISSIVE 观测到 STRICT,配合指标确认迁移状态,对例外设置 owner 和过期时间。
安全策略不是越猛越好,而是要稳稳进入生产路径。mTLS 的目标是提高系统安全性,不是制造一批没人看得懂的 503。