配置Istio:终止TLS后使用新HTTPS连接访问外部服务
Istio流量分流配置问题:内部服务转发+外部服务HTTPS发起
需求场景
我有一个VirtualService,需要基于HTTP路由前缀,在内部Service和外部ServiceEntry之间分流流量,其中外部服务要求接收HTTPS流量。
测试命令
使用以下curl命令验证路由:
curl https://my-service.domain.com/internal-route -> 应转发至内部服务 curl https://my-service.domain.com/external-route -> 应转发至外部服务
已尝试的配置方案
方案1:内部、外部服务均使用HTTP路由
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService spec: gateways: - ... hosts: - my-service.domain.com http: - match: - uri: prefix: /internal-route route: - destination: host: my-service.my-ns.svc.cluster.local - match: - uri: prefix: /external-route route: - destination: host: external-service.otherdomain.com --- apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry spec: hosts: - external-service.otherdomain.com ports: - number: 443 name: https protocol: HTTP location: MESH_EXTERNAL resolution: DNS
问题:外部服务反馈其443端口收到HTTP流量,因为Istio终止TLS后以HTTP转发请求。
方案2:内部用HTTP路由,外部用TLS匹配类型
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService spec: gateways: - ... hosts: - my-service.domain.com http: - match: - uri: prefix: /internal-route route: - destination: host: my-service.my-ns.svc.cluster.local tls: - match: - port: 443 sniHosts: - my-service.domain.com route: - destination: host: external-service.otherdomain.com --- apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry spec: hosts: - external-service.otherdomain.com ports: - number: 443 name: https protocol: TLS location: MESH_EXTERNAL resolution: DNS
问题:访问外部服务路由时Istio返回HTTP 404错误。
方案3:同方案2,但ServiceEntry的protocol设为HTTP
问题:未解决上述问题。
核心疑问
如何配置Istio,使其终止TLS连接后,通过新的HTTPS连接向外部服务发送流量?
补充尝试(编辑1)
参考Istio文档后尝试添加DestinationRule,但无效果:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: tls-foo spec: host: external-service.otherdomain.com trafficPolicy: portLevelSettings: - port: number: 80 tls: mode: SIMPLE
正确配置方案
要实现终止TLS后发起新的HTTPS连接到外部服务,需要调整以下配置:
1. 修正VirtualService配置
保持HTTP路由匹配前缀,同时确保外部服务的路由指向正确的ServiceEntry:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: my-service-vs spec: gateways: - your-gateway-name # 替换为实际网关名称 hosts: - my-service.domain.com http: - match: - uri: prefix: /internal-route route: - destination: host: my-service.my-ns.svc.cluster.local port: number: 80 # 内部服务的HTTP端口,根据实际调整 - match: - uri: prefix: /external-route route: - destination: host: external-service.otherdomain.com port: number: 443 # 外部服务的HTTPS端口
2. 修正ServiceEntry配置
将协议设为HTTP,因为Istio需要解析HTTP流量来匹配路由,后续通过DestinationRule发起TLS:
apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: external-service-se spec: hosts: - external-service.otherdomain.com ports: - number: 443 name: https protocol: HTTP location: MESH_EXTERNAL resolution: DNS
3. 正确配置DestinationRule
指定对外部服务的443端口启用SIMPLE TLS模式,让Istio发起HTTPS连接:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: external-service-dr spec: host: external-service.otherdomain.com trafficPolicy: portLevelSettings: - port: number: 443 tls: mode: SIMPLE # 若外部服务使用自定义证书,可添加以下配置 # clientCertificate: /path/to/client-cert # privateKey: /path/to/client-key # caCertificates: /path/to/ca-cert
配置说明
- VirtualService通过HTTP前缀匹配流量,分别转发到内部服务和外部ServiceEntry
- ServiceEntry将外部服务的443端口注册为HTTP协议,允许Istio处理HTTP路由逻辑
- DestinationRule告诉Istio,当流量发往外部服务的443端口时,发起新的TLS连接(SIMPLE模式),从而将HTTP流量封装为HTTPS发送给外部服务
内容的提问来源于stack exchange,提问作者GreenGiant
相关产品推荐
相关产品推荐

