流量拆分
流量拆分是 Istio 最强大的功能之一,无需更改代码即可实现 Canary 部署、A/B 测试和 Blue/Green 部署。
目录
流量拆分概述
流量拆分使用 VirtualService 中的 weight 字段,按比例在多个 Service 版本之间分配流量。
基本结构
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 90 # 90% of traffic
- destination:
host: reviews
subset: v2
weight: 10 # 10% of trafficCanary 部署
Canary 部署是一种先仅向少量用户部署新版本以安全验证的策略。将 Argo Rollouts 与 Istio 搭配使用,可实现自动化渐进式部署和基于指标的自动回滚。
Argo Rollouts + Istio 架构
Canary 部署流程
步骤 1:安装 Argo Rollouts
# Install Argo Rollouts
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
# Install Argo Rollouts CLI (optional)
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64
chmod +x kubectl-argo-rollouts-linux-amd64
sudo mv kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
# Run Argo Rollouts Dashboard
kubectl argo rollouts dashboard步骤 2:定义 Rollout 资源
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: reviews
namespace: default
spec:
replicas: 5
revisionHistoryLimit: 2
selector:
matchLabels:
app: reviews
template:
metadata:
labels:
app: reviews
istio-injection: enabled
spec:
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v2:1.17.0
ports:
- containerPort: 9080
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
# Canary Deployment Strategy
strategy:
canary:
# Traffic Control via Istio VirtualService
trafficRouting:
istio:
virtualService:
name: reviews-vsvc
routes:
- primary
destinationRule:
name: reviews-destrule
canarySubsetName: canary
stableSubsetName: stable
# Canary Steps Definition
steps:
- setWeight: 10 # 10% traffic to Canary
- pause:
duration: 2m # Wait 2 minutes
- setWeight: 25 # 25% traffic to Canary
- pause:
duration: 2m
- setWeight: 50 # 50% traffic to Canary
- pause:
duration: 2m
- setWeight: 75 # 75% traffic to Canary
- pause:
duration: 2m
# Automatic Metric Analysis
analysis:
templates:
- templateName: success-rate
- templateName: latency
startingStep: 1 # Start analysis from first step
args:
- name: service-name
value: reviews步骤 3:创建 Service
首先,创建 Kubernetes Service:
apiVersion: v1
kind: Service
metadata:
name: reviews
namespace: default
spec:
ports:
- port: 9080
name: http
selector:
app: reviews # Select all Pods from Rollout步骤 4:定义 VirtualService
重要:Argo Rollouts 不会自动修改 VirtualService。必须预先创建 VirtualService,而 Rollout 仅引用它来更新权重。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-vsvc
namespace: default
spec:
hosts:
- reviews
http:
- name: primary # Route name referenced by Rollout (required)
route:
- destination:
host: reviews
subset: stable # Stable version
weight: 100
- destination:
host: reviews
subset: canary # Canary version
weight: 0要点:
http[].name字段是必需的(与 Rollout 的routes字段匹配)- Rollout 只会自动更新此 VirtualService 的
weight值 - 需要两个目标:stable 和 canary
步骤 5:定义 DestinationRule
重要:Argo Rollouts 不会自动创建 DestinationRule。必须预先创建它。
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: reviews-destrule
namespace: default
spec:
host: reviews
subsets:
- name: stable
labels:
# Label automatically added by Rollout
# rollouts-pod-template-hash: <stable-hash>
- name: canary
labels:
# Label automatically added by Rollout
# rollouts-pod-template-hash: <canary-hash>要点:
- 子集名称(
stable、canary)必须与 Rollout 的stableSubsetName和canarySubsetName匹配 - Rollout 会自动将
rollouts-pod-template-hash标签添加到 Pod - DestinationRule 子集根据此标签选择 Pod
- 保持标签选择器为空——Rollout 会在运行时管理它们
步骤 6:定义 AnalysisTemplate
成功率分析
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
namespace: default
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 30s
count: 4 # 4 measurements (total 2 minutes)
successCondition: result >= 0.95 # 95% or higher success rate
failureLimit: 2 # Rollback after 2 failures
provider:
prometheus:
address: http://prometheus.istio-system:9090
query: |
sum(rate(
istio_requests_total{
destination_service_name="{{args.service-name}}",
destination_workload_namespace="default",
response_code!~"5.*"
}[2m]
))
/
sum(rate(
istio_requests_total{
destination_service_name="{{args.service-name}}",
destination_workload_namespace="default"
}[2m]
))延迟分析
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: latency
namespace: default
spec:
args:
- name: service-name
metrics:
- name: latency-p95
interval: 30s
count: 4
successCondition: result <= 500 # P95 latency 500ms or less
failureLimit: 2
provider:
prometheus:
address: http://prometheus.istio-system:9090
query: |
histogram_quantile(0.95,
sum(rate(
istio_request_duration_milliseconds_bucket{
destination_service_name="{{args.service-name}}",
destination_workload_namespace="default"
}[2m]
)) by (le)
)执行和监控部署
部署新版本
# Start Canary deployment with image update
kubectl argo rollouts set image reviews \
reviews=docker.io/istio/examples-bookinfo-reviews-v3:1.17.0
# Check Rollout status
kubectl argo rollouts get rollout reviews --watch
# Real-time dashboard
kubectl argo rollouts dashboard手动批准/拒绝
# Manual approval to proceed to next step
kubectl argo rollouts promote reviews
# Abort and rollback Canary deployment
kubectl argo rollouts abort reviews
# Rollback to specific revision
kubectl argo rollouts undo reviews监控部署进度
# Check Rollout status
kubectl argo rollouts status reviews
# Check analysis results
kubectl get analysisrun -w
# Check Canary vs Stable traffic distribution
kubectl get virtualservice reviews-vsvc -o yaml
# Check actual Pod status
kubectl get pods -l app=reviews --show-labels高级配置:基于指标的自动推进
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: reviews-auto
spec:
replicas: 5
strategy:
canary:
trafficRouting:
istio:
virtualService:
name: reviews-vsvc
routes:
- primary
destinationRule:
name: reviews-destrule
canarySubsetName: canary
stableSubsetName: stable
steps:
- setWeight: 10
- pause:
duration: 1m
# Automatic Analysis - Automatically proceed to next step on success
- analysis:
templates:
- templateName: success-rate
- templateName: latency
args:
- name: service-name
value: reviews
- setWeight: 25
- pause:
duration: 1m
- analysis:
templates:
- templateName: success-rate
- templateName: latency
args:
- name: service-name
value: reviews
- setWeight: 50
- pause:
duration: 1m
- analysis:
templates:
- templateName: success-rate
- templateName: latency
args:
- name: service-name
value: reviews
- setWeight: 75
- pause:
duration: 1m
- analysis:
templates:
- templateName: success-rate
- templateName: latency
args:
- name: service-name
value: reviews关键注意事项
1. 必须预先创建 VirtualService 和 DestinationRule
Argo Rollouts 不会创建这些资源。必须在部署 Rollout 前创建它们:
# Order is important
kubectl apply -f service.yaml
kubectl apply -f destination-rule.yaml
kubectl apply -f virtual-service.yaml
kubectl apply -f rollout.yaml2. 由 Rollout 管理的标签
Argo Rollouts 会自动添加/管理以下标签:
# Labels automatically added by Rollout
rollouts-pod-template-hash: <hash> # For ReplicaSet identification这些标签用于在 DestinationRule 中选择子集。
3. 必须提供 HTTP 路由名称
VirtualService 中的每条 HTTP 路由都必须具有 name 字段:
# Wrong example
http:
- route: # No name!
- destination:
host: reviews
# Correct example
http:
- name: primary # Required!
route:
- destination:
host: reviews4. 启用 Istio 注入
必须将 Istio sidecar 注入 Rollout Pod:
# Method 1: Namespace level
kubectl label namespace default istio-injection=enabled
# Method 2: Pod level
template:
metadata:
labels:
sidecar.istio.io/inject: "true"与 VirtualService Match 配合使用
Argo Rollouts 可以与 VirtualService match 条件配合使用。这允许仅将满足特定条件的流量路由到 Canary。
示例 1:基于 Header 的 Canary(面向内部测试人员)
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-vsvc
spec:
hosts:
- reviews
http:
# Priority 1: Internal testers always go to Canary
- match:
- headers:
x-canary-tester:
exact: "true"
route:
- destination:
host: reviews
subset: canary
# Priority 2: Normal traffic - Rollout manages this route's weight
- name: primary
route:
- destination:
host: reviews
subset: stable
weight: 100
- destination:
host: reviews
subset: canary
weight: 0使用场景:
# Internal testers always access Canary version
curl -H "x-canary-tester: true" http://reviews:9080/
# Regular users are routed based on Rollout's weight
curl http://reviews:9080/示例 2:基于区域的分阶段部署
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-vsvc
spec:
hosts:
- reviews
http:
# Priority 1: Dev environment always gets latest version
- match:
- headers:
x-env:
exact: "dev"
route:
- destination:
host: reviews
subset: canary
# Priority 2: Only specific region for Canary test (e.g., Seoul)
- match:
- headers:
x-region:
exact: "ap-northeast-2"
name: seoul-traffic
route:
- destination:
host: reviews
subset: stable
weight: 100
- destination:
host: reviews
subset: canary
weight: 0
# Priority 3: Other regions stay on stable version
- name: other-regions
route:
- destination:
host: reviews
subset: stableRollout 配置:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: reviews
spec:
# ... (same as before)
strategy:
canary:
trafficRouting:
istio:
virtualService:
name: reviews-vsvc
routes:
- seoul-traffic # Only apply Canary to Seoul traffic
destinationRule:
name: reviews-destrule
canarySubsetName: canary
stableSubsetName: stable
steps:
- setWeight: 10
- pause: {duration: 2m}
- setWeight: 50
- pause: {duration: 2m}示例 3:基于用户层级的部署
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-vsvc
spec:
hosts:
- reviews
http:
# Priority 1: Beta program participants
- match:
- headers:
x-user-tier:
exact: "beta"
route:
- destination:
host: reviews
subset: canary
# Priority 2: Only premium users for Canary test
- match:
- headers:
x-user-tier:
exact: "premium"
name: premium-users
route:
- destination:
host: reviews
subset: stable
weight: 100
- destination:
host: reviews
subset: canary
weight: 0
# Priority 3: Free users get stable version
- name: free-users
route:
- destination:
host: reviews
subset: stable示例 4:基于移动应用版本的部署
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-vsvc
spec:
hosts:
- reviews
http:
# Priority 1: Only latest app version users get Canary
- match:
- headers:
x-app-version:
regex: "^3\\.(1[0-9]|[2-9][0-9])\\." # 3.10.x or higher
name: latest-app-version
route:
- destination:
host: reviews
subset: stable
weight: 100
- destination:
host: reviews
subset: canary
weight: 0
# Priority 2: Legacy app only gets stable version
- name: legacy-app-version
route:
- destination:
host: reviews
subset: stable完整部署示例
一个一次部署所有资源的基本示例:
---
# Service
apiVersion: v1
kind: Service
metadata:
name: reviews
spec:
ports:
- port: 9080
name: http
selector:
app: reviews
---
# DestinationRule
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: reviews-destrule
spec:
host: reviews
subsets:
- name: stable
labels: {} # Managed by Rollout
- name: canary
labels: {} # Managed by Rollout
---
# VirtualService
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-vsvc
spec:
hosts:
- reviews
http:
- name: primary
route:
- destination:
host: reviews
subset: stable
weight: 100
- destination:
host: reviews
subset: canary
weight: 0
---
# Rollout
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: reviews
spec:
replicas: 3
selector:
matchLabels:
app: reviews
template:
metadata:
labels:
app: reviews
spec:
containers:
- name: reviews
image: istio/examples-bookinfo-reviews-v1:1.17.0
ports:
- containerPort: 9080
strategy:
canary:
trafficRouting:
istio:
virtualService:
name: reviews-vsvc
routes:
- primary
destinationRule:
name: reviews-destrule
canarySubsetName: canary
stableSubsetName: stable
steps:
- setWeight: 20
- pause: {duration: 1m}
- setWeight: 40
- pause: {duration: 1m}
- setWeight: 60
- pause: {duration: 1m}
- setWeight: 80
- pause: {duration: 1m}使用 Match 时的注意事项
1. 路由顺序很重要
VirtualService 中的 HTTP 路由会按顺序评估。具有 match 的路由应置于由 Rollout 管理的路由之前:
# Correct example
http:
- match:
- headers:
x-tester: {exact: "true"}
route:
- destination: {host: reviews, subset: canary}
- name: primary # Managed by Rollout
route:
- destination: {host: reviews, subset: stable}
weight: 100
- destination: {host: reviews, subset: canary}
weight: 0
# Wrong example - match is ignored if primary comes first
http:
- name: primary
route: [...]
- match: [...] # Never reached!
route: [...]2. Rollout 仅管理指定路由
Rollout 仅修改 routes 字段中指定路由的权重:
strategy:
canary:
trafficRouting:
istio:
virtualService:
name: reviews-vsvc
routes:
- primary # Only modifies this route's weight
# Other routes with match are not modified3. 同时管理多个路由
如有需要,可以同时管理多个路由:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-vsvc
spec:
hosts:
- reviews
http:
# Premium users route
- match:
- headers:
x-user-tier: {exact: "premium"}
name: premium-route
route:
- destination: {host: reviews, subset: stable}
weight: 100
- destination: {host: reviews, subset: canary}
weight: 0
# Standard users route
- name: standard-route
route:
- destination: {host: reviews, subset: stable}
weight: 100
- destination: {host: reviews, subset: canary}
weight: 0
---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: reviews
spec:
strategy:
canary:
trafficRouting:
istio:
virtualService:
name: reviews-vsvc
routes:
- premium-route # Manage both routes
- standard-route
destinationRule:
name: reviews-destrule
canarySubsetName: canary
stableSubsetName: stable
steps:
- setWeight: 10
- pause: {duration: 2m}故障排除
Rollout 卡在 Progressing 状态
# Check Rollout status
kubectl argo rollouts get rollout reviews
# Check Events
kubectl describe rollout reviews
# Common causes:
# 1. VirtualService/DestinationRule doesn't exist
kubectl get virtualservice reviews-vsvc
kubectl get destinationrule reviews-destrule
# 2. HTTP route name is wrong
kubectl get virtualservice reviews-vsvc -o yaml | grep "name:"
# 3. Istio sidecar not injected
kubectl get pods -l app=reviews -o jsonpath='{.items[*].spec.containers[*].name}'流量未进入 Canary
# Check VirtualService weight
kubectl get virtualservice reviews-vsvc -o yaml
# Check DestinationRule subsets
kubectl get destinationrule reviews-destrule -o yaml
# Check Pod labels
kubectl get pods -l app=reviews --show-labels
# Check Envoy configuration
istioctl proxy-config routes <pod-name>Rollout 回滚
# Rollback to previous revision
kubectl argo rollouts undo reviews
# Rollback to specific revision
kubectl argo rollouts undo reviews --to-revision=2
# Abort and rollback immediately
kubectl argo rollouts abort reviews使用 Argo Rollouts 进行 Blue/Green 部署
Argo Rollouts 也支持 Blue/Green 策略:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: reviews-bluegreen
spec:
replicas: 5
selector:
matchLabels:
app: reviews
template:
metadata:
labels:
app: reviews
spec:
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v2:1.17.0
ports:
- containerPort: 9080
strategy:
blueGreen:
activeService: reviews-active
previewService: reviews-preview
autoPromotionEnabled: false # Manual approval
scaleDownDelaySeconds: 30
prePromotionAnalysis:
templates:
- templateName: smoke-tests
args:
- name: service-name
value: reviews-previewBlue/Green 部署
Blue/Green 部署维护两个相同的生产环境,并可即时切换流量。将 Argo Rollouts 与 Istio 搭配使用可实现安全切换和自动回滚。
Argo Rollouts Blue/Green 架构
Blue/Green 部署流程
步骤 1:定义 Service
Blue/Green 部署需要两个 Service:
---
# Active Service - Production traffic
apiVersion: v1
kind: Service
metadata:
name: reviews-active
spec:
ports:
- port: 9080
name: http
selector:
app: reviews
# Rollout automatically updates selector
---
# Preview Service - Test traffic
apiVersion: v1
kind: Service
metadata:
name: reviews-preview
spec:
ports:
- port: 9080
name: http
selector:
app: reviews
# Rollout automatically updates selector步骤 2:Istio Gateway 和 VirtualService
---
# Gateway
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: reviews-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- reviews.example.com
---
# VirtualService - Active Service
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-vsvc
spec:
hosts:
- reviews.example.com
gateways:
- reviews-gateway
http:
- route:
- destination:
host: reviews-active # Route to Active Service
port:
number: 9080
---
# VirtualService - Preview Service (for testing)
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-preview-vsvc
spec:
hosts:
- reviews-preview.example.com
gateways:
- reviews-gateway
http:
- route:
- destination:
host: reviews-preview # Route to Preview Service
port:
number: 9080步骤 3:定义 Rollout 资源
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: reviews
spec:
replicas: 3
revisionHistoryLimit: 2
selector:
matchLabels:
app: reviews
template:
metadata:
labels:
app: reviews
spec:
containers:
- name: reviews
image: istio/examples-bookinfo-reviews-v1:1.17.0
ports:
- containerPort: 9080
strategy:
blueGreen:
# Specify Active/Preview Services
activeService: reviews-active
previewService: reviews-preview
# Auto-promotion settings
autoPromotionEnabled: false # false: manual approval, true: auto-approve
autoPromotionSeconds: 30 # Wait time for auto-promotion
# Blue environment retention time
scaleDownDelaySeconds: 30 # Delete Blue 30 seconds after switch
scaleDownDelayRevisionLimit: 2 # Keep up to 2 previous versions
# Pre-test (validate Preview before deployment)
prePromotionAnalysis:
templates:
- templateName: smoke-tests
args:
- name: service-name
value: reviews-preview
# Post-verification (validate Active after switch)
postPromotionAnalysis:
templates:
- templateName: post-promotion-tests
args:
- name: service-name
value: reviews-active
# Anti-affinity (deploy Blue/Green on different nodes)
antiAffinity:
requiredDuringSchedulingIgnoredDuringExecution: {}步骤 4:定义 AnalysisTemplate
预测试(Smoke Tests)
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: smoke-tests
spec:
args:
- name: service-name
metrics:
# 1. HTTP status code check
- name: http-status
interval: 10s
count: 5
successCondition: result == 200
provider:
job:
spec:
template:
spec:
containers:
- name: curl
image: curlimages/curl:7.88.1
command:
- sh
- -c
- |
curl -s -o /dev/null -w "%{http_code}" http://{{args.service-name}}:9080/health
restartPolicy: Never
backoffLimit: 1
# 2. Basic functional test
- name: functional-test
interval: 10s
count: 3
successCondition: result == true
provider:
job:
spec:
template:
spec:
containers:
- name: test
image: appropriate/curl:latest
command:
- sh
- -c
- |
# API endpoint test
curl -f http://{{args.service-name}}:9080/api/v1/health
restartPolicy: Never
backoffLimit: 1推广后验证测试
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: post-promotion-tests
spec:
args:
- name: service-name
metrics:
# Prometheus metric-based verification
- name: error-rate
interval: 30s
count: 10
successCondition: result < 0.05 # Less than 5% error rate
provider:
prometheus:
address: http://prometheus.istio-system:9090
query: |
sum(rate(
istio_requests_total{
destination_service_name="{{args.service-name}}",
response_code=~"5.."
}[1m]
))
/
sum(rate(
istio_requests_total{
destination_service_name="{{args.service-name}}"
}[1m]
))
- name: response-time
interval: 30s
count: 10
successCondition: result < 500 # Less than 500ms
provider:
prometheus:
address: http://prometheus.istio-system:9090
query: |
histogram_quantile(0.95,
sum(rate(
istio_request_duration_milliseconds_bucket{
destination_service_name="{{args.service-name}}"
}[1m]
)) by (le)
)执行和管理部署
部署新版本
# Start Blue/Green deployment with image update
kubectl argo rollouts set image reviews \
reviews=istio/examples-bookinfo-reviews-v2:1.17.0
# Check Rollout status
kubectl argo rollouts get rollout reviews --watch
# Test Preview environment
curl http://reviews-preview.example.com/手动批准(Promotion)
# Manually approve after pre-tests succeed
kubectl argo rollouts promote reviews
# Or approve from dashboard
kubectl argo rollouts dashboard检查状态
# Rollout status
kubectl argo rollouts status reviews
# Check Active/Preview Services
kubectl get svc reviews-active reviews-preview
# Check Pod status
kubectl get pods -l app=reviews --show-labels
# Check Analysis results
kubectl get analysisrun回滚
# Immediate rollback (switch to Blue)
kubectl argo rollouts abort reviews
# Rollback to previous version
kubectl argo rollouts undo reviews
# Rollback to specific revision
kubectl argo rollouts undo reviews --to-revision=3A/B 测试
A/B 测试同时运行两个版本,并根据特定条件对用户进行分类以衡量效果。
基于 Cookie 的 A/B 测试
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp-ab-test
spec:
hosts:
- myapp.example.com
http:
# Group A (cookie value "a")
- match:
- headers:
cookie:
regex: ".*ab_test=a.*"
route:
- destination:
host: myapp
subset: version-a
# Group B (cookie value "b")
- match:
- headers:
cookie:
regex: ".*ab_test=b.*"
route:
- destination:
host: myapp
subset: version-b
# New users (no cookie) - 50/50 split
- route:
- destination:
host: myapp
subset: version-a
weight: 50
- destination:
host: myapp
subset: version-b
weight: 50
headers:
response:
add:
Set-Cookie: "ab_test=a; Max-Age=2592000; Path=/"基于 Header 的 A/B 测试
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp-ab-header
spec:
hosts:
- myapp
http:
# Mobile users -> Version B (new mobile UI)
- match:
- headers:
user-agent:
regex: ".*Mobile.*"
route:
- destination:
host: myapp
subset: version-b
# Premium users -> Version B (new features)
- match:
- headers:
x-user-tier:
exact: "premium"
route:
- destination:
host: myapp
subset: version-b
# Regular users -> Version A
- route:
- destination:
host: myapp
subset: version-a基于地理位置的 A/B 测试
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp-ab-geo
spec:
hosts:
- myapp
http:
# Test new version only in specific regions
- match:
- headers:
x-country-code:
regex: "US|CA" # USA, Canada
route:
- destination:
host: myapp
subset: version-b
weight: 50
- destination:
host: myapp
subset: version-a
weight: 50
# Other regions get existing version
- route:
- destination:
host: myapp
subset: version-a渐进式发布
渐进式发布会随时间自动提高流量比例。使用 Argo Rollouts 的 Canary 策略可实现自动化渐进式部署。
手动渐进式发布
#!/bin/bash
# progressive-rollout.sh
SERVICE="myapp"
NAMESPACE="default"
INTERVAL=300 # 5 minutes
# Traffic ratio array
WEIGHTS=(0 10 25 50 75 100)
for i in "${!WEIGHTS[@]}"; do
weight=${WEIGHTS[$i]}
prev_weight=$((100 - weight))
echo "[$i/${#WEIGHTS[@]}] Shifting traffic: v1=$prev_weight%, v2=$weight%"
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: ${SERVICE}
namespace: ${NAMESPACE}
spec:
hosts:
- ${SERVICE}
http:
- route:
- destination:
host: ${SERVICE}
subset: v1
weight: ${prev_weight}
- destination:
host: ${SERVICE}
subset: v2
weight: ${weight}
EOF
if [ $weight -lt 100 ]; then
echo "Waiting ${INTERVAL} seconds before next step..."
sleep $INTERVAL
# Check metrics
echo "Checking metrics..."
ERROR_RATE=$(kubectl exec -n ${NAMESPACE} -c istio-proxy \
$(kubectl get pod -n ${NAMESPACE} -l app=${SERVICE},version=v2 -o jsonpath='{.items[0].metadata.name}') -- \
curl -s localhost:15000/stats/prometheus | \
grep 'istio_requests_total{response_code="500"}' | \
awk '{print $2}')
if [ "$ERROR_RATE" != "" ] && [ "$ERROR_RATE" -gt 5 ]; then
echo "ERROR: High error rate detected ($ERROR_RATE errors). Rolling back!"
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: ${SERVICE}
namespace: ${NAMESPACE}
spec:
hosts:
- ${SERVICE}
http:
- route:
- destination:
host: ${SERVICE}
subset: v1
weight: 100
EOF
exit 1
fi
fi
done
echo "Progressive rollout completed successfully!"与流量镜像配合使用
将流量拆分与镜像结合,可实现更安全的部署。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp-canary-with-mirror
spec:
hosts:
- myapp
http:
- route:
# Main traffic: 90% v1, 10% v2
- destination:
host: myapp
subset: v1
weight: 90
- destination:
host: myapp
subset: v2
weight: 10
# Mirroring: duplicate all traffic to v3 (ignore response)
mirror:
host: myapp
subset: v3
mirrorPercentage:
value: 100实践示例
示例 1:基于用户群体的部署
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp-segmented-rollout
spec:
hosts:
- myapp.example.com
http:
# Internal employees - use new version first
- match:
- headers:
x-employee:
exact: "true"
route:
- destination:
host: myapp
subset: v2
# Beta testers - next to use new version
- match:
- headers:
x-beta-tester:
exact: "true"
route:
- destination:
host: myapp
subset: v2
# VIP customers - Canary 50%
- match:
- headers:
x-user-tier:
exact: "vip"
route:
- destination:
host: myapp
subset: v1
weight: 50
- destination:
host: myapp
subset: v2
weight: 50
# Regular customers - Canary 10%
- route:
- destination:
host: myapp
subset: v1
weight: 90
- destination:
host: myapp
subset: v2
weight: 10示例 2:基于时间的部署
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp-time-based
spec:
hosts:
- myapp
http:
# Korea daytime (KST 09:00-18:00) - stable version
- match:
- headers:
x-country-code:
exact: "KR"
x-hour:
regex: "0[9]|1[0-7]" # 09-17 hours
route:
- destination:
host: myapp
subset: v1
# Korea nighttime - Canary test
- match:
- headers:
x-country-code:
exact: "KR"
route:
- destination:
host: myapp
subset: v1
weight: 80
- destination:
host: myapp
subset: v2
weight: 20
# Other regions
- route:
- destination:
host: myapp
subset: v1示例 3:微服务链 Canary
# Frontend Canary
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: frontend-canary
spec:
hosts:
- frontend
http:
- route:
- destination:
host: frontend
subset: v1
weight: 90
- destination:
host: frontend
subset: v2
weight: 10
---
# Backend Canary (only used by Frontend v2)
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: backend-canary
spec:
hosts:
- backend
http:
# Only requests from Frontend v2 go to Backend v2
- match:
- sourceLabels:
app: frontend
version: v2
route:
- destination:
host: backend
subset: v2
# Rest go to Backend v1
- route:
- destination:
host: backend
subset: v1监控和回滚
Prometheus 查询
# Requests per version
sum(rate(istio_requests_total{destination_service="myapp.default.svc.cluster.local"}[5m])) by (destination_version)
# Error rate per version
sum(rate(istio_requests_total{destination_service="myapp.default.svc.cluster.local",response_code=~"5.."}[5m])) by (destination_version)
/
sum(rate(istio_requests_total{destination_service="myapp.default.svc.cluster.local"}[5m])) by (destination_version)
# Latency per version (P95)
histogram_quantile(0.95, sum(rate(istio_request_duration_milliseconds_bucket{destination_service="myapp.default.svc.cluster.local"}[5m])) by (destination_version, le))
# Traffic split ratio
sum(rate(istio_requests_total{destination_service="myapp.default.svc.cluster.local"}[5m])) by (destination_version)
/
sum(rate(istio_requests_total{destination_service="myapp.default.svc.cluster.local"}[5m]))自动回滚脚本
#!/bin/bash
# auto-rollback.sh
SERVICE="myapp"
NAMESPACE="default"
ERROR_THRESHOLD=5 # 5% error rate threshold
LATENCY_THRESHOLD=1000 # 1 second latency threshold
# Collect Canary version metrics
POD=$(kubectl get pod -n ${NAMESPACE} -l app=${SERVICE},version=v2 -o jsonpath='{.items[0].metadata.name}')
# Check error rate
ERROR_RATE=$(kubectl exec -n ${NAMESPACE} -c istio-proxy ${POD} -- \
curl -s localhost:15000/stats/prometheus | \
grep 'istio_requests_total{response_code="500"}' | \
awk '{sum+=$2} END {print sum}')
TOTAL_REQUESTS=$(kubectl exec -n ${NAMESPACE} -c istio-proxy ${POD} -- \
curl -s localhost:15000/stats/prometheus | \
grep 'istio_requests_total' | \
grep -v 'response_code' | \
awk '{sum+=$2} END {print sum}')
if [ "$TOTAL_REQUESTS" -gt 0 ]; then
ERROR_PERCENTAGE=$(echo "scale=2; ($ERROR_RATE / $TOTAL_REQUESTS) * 100" | bc)
if (( $(echo "$ERROR_PERCENTAGE > $ERROR_THRESHOLD" | bc -l) )); then
echo "ERROR: Error rate ${ERROR_PERCENTAGE}% exceeds threshold ${ERROR_THRESHOLD}%"
echo "Rolling back to v1..."
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: ${SERVICE}
namespace: ${NAMESPACE}
spec:
hosts:
- ${SERVICE}
http:
- route:
- destination:
host: ${SERVICE}
subset: v1
weight: 100
EOF
# Send notification
curl -X POST https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK \
-H 'Content-Type: application/json' \
-d "{\"text\":\"Warning: ${SERVICE} Canary rollback triggered! Error rate: ${ERROR_PERCENTAGE}%\"}"
exit 1
fi
fi
echo "Canary metrics within acceptable range"故障排除
流量拆分未生效
# 1. Check DestinationRule
kubectl get destinationrule -A
kubectl describe destinationrule <name> -n <namespace>
# 2. Check subset labels
kubectl get pods -n <namespace> --show-labels
# 3. Check VirtualService configuration
istioctl proxy-config routes <pod-name> -n <namespace> -o json
# 4. Check actual traffic distribution
kubectl exec -n <namespace> <pod-name> -c istio-proxy -- \
curl -s localhost:15000/clusters | grep <service-name>权重未按预期工作
# Check Envoy cluster weights
istioctl proxy-config clusters <pod-name> -n <namespace> --fqdn <service-fqdn> -o json
# Check endpoint status
kubectl get endpoints -n <namespace> <service-name> -o yaml
# Check Pod ready status
kubectl get pods -n <namespace> -l version=v2最佳实践
1. 分阶段发布
# Good example: Gradual increase
# 5% -> 10% -> 25% -> 50% -> 100%
# Bad example: Sudden increase
# 5% -> 100%2. 制定回滚计划
# Prepare rollback YAML file in advance
cat > rollback-v1.yaml <<EOF
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp
http:
- route:
- destination:
host: myapp
subset: v1
weight: 100
EOF
# Rollback command
kubectl apply -f rollback-v1.yaml3. 监控至关重要
- Golden Signals 监控:Latency、Traffic、Errors、Saturation
- 基于 SLO 的决策:未达到目标 SLO 时自动回滚
- 实时告警:通过 Slack、PagerDuty 等设置通知。
4. 测试自动化
使用 Argo Rollouts 的 AnalysisTemplate 实现自动化测试和验证:
# AnalysisTemplate for automated testing and verification
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 1m
count: 10
successCondition: result >= 0.95
failureLimit: 3
provider:
prometheus:
address: http://prometheus.istio-system:9090
query: |
sum(rate(
istio_requests_total{
destination_service_name="{{args.service-name}}",
response_code!~"5.*"
}[1m]
))
/
sum(rate(
istio_requests_total{
destination_service_name="{{args.service-name}}"
}[1m]
))
---
# Using AnalysisTemplate in Rollout
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp
spec:
strategy:
canary:
steps:
- setWeight: 10
- pause: {duration: 1m}
- analysis:
templates:
- templateName: success-rate
args:
- name: service-name
value: myapp5. 文档
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: myapp-canary
annotations:
description: "Canary deployment for myapp v2"
owner: "platform-team"
rollout-date: "2025-11-24"
rollout-plan: "5% -> 10% -> 25% -> 50% -> 100%"
monitoring-dashboard: "https://grafana.example.com/d/canary"
spec:
# ...