すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:Nginx Ingress を使用した段階的リリースとブルーグリーンリリースの実装

最終更新日:Jun 16, 2026

完全な切り替えの前に、ヘッダー、Cookie、または重みに基づいて、新しいサービスバージョンにトラフィックを段階的に移行します。

背景情報

段階的リリース (カナリアリリースとも呼ばれます) とブルーグリーンリリースは、どちらも旧バージョンと並行して新バージョンを実行し、トラフィックの一部を新バージョンにルーティングします。新バージョンが安定したら、すべてのトラフィックを切り替え、旧バージョンを廃止します。

ACK Nginx Ingress Controller は、アノテーションに基づいた 2 つのトラフィック分割方式をサポートしています:

メソッド ステータス
canary-* アノテーション アクティブ 公式コミュニティの方式です。すべての新しい構成には、この方式を使用してください。
service-* アノテーション 非推奨 Nginx Ingress Controller v1.12 以降では利用できなくなりました。使用しないでください。

利用シーン

  • クライアントリクエストに基づくトラフィック分割:リクエストに特定のヘッダーまたは Cookie (例:foo=bar) が含まれている場合にのみ、新バージョンにトラフィックをルーティングします。その他のリクエストは旧バージョンにルーティングされます。安定したら、すべてのトラフィックを切り替えます。

    image

  • サービスの重みに基づくトラフィック分割:トラフィックの一定の割合 (例:20%) を新バージョンにルーティングします。すべてのトラフィックが新バージョンにルーティングされるまで、この割合を徐々に増やしていきます。

    image

サポートされているトラフィック分割のディメンション:

  • リクエストヘッダー — 段階的リリースおよび A/B テストに適しています

  • Cookie — 段階的リリースおよび A/B テストに適しています

  • クエリパラメーター — 段階的リリースおよび A/B テストに適しています

  • サービスの重み — ブルーグリーンリリースに適しています

canary-* アノテーション方式

アノテーションリファレンス

すべてのカナリア構成には、nginx.ingress.kubernetes.io/canary: "true" アノテーションが必要です。その他のアノテーションはルーティングロジックを定義します。

アノテーション 説明 最小バージョン
nginx.ingress.kubernetes.io/canary カナリア機能を有効にします。他のカナリアアノテーションを有効にするには、true に設定する必要があります。有効な値:truefalse >=v0.22.0
nginx.ingress.kubernetes.io/canary-by-header リクエストヘッダーに基づいて、リクエストをカナリアサービスにルーティングします。特別な値:always (常にカナリアにルーティング)、never (カナリアにルーティングしない)。値が指定されていない場合、ヘッダーが存在するたびにトラフィックが転送されます。 >=v0.22.0
nginx.ingress.kubernetes.io/canary-by-header-value canary-by-header で指定されたヘッダーが正確な値と一致する場合に、リクエストをカナリアサービスにルーティングします。canary-by-header と一緒に使用する必要があります。 >=v0.30.0
nginx.ingress.kubernetes.io/canary-by-header-pattern canary-by-header で指定されたヘッダーが正規表現と一致する場合に、リクエストをカナリアサービスにルーティングします。canary-by-header と一緒に使用する必要があります。 >=v0.44.0
nginx.ingress.kubernetes.io/canary-by-cookie Cookie に基づいてリクエストをカナリアサービスにルーティングします。例:nginx.ingress.kubernetes.io/canary-by-cookie: foo。Cookie の値:always (foo=always はカナリアにルーティング)、never (foo=never はルーティングしない)。トラフィックは、Cookie が存在し、その値が always の場合にのみ転送されます。 >=v0.22.0
nginx.ingress.kubernetes.io/canary-weight 重みに基づいて、リクエストのパーセンテージをカナリアサービスにルーティングします。範囲:0 から canary-weight-total (デフォルトは 100)。 >=v0.22.0
nginx.ingress.kubernetes.io/canary-weight-total 合計の重みの分母を設定します。デフォルト:100 >=v1.1.2

アノテーションの優先度 (降順):

canary-by-header > canary-by-cookie > canary-weight

各 Ingress ルールは、1 つのカナリア Ingress のみをサポートします。追加のカナリア Ingress は無視されます。

ステップ 1:サービスのデプロイ

Nginx サービスをデプロイし、Nginx Ingress Controller を使用してレイヤー 7 ドメインアクセス用に公開します。

  1. Deployment と Service を作成します。次の内容を nginx.yaml として保存します。

    YAML ファイルの表示

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: old-nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          run: old-nginx
      template:
        metadata:
          labels:
            run: old-nginx
        spec:
          containers:
          - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx
            imagePullPolicy: Always
            name: old-nginx
            ports:
            - containerPort: 80
              protocol: TCP
          restartPolicy: Always
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: old-nginx
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        run: old-nginx
      sessionAffinity: None
      type: NodePort

    マニフェストを適用します:

    kubectl apply -f nginx.yaml
  2. Ingress を作成します。次の内容を ingress.yaml として保存します。

    v1.19 以降のクラスター

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          # サービスの旧バージョン
          - path: /
            backend:
              service:
                name: old-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    v1.19 より前のクラスター

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          # サービスの旧バージョン
          - path: /
            backend:
              serviceName: old-nginx
              servicePort: 80

    マニフェストを適用します:

    kubectl apply -f ingress.yaml
  3. デプロイメントを検証します。外部 IP アドレスを取得します:

    kubectl get ingress

    ルーティングアクセスを確認します:

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    期待される出力:

    old

ステップ 2:新しいサービスバージョンのリリース

新しい Nginx バージョンをデプロイし、カナリアルーティングルールを構成します。

  1. 新しい Deployment と Service を作成します。次の内容を nginx1.yaml として保存します。

    YAML ファイルの表示

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: new-nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: new-nginx
      template:
        metadata:
          labels:
            run: new-nginx
        spec:
          containers:
          - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx
            imagePullPolicy: Always
            name: new-nginx
            ports:
            - containerPort: 80
              protocol: TCP
          restartPolicy: Always
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: new-nginx
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        run: new-nginx
      sessionAffinity: None
      type: NodePort

    マニフェストを適用します:

    kubectl apply -f nginx1.yaml
  2. 新しいバージョンにトラフィックをルーティングするためのカナリア Ingress を作成します。3 つの戦略が利用可能です。戦略 A:リクエストヘッダーによるルーティング foo ヘッダーが bar と等しい場合にのみ、リクエストを新しいバージョンにルーティングします。その他のリクエストは古いバージョンにルーティングされます。次の内容を ingress1.yaml として保存します。v1.19 以降のクラスターの場合:

    • `foo: bar` ヘッダーあり:トラフィックの 100% が new-nginx にルーティングされます (canary-by-headercanary-by-header-value によって制御)。

    • `foo: bar` ヘッダーなし:トラフィックの 50% が new-nginx にルーティングされます (canary-weight によって制御)。

    v1.19 以降のクラスター

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release-canary
      annotations:
        # カナリアルーティングを有効にする
        nginx.ingress.kubernetes.io/canary: "true"
        # foo ヘッダーが bar と等しい場合に new-nginx にルーティングする
        nginx.ingress.kubernetes.io/canary-by-header: "foo"
        nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          # サービスの新バージョン
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    v1.19 より前のクラスター

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release-canary
      annotations:
        nginx.ingress.kubernetes.io/canary: "true"
        nginx.ingress.kubernetes.io/canary-by-header: "foo"
        nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
        nginx.ingress.kubernetes.io/canary-weight: "50"
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    マニフェストを適用して検証します:

    kubectl get ingress
    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    ヘッダーなしでテストします (旧バージョンにルーティングされます):

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    期待される出力:old foo: bar ヘッダーありでテストします (新バージョンにルーティングされます):

    curl -H "Host: www.example.com" -H "foo: bar" http://<EXTERNAL_IP>

    期待される出力:new

    戦略 B:ヘッダーによるルーティングと残りのトラフィックの重みによる分割

    foo=bar を含むすべてのリクエストを新バージョンにルーティングし、その他のリクエストの 50% を新バージョンにルーティングします。次の内容で ingress1.yaml を更新します。

    v1.19 以降のクラスター

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release-canary
      annotations:
        nginx.ingress.kubernetes.io/canary: "true"
        # すべてのトラフィックの 50% を new-nginx にルーティングします。デフォルトの合計の重みは 100 です。
        nginx.ingress.kubernetes.io/canary-weight: "50"
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    v1.19 より前のクラスター

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release-canary
      annotations:
        nginx.ingress.kubernetes.io/canary: "true"
        nginx.ingress.kubernetes.io/canary-by-header: "foo"
        nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
        nginx.ingress.kubernetes.io/canary-weight: "50"
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    マニフェストを適用します:

    kubectl apply -f ingress1.yaml

    戦略 C:重みのみによるルーティング

    ヘッダーや Cookie に関係なく、トラフィックの 50% を新バージョンにルーティングします。次の内容で ingress1.yaml を更新します。

    v1.19 以降のクラスター

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release-canary
      annotations:
        nginx.ingress.kubernetes.io/canary: "true"
        # すべてのトラフィックの 50% を new-nginx にルーティングする。デフォルトの合計の重みは 100
        nginx.ingress.kubernetes.io/canary-weight: "50"
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    v1.19 より前のクラスター

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release-canary
      annotations:
        nginx.ingress.kubernetes.io/canary: "true"
        nginx.ingress.kubernetes.io/canary-weight: "50"
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    マニフェストを適用します:

    kubectl apply -f ingress1.yaml

    検証:このコマンドを数回実行します。応答の約 50% が new を返すはずです。

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

ステップ 3:トラフィックの完全な切り替え

新バージョンが安定したら、旧バージョンを廃止します。

  1. nginx.yaml を更新して、古い Service を新しい Deployment にリダイレクトします。

    YAML ファイルの表示

    apiVersion: v1
    kind: Service
    metadata:
      name: old-nginx
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        # 新しいサービスバージョンを指す
        run: new-nginx
      sessionAffinity: None
      type: NodePort

    更新を適用します:

    kubectl apply -f nginx.yaml
  2. すべてのトラフィックが新バージョンにルーティングされることを確認します:

    kubectl get ingress
    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    期待される出力:new

  3. カナリア Ingress を削除します:

    kubectl delete ingress gray-release-canary
  4. 古い Deployment と新しい Service を削除します:

    kubectl delete deploy old-nginx
    kubectl delete svc new-nginx

service-* アノテーション方式

重要

service-* アノテーションは、Nginx Ingress Controller v1.12 以降では使用できなくなりました。使用しないでください。

アノテーションリファレンス

アノテーション 説明
nginx.ingress.kubernetes.io/service-match リクエスト属性をサービスにマッピングするルーティングルールを定義します。構文:nginx.ingress.kubernetes.io/service-match: | <service-name>: <match-rule>。サポートされているマッチタイプ:headercookiequery。マッチフォーマット:正規表現 /regular expression/、完全一致 "exact value"。例:new-nginx: header("foo", /^bar$/)new-nginx: header("foo", "bar")new-nginx: cookie("foo", /^sticky-.+$/)new-nginx: query("foo", "bar")
nginx.ingress.kubernetes.io/service-weight 新旧のサービスバージョン間のトラフィックの重みを設定します。構文:nginx.ingress.kubernetes.io/service-weight: | <new-svc-name>:<new-svc-weight>, <old-svc-name>:<old-svc-weight>。例:new-nginx: 20, old-nginx: 60

ステップ 1:サービスのデプロイ

Nginx サービスをデプロイし、Nginx Ingress Controller を使用してレイヤー 7 ドメインアクセス用に公開します。

  1. Deployment と Service を作成します。次の内容を nginx.yaml として保存します。

    YAML ファイルの表示

    old

    マニフェストを適用します:

    kubectl apply -f nginx.yaml
  2. Ingress を作成します。次の内容を ingress.yaml として保存します。

    v1.19 以降のクラスター

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          # サービスの旧バージョン
          - path: /
            backend:
              service:
                name: old-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    v1.19 より前のクラスター

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    マニフェストを適用します:

    kubectl apply -f ingress.yaml
    kubectl get ingress
  3. デプロイメントを検証します。外部 IP アドレスを取得します:

    kubectl get ingress

    ルーティングアクセスを確認します:

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    期待される出力:

    old

ステップ 2:新しいサービスバージョンのリリース

新しい Nginx バージョンをデプロイし、ルーティングルールを構成します。

  1. 新しい Deployment と Service を作成します。次の内容を nginx1.yaml として保存します。

    YAML ファイルの表示

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: new-nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: new-nginx
      template:
        metadata:
          labels:
            run: new-nginx
        spec:
          containers:
          - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx
            imagePullPolicy: Always
            name: new-nginx
            ports:
            - containerPort: 80
              protocol: TCP
          restartPolicy: Always
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: new-nginx
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        run: new-nginx
      sessionAffinity: None
      type: NodePort

    マニフェストを適用します:

    kubectl apply -f nginx1.yaml
  2. gray-release Ingress を変更します。3 つの戦略が利用可能です。戦略 A:リクエストヘッダーによるルーティング foo ヘッダーが bar と一致する場合にのみ、リクエストを新しいバージョンにルーティングします。次の内容で ingress.yaml を更新します。v1.19 以降のクラスターの場合:

    v1.19 以降のクラスター

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release
      annotations:
        # foo ヘッダーが ^bar$ と一致する場合に new-nginx にルーティングする
        nginx.ingress.kubernetes.io/service-match: |
          new-nginx: header("foo", /^bar$/)
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          # サービスの旧バージョン
          - path: /
            backend:
              service:
                name: old-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific
          # サービスの新バージョン
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    v1.19 より前のクラスター

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release
      annotations:
        nginx.ingress.kubernetes.io/service-match: |
            new-nginx: header("foo", /^bar$/)
        nginx.ingress.kubernetes.io/service-weight: |
            new-nginx: 50, old-nginx: 50
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: old-nginx
              servicePort: 80
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    マニフェストを適用して検証します:

    kubectl apply -f ingress.yaml
    kubectl get ingress

    ヘッダーなしでテストします (旧バージョンにルーティングされます):

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    期待される出力:old foo: bar ヘッダーありでテストします (新バージョンにルーティングされます):

    curl -H "Host: www.example.com" -H "foo: bar" http://<EXTERNAL_IP>

    期待される出力:new

    戦略 B:重み付け分割を伴うヘッダーによるルーティング

    foo=bar に一致するリクエストを両方のバージョンにルーティングし、それぞれに 50% ずつ割り当てます。次の内容で ingress.yaml を更新します。

    v1.19 以降のクラスター

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release
      annotations:
        nginx.ingress.kubernetes.io/service-match: |
            new-nginx: header("foo", /^bar$/)
        # 一致するリクエストのうち、50% を new-nginx に、50% を old-nginx にルーティングする
        nginx.ingress.kubernetes.io/service-weight: |
            new-nginx: 50, old-nginx: 50
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              service:
                name: old-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    v1.19 より前のクラスター

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release
      annotations:
        nginx.ingress.kubernetes.io/service-match: |
            new-nginx: header("foo", /^bar$/)
        nginx.ingress.kubernetes.io/service-weight: |
            new-nginx: 50, old-nginx: 50
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: old-nginx
              servicePort: 80
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    マニフェストを適用します:

    kubectl apply -f ingress.yaml

    テストコマンドを数回実行します。foo: bar リクエストの約 50% が new を返すはずです。

    戦略 C:重みのみによるルーティング

    トラフィックの 50% を新バージョンにルーティングします。次の内容で ingress.yaml を更新します。

    v1.19 以降のクラスター

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release
      annotations:
        # すべてのトラフィックの 50% を new-nginx にルーティングする
        nginx.ingress.kubernetes.io/service-weight: |
            new-nginx: 50, old-nginx: 50
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              service:
                name: old-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    v1.19 より前のクラスター

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release
      annotations:
        nginx.ingress.kubernetes.io/service-weight: |
            new-nginx: 50, old-nginx: 50
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: old-nginx
              servicePort: 80
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    マニフェストを適用します:

    kubectl apply -f ingress.yaml

    検証:このコマンドを数回実行します。応答の約 50% が new を返すはずです。

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

ステップ 3:トラフィックの完全な切り替え

新バージョンが安定したら、旧バージョンを廃止します。

  1. v1.19 以降のクラスター

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          # サービスの新バージョン
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    v1.19 より前のクラスター

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    更新を適用します:

    kubectl apply -f ingress.yaml
  2. すべてのトラフィックが新バージョンにルーティングされることを確認します:

    kubectl get ingress
    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    期待される出力:new

  3. 古い Deployment と Service を削除します:

    kubectl delete deploy <Deployment_name>
    kubectl delete svc <Service_name>