ArgoCD 流量管理
支持的版本: Argo Rollouts v1.6+, ArgoCD v2.9+ 最后更新: February 22, 2026
目录
Argo Rollouts 概述
Argo Rollouts 是一个 Kubernetes controller,提供高级部署功能,包括蓝绿部署、金丝雀部署和渐进式交付功能。
为什么选择 Argo Rollouts?
标准 Kubernetes Deployments 仅支持滚动更新。Argo Rollouts 在此基础上扩展了以下功能:
| Feature | K8s Deployment | Argo Rollouts |
|---|---|---|
| Rolling Update | Yes | Yes |
| Blue-Green | No | Yes |
| Canary | No | Yes |
| Traffic Splitting | No | Yes |
| Automated Rollback | No | Yes |
| Analysis/Verification | No | Yes |
| Pause/Resume | No | Yes |
| Experiments | No | Yes |
架构
安装
安装 Argo Rollouts Controller
bash
# Create namespace
kubectl create namespace argo-rollouts
# Install controller
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
# Verify installation
kubectl get pods -n argo-rollouts安装 kubectl 插件
bash
# macOS
brew install argoproj/tap/kubectl-argo-rollouts
# Linux
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
# Verify
kubectl argo rollouts version通过 Helm 安装
bash
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm install argo-rollouts argo/argo-rollouts \
--namespace argo-rollouts \
--create-namespace \
--set dashboard.enabled=true生产环境的 Helm Values
yaml
controller:
replicas: 2
metrics:
enabled: true
serviceMonitor:
enabled: true
dashboard:
enabled: true
ingress:
enabled: true
ingressClassName: nginx
hosts:
- rollouts.example.com
# For AWS ALB integration
trafficRouterPlugins:
- name: alb
enabled: true蓝绿部署
蓝绿部署维护两个相同的环境,并在它们之间切换流量。
基本蓝绿 Rollout
yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp
namespace: myapp
spec:
replicas: 5
revisionHistoryLimit: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:v1.0.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
strategy:
blueGreen:
activeService: myapp-active
previewService: myapp-preview
autoPromotionEnabled: false
scaleDownDelaySeconds: 30
previewReplicaCount: 2
prePromotionAnalysis:
templates:
- templateName: smoke-tests
args:
- name: service-name
value: myapp-preview
postPromotionAnalysis:
templates:
- templateName: success-rate
---
apiVersion: v1
kind: Service
metadata:
name: myapp-active
namespace: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: myapp-preview
namespace: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080蓝绿流程
启用自动提升的蓝绿部署
yaml
strategy:
blueGreen:
activeService: myapp-active
previewService: myapp-preview
autoPromotionEnabled: true
autoPromotionSeconds: 60 # Wait 60s before auto-promoting
previewReplicaCount: 3金丝雀部署
金丝雀部署将流量逐步迁移到新版本。
基本金丝雀 Rollout
yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp-canary
namespace: myapp
spec:
replicas: 10
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:v1.0.0
ports:
- containerPort: 8080
strategy:
canary:
canaryService: myapp-canary
stableService: myapp-stable
trafficRouting:
nginx:
stableIngress: myapp-ingress
steps:
# Step 1: 5% traffic to canary
- setWeight: 5
- pause: {duration: 2m}
# Step 2: 10% traffic, run analysis
- setWeight: 10
- analysis:
templates:
- templateName: success-rate
args:
- name: service-name
value: myapp-canary
# Step 3: 25% traffic
- setWeight: 25
- pause: {duration: 5m}
# Step 4: 50% traffic
- setWeight: 50
- pause: {duration: 5m}
# Step 5: 75% traffic
- setWeight: 75
- analysis:
templates:
- templateName: success-rate
- templateName: latency-check
# Step 6: 100% traffic (full promotion)
- setWeight: 100
---
apiVersion: v1
kind: Service
metadata:
name: myapp-stable
namespace: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: myapp-canary
namespace: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080金丝雀步骤说明
| Step Type | Description |
|---|---|
setWeight | Set traffic percentage to canary |
pause | Wait for duration or manual approval |
analysis | Run AnalysisTemplate |
setCanaryScale | Set canary replica count |
setHeaderRoute | Route by header (for traffic routers) |
带手动关卡的金丝雀部署
yaml
strategy:
canary:
steps:
- setWeight: 10
- pause: {} # Indefinite pause - requires manual promotion
- setWeight: 50
- pause: {duration: 10m}
- setWeight: 100手动提升:
bash
# Promote to next step
kubectl argo rollouts promote myapp-canary
# Promote fully (skip remaining steps)
kubectl argo rollouts promote myapp-canary --full金丝雀流量流程
分析与验证
AnalysisTemplates 定义如何验证部署健康状况。
Prometheus 分析
yaml
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
namespace: myapp
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 1m
count: 5
successCondition: result[0] >= 0.95
failureLimit: 3
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(
http_requests_total{
service="{{args.service-name}}",
status=~"2.."
}[5m]
)) /
sum(rate(
http_requests_total{
service="{{args.service-name}}"
}[5m]
))延迟分析
yaml
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: latency-check
namespace: myapp
spec:
args:
- name: service-name
metrics:
- name: p99-latency
interval: 2m
count: 3
successCondition: result[0] < 500 # 500ms threshold
failureLimit: 2
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
histogram_quantile(0.99,
sum(rate(
http_request_duration_seconds_bucket{
service="{{args.service-name}}"
}[5m]
)) by (le)
) * 1000Web 分析(HTTP Endpoint)
yaml
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: smoke-tests
namespace: myapp
spec:
args:
- name: service-name
metrics:
- name: smoke-test
interval: 30s
count: 3
successCondition: result.status == "healthy"
failureLimit: 1
provider:
web:
url: "http://{{args.service-name}}/health"
jsonPath: "{$.status}"
timeoutSeconds: 10Datadog 分析
yaml
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: datadog-success-rate
namespace: myapp
spec:
args:
- name: service-name
metrics:
- name: error-rate
interval: 5m
count: 3
successCondition: result < 0.05
failureLimit: 2
provider:
datadog:
apiVersion: v2
interval: 5m
query: |
sum:http.requests{service:{{args.service-name}},status:5xx}.as_count() /
sum:http.requests{service:{{args.service-name}}}.as_count()基于 Job 的分析
yaml
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: integration-tests
namespace: myapp
spec:
args:
- name: service-url
metrics:
- name: integration-tests
provider:
job:
spec:
backoffLimit: 1
template:
spec:
restartPolicy: Never
containers:
- name: test-runner
image: myregistry/integration-tests:latest
env:
- name: TARGET_URL
value: "{{args.service-url}}"
command:
- /bin/sh
- -c
- |
npm run test:integration
if [ $? -eq 0 ]; then
exit 0
else
exit 1
fiClusterAnalysisTemplate
在各 namespace 之间共享分析模板:
yaml
apiVersion: argoproj.io/v1alpha1
kind: ClusterAnalysisTemplate
metadata:
name: global-success-rate
spec:
args:
- name: service-name
- name: namespace
metrics:
- name: success-rate
interval: 1m
count: 5
successCondition: result[0] >= 0.95
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(
http_requests_total{
namespace="{{args.namespace}}",
service="{{args.service-name}}",
status=~"2.."
}[5m]
)) /
sum(rate(
http_requests_total{
namespace="{{args.namespace}}",
service="{{args.service-name}}"
}[5m]
))Ingress 集成
NGINX Ingress
yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp
namespace: myapp
spec:
strategy:
canary:
stableService: myapp-stable
canaryService: myapp-canary
trafficRouting:
nginx:
stableIngress: myapp-ingress
additionalIngressAnnotations:
canary-by-header: X-Canary
canary-by-header-value: "true"
steps:
- setWeight: 10
- pause: {duration: 5m}
- setWeight: 50
- pause: {duration: 5m}
- setWeight: 100
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
namespace: myapp
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-stable
port:
number: 80AWS ALB Ingress
yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp
namespace: myapp
spec:
strategy:
canary:
stableService: myapp-stable
canaryService: myapp-canary
trafficRouting:
alb:
ingress: myapp-ingress
rootService: myapp-root
servicePort: 80
steps:
- setWeight: 10
- pause: {duration: 5m}
- setWeight: 50
- pause: {duration: 5m}
- setWeight: 100
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
namespace: myapp
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/actions.myapp-root: |
{
"type": "forward",
"forwardConfig": {
"targetGroups": [
{
"serviceName": "myapp-stable",
"servicePort": 80,
"weight": 100
},
{
"serviceName": "myapp-canary",
"servicePort": 80,
"weight": 0
}
]
}
}
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-root
port:
name: use-annotationIstio 流量拆分
yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp
namespace: myapp
spec:
strategy:
canary:
stableService: myapp-stable
canaryService: myapp-canary
trafficRouting:
istio:
virtualService:
name: myapp-vsvc
routes:
- primary
destinationRule:
name: myapp-destrule
canarySubsetName: canary
stableSubsetName: stable
steps:
- setWeight: 10
- pause: {duration: 5m}
- setWeight: 50
- pause: {duration: 5m}
- setWeight: 100
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp-vsvc
namespace: myapp
spec:
hosts:
- myapp.example.com
gateways:
- myapp-gateway
http:
- name: primary
route:
- destination:
host: myapp-stable
weight: 100
- destination:
host: myapp-canary
weight: 0
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: myapp-destrule
namespace: myapp
spec:
host: myapp
subsets:
- name: stable
labels:
app: myapp
- name: canary
labels:
app: myapp回滚策略
分析失败时自动回滚
yaml
strategy:
canary:
steps:
- setWeight: 10
- analysis:
templates:
- templateName: success-rate
args:
- name: service-name
value: myapp-canary
# Analysis failure automatically triggers rollback手动回滚
bash
# Abort current rollout and rollback
kubectl argo rollouts abort myapp
# Undo to previous version
kubectl argo rollouts undo myapp
# Undo to specific revision
kubectl argo rollouts undo myapp --to-revision=2回滚配置
yaml
spec:
strategy:
canary:
abortScaleDownDelaySeconds: 30
dynamicStableScale: true
steps:
- setWeight: 10
- analysis:
templates:
- templateName: success-rate
# Analysis runs continuously
# Failure at any point triggers rollback实验
同时使用多个版本运行 A/B 测试。
yaml
apiVersion: argoproj.io/v1alpha1
kind: Experiment
metadata:
name: myapp-experiment
namespace: myapp
spec:
duration: 1h
progressDeadlineSeconds: 300
templates:
- name: baseline
replicas: 2
selector:
matchLabels:
app: myapp
variant: baseline
template:
metadata:
labels:
app: myapp
variant: baseline
spec:
containers:
- name: myapp
image: myregistry/myapp:v1.0.0
ports:
- containerPort: 8080
- name: canary
replicas: 2
selector:
matchLabels:
app: myapp
variant: canary
template:
metadata:
labels:
app: myapp
variant: canary
spec:
containers:
- name: myapp
image: myregistry/myapp:v2.0.0
ports:
- containerPort: 8080
analyses:
- name: compare-metrics
templateName: compare-experiment
args:
- name: baseline-hash
valueFrom:
podTemplateHashValue: baseline
- name: canary-hash
valueFrom:
podTemplateHashValue: canary通知
将 Rollout 事件与通知系统集成。
在 Rollout 中配置通知
yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp
namespace: myapp
annotations:
notifications.argoproj.io/subscribe.on-rollout-completed.slack: deployments
notifications.argoproj.io/subscribe.on-rollout-aborted.slack: deployments
notifications.argoproj.io/subscribe.on-analysis-run-failed.slack: alerts
spec:
# ...通知触发器与模板
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: argo-rollouts-notification-configmap
namespace: argo-rollouts
data:
service.slack: |
token: $slack-token
trigger.on-rollout-completed: |
- when: rollout.status.phase == 'Healthy'
send: [rollout-completed]
trigger.on-rollout-aborted: |
- when: rollout.status.phase == 'Degraded'
send: [rollout-aborted]
template.rollout-completed: |
message: |
Rollout {{.rollout.metadata.name}} completed successfully!
Revision: {{.rollout.status.currentPodHash}}
Image: {{(index .rollout.spec.template.spec.containers 0).image}}
template.rollout-aborted: |
message: |
Rollout {{.rollout.metadata.name}} was aborted!
Reason: {{.rollout.status.message}}测验
要测试你所学的内容,请尝试 ArgoCD 流量管理测验。