在信创改造的大背景下,越来越多的企业把业务系统迁移到中标麒麟等国产操作系统上,同时也在积极引入云原生技术栈。Istio作为主流的服务网格方案,其流量镜像(mirroring)能力可以在生产环境安全地验证新版本服务:真实流量被复制一份发往镜像服务,而镜像服务的响应会被丢弃,不会对线上调用方产生任何干扰。本文将结合中标麒麟系统环境,完整讲解Istio流量镜像的原理与落地配置。

一、流量镜像的工作原理
Istio的流量镜像本质上依赖Envoy代理的shadowing能力。当请求经过Sidecar时,Envoy除了把请求转发给主目标服务之外,还会异步复制一份相同的请求发送到镜像集群,整个过程对调用方完全透明。
需要特别理解的一点是:镜像请求的响应会被Envoy直接丢弃。也就是说,即使镜像服务返回错误甚至直接崩溃,原始请求的返回结果也不会受任何影响。这使得镜像非常适合用来做新版本的真实压力验证,比如在灰度发布前观察新版本在真实流量下的表现。
另外,镜像流量默认是在fire-and-forget模式下发送的,即发送即忘。如果镜像集群响应过慢或队列堆积,理论上存在一定的资源占用风险,因此在生产中启用镜像时,建议对镜像服务的容量做一定评估,并配合mirror_percentage字段控制镜像比例。
二、中标麒麟环境下的准备与安装
中标麒麟(如V7、V10版本)基于Linux内核,对Kubernetes和Istio的兼容性较好。在开始之前,确保已经有一套可用的Kubernetes集群,且集群节点操作系统均为中标麒麟,节点上已正确配置容器运行时。可以通过以下命令确认环境状态:
# 确认系统版本 cat /etc/kylin-release # 确认Kubernetes节点状态 kubectl get nodes -o wide # 确认默认命名空间是否已开启Sidecar自动注入 kubectl get namespace default --show-labels
如果还没有安装Istio,可以使用istioctl进行安装。建议下载与集群版本匹配的Istio发行版,解压后将其中的istioctl二进制文件加入PATH。由于中标麒麟默认可能没有配置外网代理,下载安装包时可以在有网络的机器上先获取再传入内网。
# 安Istio演示配置档,适合测试验证 istioctl install --set profile=demo -y # 为default命名空间开启自动Sidecar注入 kubectl label namespace default istio-injection=enabled
安装完成后,通过kubectl get pods -n istio-system检查istiod等相关Pod是否全部Running,这是后续流量镜像能生效的前提条件。
三、部署示例服务并配置流量镜像
接下来部署两个版本的服务作为演示:v1代表当前线上稳定版本,v2代表待验证的新版本。先创建Deployment与Service:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-v1
spec:
replicas: 1
selector:
matchLabels:
app: demo
version: v1
template:
metadata:
labels:
app: demo
version: v1
spec:
containers:
- name: app
image: ipipp.com/demo/httpbin:v1
ports:
- containerPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-v2
spec:
replicas: 1
selector:
matchLabels:
app: demo
version: v2
template:
metadata:
labels:
app: demo
version: v2
spec:
containers:
- name: app
image: ipipp.com/demo/httpbin:v2
ports:
- containerPort: 8080
核心配置在于VirtualService中的mirror字段。下面的配置会把发往v1的所有流量100%镜像到v2:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: demo-vs
spec:
hosts:
- demo-svc
http:
- route:
- destination:
host: demo-svc
subset: v1
weight: 100
mirror:
host: demo-svc
subset: v2
mirror_percentage:
value: 100.0
同时需要配套一个DestinationRule来定义subset,将不同版本的Pod通过标签区分开来。如果只需要小比例验证,可以将mirror_percentage的值调低,例如设为10.0,表示只镜像一成流量,降低镜像服务的负载压力。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: demo-dr
spec:
host: demo-svc
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
四、验证镜像效果与常见问题排查
配置生效后,可以从一个注入了Sidecar的客户端Pod发起请求,然后分别查看v1和v2两个Pod的日志。如果两个版本都收到了请求,说明镜像已经正常工作:
# 从客户端Pod发起请求 kubectl exec -it client-pod -- curl -s http://demo-svc/api # 分别查看两个版本的访问日志 kubectl logs deploy/app-v1 --tail=5 kubectl logs deploy/app-v2 --tail=5
排查时常见的坑主要有几个方面。第一,客户端Pod必须注入了Sidecar,否则流量根本不经过Envoy,镜像自然不会发生,可以通过istioctl proxy-status或查看Pod中是否包含istio-proxy容器来确认。第二,镜像请求的Host头部保持原始值,如果镜像服务的路由规则依赖不同的Host,可能会匹配失败。第三,在中标麒麟上如果启用了系统级防火墙,注意放行Istio控制面与数据面相关端口,避免Sidecar之间的通信被拦截。
最后补充一点实践建议:镜像服务最好是无副作用或可容忍重复写入的,因为同一请求会被处理两次。如果服务中存在下单、扣款这类写操作,需要在上游增加幂等性保护或通过请求头标记来区分镜像流量,这样才能安全地发挥流量镜像在新版本验证中的价值。通过这套流程,在中标麒麟加Istio的组合环境下,就能低成本地把真实生产流量引入新版本进行充分验证,为灰度发布保驾护航。
中标麒麟Istiomirroring流量镜像修改时间:2026-09-02 08:48:31