启用双向TLS与HTTPS端口时Istio VirtualService未被识别
Istio双向TLS环境下VirtualService金丝雀流量拆分失效问题
我们在Kubernetes集群中使用Istio,网格内Pod间通信采用双向TLS(mutual TLS),此前运行正常。现需配置VirtualService实现金丝雀发布的流量切分,已按Istio文档完成配置,但VirtualService未生效——即使设置50/50流量拆分,金丝雀版本仍未收到任何流量。
注:仅涉及网格内部流量,无外部流量,所有通信均在同一命名空间的Pod间进行。
现有配置
业务应用Service(parser-service)
# service parser-service spec: clusterIP: 172.20.181.129 ports: - name: https-web port: 80 protocol: TCP targetPort: 8080 selector: service: parser-service type: ClusterIP
金丝雀版本Service(parser-service-canary)
# service parser-service-canary spec: clusterIP: 172.20.30.101 ports: - name: https-web port: 80 protocol: TCP targetPort: 8080 selector: service: parser-service-canary type: ClusterIP
尝试的50/50流量拆分VirtualService配置
spec: gateways: - mesh hosts: - parser-service tls: - match: - port: 80 sniHosts: - parser-service route: - destination: host: parser-service port: number: 80 weight: 50 - destination: host: parser-service-canary port: number: 80 weight: 50
问题现象
目前流量仍100%路由至parser-service,执行istioctl x describe pod parser-service-xxx-xxx未显示VirtualService,说明规则被忽略:
Pod: parser-service-7cfd596dbb-hjqd9 Pod Revision: 1-14-6 Pod Ports: 8080 (parser-service), 15090 (istio-proxy) Suggestion: add 'version' label to pod for Istio telemetry. -------------------- Service: parser-service Port: https-web 80/HTTPS targets pod port 8080 DestinationRule: istio-mutual for "*.mynamespace.svc.cluster.local" Traffic Policy TLS Mode: ISTIO_MUTUAL -------------------- Effective PeerAuthentication: Workload mTLS mode: PERMISSIVE
我们发现:将端口名改为http-web、VirtualService使用HTTP匹配而非TLS匹配时,流量切分可正常工作,推测问题与端口命名https-web有关。
排查方向与解决方案
1. 端口命名导致的协议推断错误
Istio会根据Service端口名称自动推断协议:
- 端口名包含
https-前缀时,Istio会将该端口识别为应用层HTTPS流量,但实际场景中,Sidecar之间的双向mTLS是透明加密,应用本身的流量是HTTP(targetPort指向8080,应用监听HTTP),因此用VirtualService的tls块匹配并不适用。
2. 修正VirtualService配置(无需修改Service端口名)
直接将VirtualService的tls块替换为http块,适配实际的应用层流量协议:
spec: gateways: - mesh hosts: - parser-service http: - match: - port: 80 route: - destination: host: parser-service port: number: 80 weight: 50 - destination: host: parser-service-canary port: number: 80 weight: 50
3. 显式指定Service端口协议(保留原端口名)
如果需要保留https-web的端口名,可在Service端口配置中显式指定appProtocol: http,纠正Istio的协议推断:
# 修改后的parser-service端口配置 ports: - name: https-web port: 80 protocol: TCP targetPort: 8080 appProtocol: http
金丝雀版本的Service需做同样修改,之后使用上述HTTP类型的VirtualService即可生效。
4. 验证配置有效性
- 执行
istioctl x describe pod <parser-service-pod-name>,检查输出中是否包含VirtualService规则; - 执行
istioctl pc routes <source-pod-name> -o yaml,查看Sidecar的路由配置,确认流量拆分规则已加载。
内容的提问来源于stack exchange,提问作者badger864
相关产品推荐
相关产品推荐

