报错是这么冒出来的。Istio 1.22 用 VirtualService 按 header x-canary 把流量切到 v2,灰度一小时发现 v2 承接了七成请求,日志里绝大部分请求根本没有这个 header。

中间走过弯路,把「网格外的调用方经过 ingress 后 header 被丢弃」当成主因,改完现象没变。

排查方向其实有限,先把可能性排一排。匹配规则只写了 header 精确匹配,没有默认路由兜底。另一种情况是路由顺序里 v2 规则写在前面且未设置权重。

不容易想到的是,sidecar 版本不一致,部分 Pod 用了旧的路由配置。

动手时先看实际到达的请求带了哪些 header

kubectl logs deploy/ingress -c istio-proxy | grep -o 'x-canary[^ ]*' | sort | uniq -c

接着导出 VirtualService 确认规则顺序

kubectl get vs app -o yaml

补一条默认路由指向 v1 并设权重 100

kubectl apply -f vs-canary.yaml && kubectl get vs app -o jsonpath='{.spec.http[*].route}'

剩下的就是用带 header 与不带 header 各发一次验证

curl -H 'x-canary: true' http://app/api/ver && curl http://app/api/ver

怎么算真的好了,看的是同一批现象。不带 header 的请求全部落到 v1,带 header 的落到 v2,两侧日志里的版本标识与预期一致。

补一句。灰度规则必须有默认分支,header 匹配只覆盖少数流量,剩下没有匹配的请求会按顺序落到第一条路由上。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189