显式设置协议为何导致Istio基于Header的路由失效?
问题原因
当你给Service端口显式指定HTTP协议后,Istio会把这个端口的流量当成标准HTTP协议处理,这时候原来的VirtualService规则就不满足要求了:
- 未指定协议时,Istio靠协议探测机制识别HTTP流量,此时哪怕VirtualService没绑定端口,也能勉强匹配路由;
- 但显式指定HTTP协议后,Istio会严格校验路由规则的端口关联——你的VirtualService里的
http规则没绑定Service的3011端口,Istio找不到对应的有效路由,就直接把流量透传了(也就是日志里的PassthroughCluster),Header路由自然失效。
修复方法
1. 给VirtualService绑定端口
修改VirtualService,在每个destination节点中添加端口配置,关联Service的3011端口:
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: http-app namespace: default spec: hosts: - http-app.default.svc.cluster.local http: - match: - headers: canary-token: exact: haha route: - destination: host: http-app.default.svc.cluster.local subset: canary port: number: 3011 # 绑定Service的HTTP端口 - route: - destination: host: http-app.default.svc.cluster.local subset: stable port: number: 3011 # 绑定Service的HTTP端口
2. 检查DestinationRule的端口配置
你的DestinationRule必须将每个子集(subset)与Service的3011端口绑定,否则Istio找不到对应的后端实例:
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: http-app namespace: default spec: host: http-app.default.svc.cluster.local subsets: - name: stable labels: version: stable port: number: 3011 - name: canary labels: version: canary port: number: 3011
3. 应用配置并验证
执行命令更新配置:
kubectl apply -f virtualservice.yaml kubectl apply -f destinationrule.yaml
再用携带canary-token: haha头的请求测试,查看日志是否恢复为outbound|3011|canary|http-app.default.svc.cluster.local的路由状态。
额外说明
- Istio识别协议的两种方式:一是端口名符合
http-*、https-*格式,二是通过appProtocol字段指定; - 未指定协议时的“兼容生效”是Istio协议探测机制的临时效果,生产环境务必明确指定协议和端口绑定;
allow_any与PassthroughCluster都是Istio找不到匹配路由时的透传行为,此时所有路由规则都会失效。
内容的提问来源于stack exchange,提问作者blastz
相关产品推荐
相关产品推荐

