TLS Origination(TLS 发起)是服务网格中一项非常实用却经常被误解的能力。简单来说,它指的是:应用以明文 HTTP 的方式发起请求,Sidecar 代理(如 Envoy)拦截到这条出口流量后,代替应用与外部服务完成 TLS 握手,将流量加密后再发送出去。这样应用代码完全不需要感知 TLS 的存在,也不需要管理证书,出口链路上的数据却已经是加密状态。本文将以 Istio 为例,在 Kubernetes 环境下完整讲解 TLS Origination 的配置方法、常见变体以及踩坑排查。

一、TLS Origination 与 TLS Termination 到底有什么区别
这两个术语名字相近,方向却完全相反,理解它们的区别是正确配置的前提。TLS Termination(TLS 终止)处理的是进入网格的流量:外部客户端以 HTTPS 方式访问网格内的服务,入口网关或 Sidecar 在边界处把 TLS 解开,后续网格内部通信可以继续使用明文或由网格自动加密。而 TLS Origination 处理的是离开网格的流量:网格内的应用以明文 HTTP 发起请求,Sidecar 在出口处把流量升级为 TLS。
用一张对比表可以更清晰地说明差异:
| 维度 | TLS Termination | TLS Origination |
|---|---|---|
| 流量方向 | 入站流量 | 出站流量 |
| 配置位置 | 通常是 Ingress Gateway 或服务端 Sidecar | 客户端 Sidecar(通过 DestinationRule) |
| 加密行为 | 解密进入的 TLS 流量 | 加密发出的明文流量 |
| 典型场景 | 对外暴露 HTTPS 服务 | 安全访问外部 HTTPS API |
需要特别注意的是,这两种能力可以组合使用:入口处 Termination、出口处 Origination,中间由网格的 mTLS 保证,从而形成一条端到端可审计的加密链路。
二、基础配置:将 HTTP 出口流量升级为 HTTPS
TLS Origination 的核心配置在 DestinationRule 中,通过 tls.mode 字段指定 TLS 模式为 ISTIO_MUTUAL 或 SIMPLE。当目标是网格外的普通 HTTPS 服务时,通常使用 SIMPLE 模式,即单向 TLS。为了让 Istio 识别外部服务,一般还需要配合 ServiceEntry 把外部主机纳入网格的服务注册表。
先看 ServiceEntry 的定义,将外部域名 api.ipipp.com 注册进网格:
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: external-api
spec:
hosts:
- api.ipipp.com
ports:
- number: 80
name: http-port
protocol: HTTP
- number: 443
name: https-port
protocol: HTTPS
resolution: DNS接着配置 DestinationRule,指定对 80 端口的访问使用 TLS 发起,Sidecar 会将流量转发到目标服务的 443 端口:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: external-api-tls
spec:
host: api.ipipp.com
trafficPolicy:
portLevelSettings:
- port:
number: 80
tls:
mode: SIMPLE这两个资源应用之后,应用容器内只需要发起普通的 HTTP 请求,例如访问 http://api.ipipp.com/api/data,Sidecar 会自动完成 DNS 解析、TCP 建连、TLS 握手,最终以 HTTPS 形式将请求送达目标服务。这种方式的最大优势在于零代码改造:对于那些年代久远、不支持 HTTPS 客户端库的遗留应用,只要部署进网格就能获得出口加密能力。
三、进阶场景:Sidecar 与目标端口都使用 TLS
上面的配置中存在一个小细节:应用到 Sidecar 之间仍是明文,Sidecar 到外部服务之间才是 TLS。如果应用本身直连的是目标的 TLS 端口(例如直接访问 https://api.ipipp.com),Istio 默认会直接透传 TLS 流量,此时流量经过 Sidecar 但是是密文,Istio 无法基于 HTTP 层做路由和监控。为了在应用与 Sidecar 之间也使用 TLS,并且让 Sidecar 解密后重新加密发出,可以将端口协议声明为 TLS,并配合 DestinationRule 处理。
另一种常见的进阶用法是双向 TLS 的出口发起。某些企业内部服务要求客户端证书认证,此时需要使用 MUTUAL 模式并挂载客户端证书。证书建议通过 Kubernetes Secret 挂载到 Sidecar 可访问的路径,例如:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: internal-mtls-service
spec:
host: internal-service.corp.local
trafficPolicy:
tls:
mode: MUTUAL
clientCertificate: /etc/certs/cert.pem
privateKey: /etc/certs/key.pem
caCertificates: /etc/certs/ca.pem配置 MUTUAL 模式后,Sidecar 在与目标服务握手时会主动出示客户端证书,完成双向认证。证书到期前需要及时轮换,可以借助 cert-manager 或外部密钥管理系统自动化这个过程,避免因证书过期导致出口流量全部失败。
四、常见问题与排查思路
开启 TLS Origination 后最常见的问题是连接突然失败。典型表现是:配置前应用可以正常访问外部服务,配置后返回 503 或者上游连接重置。排查时首先确认 ServiceEntry 中的端口协议声明是否正确:如果目标实际提供 TLS 服务,但端口协议被声明为 HTTP,Sidecar 会以明文形式与一个期望 TLS 握手的端口通信,目标直接重置连接。此时可以将协议改为 HTTPS,或在 DestinationRule 中正确配置 tls 模式。
第二个常见问题是与网格内 mTLS 策略冲突。如果命名空间开启了 PeerAuthentication 的 STRICT 模式,同时 DestinationRule 又对内部服务配置了 SIMPLE 模式的 TLS,两套 TLS 会叠加导致握手失败。原则是:网格内部服务交给 Istio 的 mTLS 处理,DestinationRule 中的 tls 配置只应用于网格外的目标主机。排查时可以使用 istioctl proxy-config 命令查看 Sidecar 实际生效的监听器和集群配置:
# 查看指定 Pod 的出口监听器配置 istioctl proxy-config listener <pod-name>.<namespace> --address 0.0.0.0 -o json # 查看集群配置,确认 TLS 上下文是否生效 istioctl proxy-config cluster <pod-name>.<namespace> --fqdn api.ipipp.com
最后还需要留意 SNI 与 Host 头的一致性问题。TLS Origination 场景下,Sidecar 发起握手时使用的 SNI 来自原始请求的 Host 头。如果目标服务基于 SNI 做虚拟主机路由,而应用请求的 Host 与证书域名不一致,握手阶段就会失败。解决办法是在 ServiceEntry 中确保 hosts 与实际访问域名完全一致,必要时通过 VirtualService 做请求头的重写。
总结来说,TLS Origination 通过将加密能力下沉到基础设施层,让应用无需关心证书和 TLS 细节就能实现出口流量加密。掌握 DestinationRule 的 tls 配置、ServiceEntry 的协议声明,以及常见冲突的排查方法,就能在 Kubernetes 服务网格中安全可控地管理所有出口流量。
服务网格TLS Origination出口流量加密修改时间:2026-09-01 02:50:51