Progressive Deliveryとは
Progressive Deliveryは、従来のContinuous Delivery(CD)を進化させたリスク軽減型のリリース戦略です。新しいバージョンを一度に全ユーザーへ展開するのではなく、段階的にトラフィックを移行し、メトリクスに基づいて自動的にロールアウトまたはロールバックを判断します。
┌─────────────────────────────────────────────────────────────┐
│ Progressive Delivery フロー │
├─────────────────────────────────────────────────────────────┤
│ │
│ Deploy → Canary (5%) → Analysis → Promote (25%) │
│ │ │
│ ▼ │
│ メトリクス監視 │
│ │ │
│ ┌────────┴────────┐ │
│ ▼ ▼ │
│ 成功: Promote 失敗: Rollback │
│ (50% → 100%) (0%へ戻す) │
│ │
└─────────────────────────────────────────────────────────────┘
2025年の採用状況
| 指標 | 数値 |
|---|---|
| Fortune 500企業のProgressive Delivery採用率 | 78% |
| Canaryリリースによるインシデント削減率 | 67% |
| 平均ロールバック時間の短縮 | 85% |
| Feature Flag活用企業 | 89% |
デプロイ戦略の比較
Blue-Green Deployment
# Blue-Green用Service切り替え
apiVersion: v1
kind: Service
metadata:
name: production-service
spec:
selector:
app: myapp
version: green # blue から green へ切り替え
ports:
- port: 80
targetPort: 8080
---
# Blue環境
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-blue
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: blue
template:
metadata:
labels:
app: myapp
version: blue
spec:
containers:
- name: myapp
image: myregistry/myapp:v1.0.0
ports:
- containerPort: 8080
---
# Green環境
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: green
template:
metadata:
labels:
app: myapp
version: green
spec:
containers:
- name: myapp
image: myregistry/myapp:v2.0.0
ports:
- containerPort: 8080
Canary Deployment
# Canary用トラフィック分割(Istio VirtualService)
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp-vs
spec:
hosts:
- myapp.example.com
http:
- match:
- headers:
x-canary:
exact: "true"
route:
- destination:
host: myapp-canary
port:
number: 80
- route:
- destination:
host: myapp-stable
port:
number: 80
weight: 95
- destination:
host: myapp-canary
port:
number: 80
weight: 5
Argo Rolloutsによる実装
Argo Rolloutsは、KubernetesネイティブのProgressive Deliveryコントローラーです。Deploymentリソースを拡張し、高度なデプロイ戦略を実現します。
インストール
# Argo Rolloutsのインストール
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
# kubectl pluginのインストール
brew install argoproj/tap/kubectl-argo-rollouts
# ダッシュボードの起動
kubectl argo rollouts dashboard
Canary Rollout定義
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: api-service
namespace: production
spec:
replicas: 10
selector:
matchLabels:
app: api-service
template:
metadata:
labels:
app: api-service
spec:
containers:
- name: api
image: myregistry/api-service:v2.0.0
ports:
- containerPort: 8080
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 3
strategy:
canary:
# Canaryの段階的なトラフィック増加
steps:
- setWeight: 5
- pause: {duration: 5m}
- setWeight: 10
- pause: {duration: 5m}
- setWeight: 25
- pause: {duration: 10m}
- setWeight: 50
- pause: {duration: 10m}
- setWeight: 75
- pause: {duration: 10m}
# 100%への昇格前に手動承認
- pause: {}
# Canary用Service
canaryService: api-service-canary
stableService: api-service-stable
# トラフィックルーティング(Istio使用)
trafficRouting:
istio:
virtualService:
name: api-service-vs
routes:
- primary
destinationRule:
name: api-service-dr
canarySubsetName: canary
stableSubsetName: stable
# メトリクス分析
analysis:
templates:
- templateName: success-rate
- templateName: latency
startingStep: 2
args:
- name: service-name
value: api-service-canary
AnalysisTemplate(メトリクス分析)
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
namespace: production
spec:
args:
- name: service-name
metrics:
- name: success-rate
# 成功率95%以上を要求
successCondition: result[0] >= 0.95
failureLimit: 3
interval: 60s
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]
))
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: latency
namespace: production
spec:
args:
- name: service-name
metrics:
- name: latency-p99
# P99レイテンシ500ms以下を要求
successCondition: result[0] <= 500
failureLimit: 3
interval: 60s
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
histogram_quantile(0.99,
sum(rate(
http_request_duration_milliseconds_bucket{
service="{{args.service-name}}"
}[5m]
)) by (le)
)
- name: error-rate
# エラー率1%以下を要求
successCondition: result[0] <= 0.01
failureLimit: 2
interval: 60s
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(
http_requests_total{
service="{{args.service-name}}",
status=~"5.."
}[5m]
)) /
sum(rate(
http_requests_total{
service="{{args.service-name}}"
}[5m]
))
Blue-Green Rollout
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: web-frontend
namespace: production
spec:
replicas: 5
selector:
matchLabels:
app: web-frontend
template:
metadata:
labels:
app: web-frontend
spec:
containers:
- name: frontend
image: myregistry/web-frontend:v3.0.0
ports:
- containerPort: 3000
strategy:
blueGreen:
# アクティブService(本番トラフィック)
activeService: web-frontend-active
# プレビューService(テスト用)
previewService: web-frontend-preview
# 自動昇格の有効化
autoPromotionEnabled: true
# 昇格前の待機時間
autoPromotionSeconds: 300
# プレビュー環境のレプリカ数
previewReplicaCount: 2
# 昇格前の分析
prePromotionAnalysis:
templates:
- templateName: smoke-test
- templateName: load-test
# 昇格後の分析
postPromotionAnalysis:
templates:
- templateName: success-rate
args:
- name: service-name
value: web-frontend-active
Flaggerによる自動化
Flaggerは、Service Mesh対応のProgressive Deliveryオペレーターです。Istio、Linkerd、AWS App Mesh、Nginx、Contourなど多様なサービスメッシュに対応しています。
Flaggerのインストール
# Helmリポジトリの追加
helm repo add flagger https://flagger.app
# Istio環境へのインストール
helm upgrade -i flagger flagger/flagger \
--namespace=istio-system \
--set meshProvider=istio \
--set metricsServer=http://prometheus.istio-system:9090
# Slack通知の設定
helm upgrade -i flagger flagger/flagger \
--namespace=istio-system \
--set slack.url=https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK \
--set slack.channel=deployments \
--set slack.user=flagger
Canary CRD定義
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: payment-service
namespace: production
spec:
# ターゲットとなるDeployment
targetRef:
apiVersion: apps/v1
kind: Deployment
name: payment-service
# HPA参照(オプション)
autoscalerRef:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
name: payment-service-hpa
# Service設定
service:
port: 80
targetPort: 8080
# Istio Gateway参照
gateways:
- public-gateway.istio-system.svc.cluster.local
hosts:
- payment.example.com
# リトライ設定
retries:
attempts: 3
perTryTimeout: 2s
retryOn: "gateway-error,connect-failure,refused-stream"
# ヘッダー操作
headers:
request:
add:
x-envoy-upstream-rq-timeout-ms: "15000"
# 分析設定
analysis:
# 分析間隔
interval: 1m
# 昇格に必要な成功回数
threshold: 10
# 最大失敗回数
maxWeight: 50
# ステップごとの重み増加
stepWeight: 10
# stepWeightPromotion: 20
# メトリクス定義
metrics:
- name: request-success-rate
# 成功率99%以上
thresholdRange:
min: 99
interval: 1m
- name: request-duration
# P99レイテンシ500ms以下
thresholdRange:
max: 500
interval: 1m
- name: custom-error-rate
# カスタムメトリクス
templateRef:
name: error-rate-template
namespace: istio-system
thresholdRange:
max: 1
interval: 1m
# Webhook(テスト実行)
webhooks:
- name: load-test
type: rollout
url: http://flagger-loadtester.production/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 1m -q 10 -c 2 http://payment-service-canary.production/"
- name: integration-test
type: pre-rollout
url: http://flagger-loadtester.production/
timeout: 60s
metadata:
type: bash
cmd: |
curl -s http://payment-service-canary.production/health | grep -q "ok"
- name: smoke-test
type: post-rollout
url: http://flagger-loadtester.production/
timeout: 15s
metadata:
type: bash
cmd: |
curl -sd 'test' http://payment-service.production/api/validate | grep -q "success"
# アラート設定
alerts:
- name: "Slack通知"
severity: info
providerRef:
name: slack
namespace: istio-system
- name: "PagerDuty通知"
severity: error
providerRef:
name: pagerduty
namespace: istio-system
カスタムメトリクステンプレート
apiVersion: flagger.app/v1beta1
kind: MetricTemplate
metadata:
name: error-rate-template
namespace: istio-system
spec:
provider:
type: prometheus
address: http://prometheus.istio-system:9090
query: |
100 - sum(
rate(
istio_requests_total{
reporter="destination",
destination_workload_namespace="{{ namespace }}",
destination_workload="{{ target }}",
response_code!~"5.*"
}[{{ interval }}]
)
) / sum(
rate(
istio_requests_total{
reporter="destination",
destination_workload_namespace="{{ namespace }}",
destination_workload="{{ target }}"
}[{{ interval }}]
)
) * 100
AlertProvider設定
apiVersion: flagger.app/v1beta1
kind: AlertProvider
metadata:
name: slack
namespace: istio-system
spec:
type: slack
channel: deployments
username: flagger
address: https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK
---
apiVersion: flagger.app/v1beta1
kind: AlertProvider
metadata:
name: pagerduty
namespace: istio-system
spec:
type: pagerduty
address: https://events.pagerduty.com/v2/enqueue
secretRef:
name: pagerduty-routing-key
Feature Flagsとの統合
Progressive DeliveryとFeature Flagsを組み合わせることで、コードのデプロイとフィーチャーのリリースを分離できます。
LaunchDarkly連携
# ConfigMapでFeature Flag設定を管理
apiVersion: v1
kind: ConfigMap
metadata:
name: feature-flags
namespace: production
data:
config.json: |
{
"sdkKey": "${LAUNCHDARKLY_SDK_KEY}",
"flags": {
"new-checkout-flow": {
"enabled": true,
"targeting": {
"rules": [
{
"variation": "treatment",
"percentage": 10,
"attribute": "userId"
}
]
}
},
"ai-recommendations": {
"enabled": true,
"targeting": {
"rules": [
{
"variation": "enabled",
"segments": ["beta-users", "premium-users"]
}
]
}
}
}
}
OpenFeature統合
# OpenFeature Operator設定
apiVersion: core.openfeature.dev/v1alpha1
kind: FeatureFlagConfiguration
metadata:
name: app-flags
namespace: production
spec:
featureFlagSpec:
flags:
new-payment-flow:
state: ENABLED
variants:
"on": true
"off": false
defaultVariant: "off"
targeting:
if:
- in:
- var: userTier
- ["premium", "enterprise"]
- "on"
- "off"
dark-mode:
state: ENABLED
variants:
enabled: true
disabled: false
defaultVariant: disabled
メトリクス駆動のロールアウト
Golden Signalsの監視
# ServiceMonitor定義(Prometheus Operator)
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: api-service-monitor
namespace: production
spec:
selector:
matchLabels:
app: api-service
endpoints:
- port: metrics
interval: 15s
path: /metrics
---
# PrometheusRule(アラート定義)
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: api-service-alerts
namespace: production
spec:
groups:
- name: api-service.rules
rules:
# Latency(レイテンシ)
- alert: HighLatency
expr: |
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket{service="api-service"}[5m])) by (le)
) > 0.5
for: 5m
labels:
severity: warning
annotations:
summary: "High latency detected"
description: "P99 latency is above 500ms"
# Traffic(トラフィック)
- alert: TrafficSpike
expr: |
sum(rate(http_requests_total{service="api-service"}[5m])) >
sum(rate(http_requests_total{service="api-service"}[1h] offset 1d)) * 2
for: 5m
labels:
severity: info
annotations:
summary: "Traffic spike detected"
# Errors(エラー)
- alert: HighErrorRate
expr: |
sum(rate(http_requests_total{service="api-service",status=~"5.."}[5m])) /
sum(rate(http_requests_total{service="api-service"}[5m])) > 0.01
for: 2m
labels:
severity: critical
annotations:
summary: "High error rate detected"
# Saturation(飽和度)
- alert: HighCPUUsage
expr: |
avg(rate(container_cpu_usage_seconds_total{pod=~"api-service.*"}[5m])) /
avg(kube_pod_container_resource_limits{pod=~"api-service.*",resource="cpu"}) > 0.9
for: 5m
labels:
severity: warning
Grafanaダッシュボード(JSON)
{
"dashboard": {
"title": "Progressive Delivery Dashboard",
"panels": [
{
"title": "Canary vs Stable Success Rate",
"type": "timeseries",
"targets": [
{
"expr": "sum(rate(http_requests_total{service=~\".*-canary\",status=~\"2..\"}[5m])) / sum(rate(http_requests_total{service=~\".*-canary\"}[5m]))",
"legendFormat": "Canary"
},
{
"expr": "sum(rate(http_requests_total{service=~\".*-stable\",status=~\"2..\"}[5m])) / sum(rate(http_requests_total{service=~\".*-stable\"}[5m]))",
"legendFormat": "Stable"
}
]
},
{
"title": "Traffic Weight Distribution",
"type": "gauge",
"targets": [
{
"expr": "sum(istio_requests_total{destination_service=~\".*-canary.*\"}) / sum(istio_requests_total) * 100",
"legendFormat": "Canary Traffic %"
}
]
}
]
}
}
ロールバック戦略
自動ロールバック設定
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: critical-service
spec:
# ... 省略 ...
strategy:
canary:
steps:
- setWeight: 5
- pause: {duration: 2m}
- analysis:
templates:
- templateName: critical-analysis
- setWeight: 25
- pause: {duration: 5m}
- setWeight: 50
- pause: {duration: 5m}
# 自動ロールバック条件
abortScaleDownDelaySeconds: 30
# 分析失敗時のロールバック
analysis:
templates:
- templateName: success-rate
- templateName: error-count
# 分析失敗で即時ロールバック
successfulRunHistoryLimit: 1
unsuccessfulRunHistoryLimit: 1
---
# エラーカウントベースの分析
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: error-count
spec:
metrics:
- name: error-count
# 5分間で100エラー以上でロールバック
successCondition: result[0] < 100
failureLimit: 1
interval: 1m
provider:
prometheus:
address: http://prometheus:9090
query: |
sum(increase(
http_requests_total{
service="{{args.service-name}}",
status=~"5.."
}[5m]
))
手動ロールバックコマンド
# Argo Rolloutsでのロールバック
kubectl argo rollouts abort api-service -n production
# 前のリビジョンへ戻す
kubectl argo rollouts undo api-service -n production
# 特定リビジョンへ戻す
kubectl argo rollouts undo api-service --to-revision=3 -n production
# Flaggerでのロールバック
# Deploymentのイメージを前バージョンに戻す
kubectl set image deployment/payment-service \
payment=myregistry/payment:v1.0.0 -n production
2025年のベストプラクティス
GitOps統合
# ArgoCD + Argo Rollouts統合
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: api-service
namespace: argocd
spec:
project: production
source:
repoURL: https://github.com/myorg/k8s-manifests
targetRevision: main
path: services/api-service
kustomize:
images:
- myregistry/api-service:v2.0.0
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- RespectIgnoreDifferences=true
ignoreDifferences:
# Rolloutのステータスフィールドを無視
- group: argoproj.io
kind: Rollout
jsonPointers:
- /status
マルチクラスター Progressive Delivery
# Argo Rollouts マルチクラスター設定
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: global-api
spec:
strategy:
canary:
steps:
# リージョン1でCanary開始
- setWeight: 10
- pause: {duration: 10m}
# 分析成功後、他リージョンへ展開
- analysis:
templates:
- templateName: multi-region-check
- setWeight: 50
- pause: {duration: 15m}
trafficRouting:
managedRoutes:
- name: region-us-east
- name: region-eu-west
- name: region-ap-northeast
SLO駆動のロールアウト
# Keptn + Argo Rollouts統合
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: slo-analysis
spec:
metrics:
- name: slo-compliance
# SLO準拠率99.9%以上
successCondition: result[0] >= 99.9
provider:
prometheus:
address: http://prometheus:9090
query: |
avg_over_time(
slo:compliance_ratio:rate5m{
service="{{args.service-name}}"
}[15m]
) * 100
- name: error-budget-remaining
# エラーバジェット残量10%以上
successCondition: result[0] >= 10
provider:
prometheus:
address: http://prometheus:9090
query: |
100 - (
sum(increase(http_requests_total{status=~"5..",service="{{args.service-name}}"}[30d])) /
(sum(increase(http_requests_total{service="{{args.service-name}}"}[30d])) * 0.001)
) * 100
セキュリティ統合
# Progressive Delivery with Security Scanning
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: security-scan
spec:
metrics:
- name: vulnerability-check
# クリティカル・高脆弱性がないこと
successCondition: result.critical == 0 && result.high == 0
provider:
job:
spec:
backoffLimit: 1
template:
spec:
containers:
- name: trivy-scan
image: aquasec/trivy:latest
command:
- sh
- -c
- |
trivy image --exit-code 1 --severity CRITICAL,HIGH \
--format json --output /tmp/results.json \
{{args.image}}
cat /tmp/results.json
restartPolicy: Never
今後の展望
┌────────────────────────────────────────────────────────────┐
│ Progressive Delivery 2026年トレンド │
├────────────────────────────────────────────────────────────┤
│ │
│ 1. AI駆動の自動分析 │
│ - 異常検知の高度化 │
│ - 予測的ロールバック │
│ │
│ 2. マルチクラウド・エッジ対応 │
│ - 地理的分散デプロイ │
│ - エッジロケーションへの段階的展開 │
│ │
│ 3. サプライチェーンセキュリティ統合 │
│ - SBOM検証の自動化 │
│ - 署名検証ゲート │
│ │
│ 4. プラットフォームエンジニアリング │
│ - 開発者セルフサービス │
│ - Golden Pathテンプレート │
│ │
└────────────────────────────────────────────────────────────┘
まとめ
2025年、Progressive Deliveryは本番環境での安全なリリースを実現する標準的なプラクティスとなりました。Argo RolloutsとFlaggerは、Kubernetesネイティブな実装として広く採用され、メトリクス駆動の自動ロールアウト・ロールバックを可能にしています。
Feature Flagsとの統合により、デプロイとリリースの分離が実現し、より柔軟なリリース戦略が可能になりました。SLO駆動のアプローチとGitOps統合により、信頼性の高い継続的デリバリーパイプラインを構築できます。
重要なポイントは、単にツールを導入するだけでなく、適切なメトリクス設計とアラート戦略を組み合わせることです。Golden Signals(Latency、Traffic、Errors、Saturation)を基準とした監視体制を整え、自動化された分析とロールバック機構を活用することで、本番環境でのリスクを最小限に抑えながら、迅速なイテレーションを実現できます。
← 一覧に戻る