istio 流量镜像不是录制,而是实时复制请求到另一服务端点,原响应不受影响,镜像响应被丢弃;它不保存请求体、不回放、不支持断点续录,本质是单向旁路转发。

什么是 Istio 流量镜像,它真能“录制”生产流量?
不能。Istio 的 mirror 不是录制,而是实时复制请求到另一个服务端点,原请求响应不受影响,镜像请求的响应被丢弃。它不保存请求体、不回放、不支持断点续录——本质是单向旁路转发,不是“流量录制系统”。如果你需要存下来后续重放(比如压测或调试),得在镜像目标服务里自己实现接收、解析、落盘逻辑。
如何用 VirtualService 配置 Go 服务的镜像流量?
核心是设置 mirror 和 mirrorPercentage,注意:镜像目标必须是同一网格内的服务(DNS 可解析,Sidecar 注入正常),且目标服务不需要特殊改造,但得能接收并处理镜像来的 HTTP/HTTPS 请求。
-
mirror字段填目标服务的短名(如"traffic-mirror"),不是完整域名;Istio 会自动补上命名空间和 .svc.cluster.local - 必须显式指定
mirrorPercentage,哪怕设为 100;不写就默认 0%,即不镜像 - 镜像请求的
Host头保持原样,但X-Forwarded-For和X-Request-ID会被重写,原请求的 trace ID 不会透传到镜像服务 - Go 服务若用
net/http默认 handler,需额外读取Body并提前io.Copy(ioutil.Discard, r.Body),否则镜像请求可能卡住(因为 Istio 不等待镜像响应)
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: mirror-go-service
spec:
hosts:
- "api.example.com"
http:
- route:
- destination:
host: go-service
mirror:
host: traffic-mirror
mirrorPercentage:
value: 10.0为什么镜像流量没进到你的 Go 接收服务?常见断点排查
90% 的失败不是配置错,而是网络或 Sidecar 拦截问题。重点查这四点:
- Istio 控制面是否已同步:执行
kubectl get virtualservice mirror-go-service -o yaml,确认status下没有Errors字段 - 目标服务
traffic-mirror是否注入了 Sidecar?kubectl get pod -l app=traffic-mirror -o wide看容器数是否为 2 - Go 服务监听地址是否绑定
0.0.0.0:8080而非127.0.0.1:8080?镜像请求来自集群内其他节点,localhost 绑定会拒绝 - 是否开了 mTLS?如果源服务和镜像服务启用了 STRICT mTLS,而
traffic-mirror没配对等证书,镜像请求会在入口 Sidecar 就被拦截,日志里搜"no client certificate found"
Go 服务怎么安全接收并保存镜像请求?
别直接用主业务 handler 复用逻辑。镜像流量是“影子”,不应触发真实 DB 写入、发消息、调第三方 API。建议独立 endpoint + 显式标记:
立即学习“go语言免费学习笔记(深入)”;
- 加专用路由,比如
POST /_mirror/receive,避免和业务路径混淆 - 从
X-Istio-Attribute或自定义 header(如X-Mirror-Src)识别镜像来源,拒绝非镜像流量访问该 endpoint - 用
io.ReadAll(r.Body)读完原始 body 后立刻保存为 JSON 文件或发到 Kafka,不要做任何业务校验或状态变更 - 务必设超时:
http.Server{ReadTimeout: 5 * time.Second, WriteTimeout: 5 * time.Second},防止镜像积压拖垮主服务
容易被忽略的是:Istio 镜像不保证顺序、不重试、不保障送达。一次 503 或超时,那条请求就丢了——它本来就不是为可靠传输设计的。











