EKS集群中Istio经典负载均衡器的子域名TCP路由未按预期工作问题排查
问题分析与解决方案
从你的配置和现象来看,主要存在两个关键问题导致TCP路由不符合预期:
1. VirtualService资源名称重复
你在default命名空间下创建了两个同名的VirtualService(metadata.name: sv1),Kubernetes中同一命名空间内的资源名称必须唯一。当你创建第二个同名的VirtualService时,它会覆盖掉第一个的配置。结合你反馈的"所有流量都路由到svc1"来看,大概率是你先创建了对应b.example.com的VirtualService,之后又创建了对应a.example.com的,最终只有a.example.com的规则保留,导致所有流量都匹配到这条路由。
2. TCP路由未配置SNI识别
TCP协议本身没有HTTP的Host头来区分域名,Istio要实现基于子域名的TCP路由,必须依赖**TLS SNI(Server Name Indication)**来识别目标主机。你当前的Gateway配置中,TCP server没有启用TLS透传模式,Istio无法解析SNI信息,因此无法区分a.example.com和b.example.com的流量,只能匹配到第一条可用的路由规则,进而全部导向svc1。
修正后的配置
第一步:调整Gateway,启用TLS PASSTHROUGH
修改Gateway的TCP server配置,添加tls: mode: PASSTHROUGH,让Istio透传TLS流量并解析SNI:
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: my-gateway namespace: default spec: selector: istio: ingressgateway servers: - port: number: 9999 name: aa protocol: TCP tls: mode: PASSTHROUGH # 新增:启用TLS透传,解析SNI hosts: - "a.example.com" - "b.example.com"
第二步:修正VirtualService名称,确保唯一
将第二个VirtualService的名称改为sv2,避免同命名空间下资源冲突:
# 对应a.example.com的VirtualService apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: sv1 namespace: default spec: hosts: - "a.example.com" gateways: - my-gateway tcp: - route: - destination: host: svc1 port: number: 8000 weight: 100 --- # 对应b.example.com的VirtualService,修改名称为sv2 apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: sv2 # 修改此处名称 namespace: default spec: hosts: - "b.example.com" gateways: - my-gateway tcp: - route: - destination: host: svc2 port: number: 8000 weight: 100
验证步骤
- 应用修正后的配置:
kubectl apply -f your-updated-config.yaml - 检查VirtualService是否都正常存在:
应该能看到kubectl get virtualservice -n defaultsv1和sv2两个资源。 - 分别测试
a.example.com:9999和b.example.com:9999的流量,确认各自路由到对应的服务。
内容的提问来源于stack exchange,提问作者MM010
相关产品推荐
相关产品推荐

