Progressive Delivery 2025 - 段階的デプロイの実践

2026.01.12

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テンプレート                               │
│                                                            │
└────────────────────────────────────────────────────────────┘

参考: Argo Rollouts Documentation, Flagger Documentation

まとめ

2025年、Progressive Deliveryは本番環境での安全なリリースを実現する標準的なプラクティスとなりました。Argo RolloutsとFlaggerは、Kubernetesネイティブな実装として広く採用され、メトリクス駆動の自動ロールアウト・ロールバックを可能にしています。

Feature Flagsとの統合により、デプロイとリリースの分離が実現し、より柔軟なリリース戦略が可能になりました。SLO駆動のアプローチとGitOps統合により、信頼性の高い継続的デリバリーパイプラインを構築できます。

重要なポイントは、単にツールを導入するだけでなく、適切なメトリクス設計とアラート戦略を組み合わせることです。Golden Signals(Latency、Traffic、Errors、Saturation)を基準とした監視体制を整え、自動化された分析とロールバック機構を活用することで、本番環境でのリスクを最小限に抑えながら、迅速なイテレーションを実現できます。

この技術を体系的に学びたいですか?

未来学では東証プライム上場企業のITエンジニアが24時間サポート。月額24,800円から、退会金0円のオンラインIT塾です。

LINEで無料相談する
← 一覧に戻る