Shadow Traffic Tester
配置影子(暗)流量镜像以测试新服务版本对真实生产流量的影响,而不影响用户。生产请求被复制到影子服务,响应被捕获并与原始服务进行比较,以检测行为差异、延迟回归和错误率变化。该技能涵盖了基于Istio的镜像、Nginx镜像模块和自定义代理级解决方案。
使用时: "影子流量"、"暗流量测试"、"镜像流量"、"流量镜像"、"比较服务版本"、"影子部署"、"金丝雀比较"
命令
设置基础设施以将实时流量镜像到影子服务版本。
步骤 1 -- 确定服务网格/入口控制器
检测流量管理层
echo "=== 检查Istio ==="
kubectl get crd virtualservices.networking.istio.io 2>/dev/null && echo "Istio检测到" || echo "没有Istio"
echo ""
echo "=== 检查Nginx入口 ==="
kubectl get ingressclass -o jsonpath='{.items[*].metadata.name}' 2>/dev/null | grep -q nginx && echo "Nginx入口检测到" || echo "没有Nginx入口"
echo ""
echo "=== 检查Linkerd ==="
kubectl get crd serviceprofiles.linkerd.io 2>/dev/null && echo "Linkerd检测到" || echo "没有Linkerd"
echo ""
echo "=== 检查Envoy Gateway ==="
kubectl get crd gateways.gateway.networking.k8s.io 2>/dev/null && echo "Gateway API检测到" || echo "没有Gateway API"
步骤 2a -- Istio镜像配置
# 部署影子版本与生产版本并行
SERVICE_NAME="${1:-my-service}"
SHADOW_VERSION="${2:-v2}"
NAMESPACE="${3:-default}"
cat << 'ISTIOEOF'
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: {SERVICE_NAME}-mirror
namespace: {NAMESPACE}
spec:
hosts:
- {SERVICE_NAME}
http:
- route:
- destination:
host: {SERVICE_NAME}
subset: production
weight: 100
mirror:
host: {SERVICE_NAME}
subset: shadow
mirrorPercentage:
value: 100.0
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: {SERVICE_NAME}-versions
namespace: {NAMESPACE}
spec:
host: {SERVICE_NAME}
subsets:
- name: production
labels:
version: v1
- name: shadow
labels:
version: {SHADOW_VERSION}
ISTIOEOF
步骤 2b -- 基于Nginx的镜像(无服务网格)
对于没有服务网格的集群,使用侧车代理方法:
cat << 'NGINXEOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: shadow-mirror-config
data:
nginx.conf: |
upstream production {
server {SERVICE_NAME}.{NAMESPACE}.svc.cluster.local:80;
}
upstream shadow {
server {SERVICE_NAME}-shadow.{NAMESPACE}.svc.cluster.local:80;
}
server {
listen 8080;
location / {
proxy_pass http://production;
mirror /mirror;
mirror_request_body on;
}
location = /mirror {
internal;
proxy_pass http://shadow$request_uri;
proxy_set_header X-Shadow-Request "true";
# 影子响应被丢弃
}
}
NGINXEOF
步骤 3 -- 部署影子服务
# 克隆生产部署并添加影子标签
kubectl get deployment "$SERVICE_NAME" -n "$NAMESPACE" -o json | python3 -c "
import json, sys
deploy = json.load(sys.stdin)
# 修改影子部署
deploy['metadata']['name'] += '-shadow'
deploy['metadata'].pop('resourceVersion', None)
deploy['metadata'].pop('uid', None)
deploy['metadata'].pop('creationTimestamp', None)
deploy['metadata']['labels']['version'] = 'shadow'
deploy['metadata']['labels']['traffic-role'] = 'shadow'
deploy['spec']['selector']['matchLabels']['version'] = 'shadow'
deploy['spec']['template']['metadata']['labels']['version'] = 'shadow'
deploy['spec']['template']['metadata']['labels']['traffic-role'] = 'shadow'
# 设置影子镜像
for c in deploy['spec']['template']['spec']['containers']:
c['image'] = c['image'].rsplit(':', 1)[0] + ':shadow'
# 减少影子副本(只需要处理,不需要服务)
deploy['spec']['replicas'] = max(1, deploy['spec'].get('replicas', 1) // 2)
print(json.dumps(deploy, indent=2))
" | kubectl apply -f -
步骤 4 -- 验证镜像是否激活
# 检查影子Pod是否接收流量
echo "=== 影子Pod日志(最后20行) ==="
kubectl logs -l traffic-role=shadow -n "$NAMESPACE" --tail=20 2>/dev/null
# 如果使用Istio,检查Envoy统计
echo ""
echo "=== Istio镜像统计 ==="
kubectl exec -n "$NAMESPACE" deploy/"$SERVICE_NAME" -c istio-proxy -- \
pilot-agent request GET stats 2>/dev/null | grep -i mirror || echo "没有Istio代理统计可用"
报告模板:
影子流量设置报告
配置
- 服务:{SERVICE_NAME}
- 名称空间:{NAMESPACE}
- 镜像方法:{Istio/Nginx/Custom}
- 镜像百分比:{100}%
- 影子镜像:{image:tag}
状态
- 影子Pod运行:{N}
- 镜像配置应用:{yes/no}
- 流量到达影子:{yes/no/pending}