Istio请求发往错误子集Pod问题排查
Istio 1.16.4中VirtualService流量路由失效问题排查
问题场景
计划对helloworld服务做镜像测试,还未配置镜像规则,却发现v2 Pod收到了流量——流量似乎是由Kubernetes Service直接分发,而非受Istio VirtualService控制。该配置在Istio 1.13.0中可正常限制流量仅到v1,但升级到1.16.4后失效,istioctl检查未发现配置异常。
相关配置
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: helloworld spec: hosts: - helloworld http: - route: - destination: host: helloworld subset: v1 weight: 100 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: helloworld spec: host: helloworld subsets: - name: v1 labels: version: v1 --- apiVersion: v1 kind: Service metadata: name: helloworld labels: app: helloworld service: helloworld spec: selector: app: helloworld ports: - name: http protocol: TCP port: 80 targetPort: 3000 --- apiVersion: apps/v1 kind: Deployment metadata: name: helloworld-v1 labels: app: helloworld version: v1 spec: replicas: 1 selector: matchLabels: app: helloworld version: v1 template: metadata: labels: app: helloworld version: v1 spec: containers: - name: helloworld-v1 image: surprised128/nodetestserver:log ports: - containerPort: 3000 --- apiVersion: apps/v1 kind: Deployment metadata: name: helloworld-v2 labels: app: helloworld version: v2 spec: replicas: 1 selector: matchLabels: app: helloworld version: v2 template: metadata: labels: app: helloworld version: v2 spec: containers: - name: helloworld-v2 image: surprised128/nodetestserver:v2 ports: - containerPort: 3000
测试命令
for i in `seq 1 100`; do curl http://helloworld.connext3.svc.cluster.local/nodejs/hello; done
根因分析
这是Istio 1.14版本引入的默认行为变更导致的:
- 在Istio 1.13及更早版本,当DestinationRule仅定义部分subset时,未匹配到任何subset的Pod会被排除在路由范围外,VirtualService的规则会完全生效。
- 从Istio 1.14开始,默认开启
STRICT_DNS服务解析模式,同时调整了subset匹配逻辑:如果Pod不属于DestinationRule中定义的任何subset,会被归为unknownsubset。而默认情况下,VirtualService若未明确限制unknownsubset的流量,Istio会允许流量路由到这些Pod,最终表现为Kubernetes Service的默认负载均衡逻辑接管了流量分发。
你的DestinationRule只定义了v1 subset,v2 Pod无对应subset配置,因此在1.16.4中被视为unknown subset,VirtualService的100%权重路由v1规则无法拦截这部分流量。
修复方案
有两种可行的修复方式:
方案1:完善DestinationRule的subset配置
将v2的subset也添加到DestinationRule中,即使暂时不路由流量:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: helloworld spec: host: helloworld subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2
此时所有Pod都属于已定义的subset,VirtualService的权重规则会完全生效,流量只会分发到v1。
方案2:启用严格子集匹配模式
在DestinationRule中开启strictSubsetMatching: true,这样Istio只会路由到属于已定义subset的Pod,未匹配的Pod会被排除:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: helloworld spec: host: helloworld strictSubsetMatching: true subsets: - name: v1 labels: version: v1
内容的提问来源于stack exchange,提问作者Mars
相关产品推荐
相关产品推荐

