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

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

最終更新日:Feb 25, 2026

サービスを更新する際には、ローリングアップグレード、ブルーグリーンリリース、段階的リリースなどのリリース方法を使用できます。このトピックでは、Container Service for Kubernetes (ACK) クラスター内の Nginx Ingress Controller を使用して、アプリケーションの段階的リリースを実装する方法について説明します。

背景情報

段階的リリースおよびブルーグリーンリリースでは、既存の本番環境と同一の新しい本番環境を作成します。特定のルールに基づき、古いバージョンに影響を与えることなく、徐々に新バージョンへトラフィックを誘導します。新バージョンが安定したら、すべてのトラフィックを新バージョンに切り替えます。

ブルーグリーンリリースは段階的リリースの一種です。一部のユーザーは引き続き旧バージョンのサービスを使用し、他のユーザーのトラフィックは新バージョンに切り替えられます。新バージョンが安定している場合、すべてのユーザーを徐々に新バージョンに移行します。

ACK コンソールの段階的リリース機能では、次の 2 つの方法がサポートされています。

  • canary-* アノテーション方式: canary-* アノテーションを使用して、ブルーグリーンリリースおよび段階的リリースを構成できます。canary-* アノテーションは、段階的リリースを実装するための公式コミュニティ方式です。

  • service-* アノテーション方式(非推奨): service-* アノテーションは、ACK Nginx Ingress Controller で段階的リリースを実装するために以前使用されていた方式です。

重要

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

利用シーン

クライアントリクエストに基づくトラフィック分割

オンライン環境でレイヤー 7 のサービスを提供している Service A があるとします。新機能を含む新バージョン Service A' をリリースしたい場合、Service A を直接置き換える代わりに、リクエストヘッダーに foo=bar が含まれている、または Cookie に foo=bar が含まれている場合にのみ、Service A' へのリクエストを転送できます。Service A' が安定して動作したら、Service A から Service A' へすべてのトラフィックを切り替え、その後 Service A をオフラインにします。

image

サービスの重みに基づくトラフィック分割

オンライン環境でレイヤー 7 のサービスを提供している Service B があるとします。いくつかの問題を修正し、新バージョン Service B' をリリースする必要があります。すべてのクライアントトラフィックを一度に新バージョンに切り替えるのではなく、20 % のトラフィックを Service B' に切り替えたいとします。Service B' が安定したら、Service B から Service B' へすべてのトラフィックを切り替え、その後 Service B をオフラインにします。

image

これらのアプリケーションリリース要件を満たすため、Alibaba Cloud Container Service Ingress Controller では次のトラフィック分割方法がサポートされています。

  • リクエストヘッダーに基づくトラフィック分割:段階的リリースおよび A/B テストのシナリオに適しています。

  • Cookie に基づくトラフィック分割:段階的リリースおよび A/B テストのシナリオに適しています。

  • クエリパラメーターに基づくトラフィック分割:段階的リリースおよび A/B テストのシナリオに適しています。

  • サービスの重みに基づくトラフィック分割:ブルーグリーンリリースのシナリオに適しています。

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

アノテーションの説明

Nginx Ingress Controller では、アプリケーションの段階的リリースをサポートするために、次の canary-* アノテーションを使用します。

アノテーション

説明

適用可能な ACK Nginx Ingress Controller バージョン

nginx.ingress.kubernetes.io/canary

  • このアノテーションを true に設定します。設定しない場合、他のルールは有効になりません。

  • 有効値:

    • truecanary 機能を有効化します。

    • falsecanary 機能を無効化します。

≥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 アノテーションと併用する必要があります。

≥v0.30.0

nginx.ingress.kubernetes.io/canary-by-header-pattern

  • リクエストヘッダーの値に基づく段階的リリースを指定し、正規表現を使用してマッチングを行います。

  • canary-by-header アノテーションと併用する必要があります。

  • 値は、リクエストヘッダーの値とマッチングするための正規表現です。

≥v0.44.0

nginx.ingress.kubernetes.io/canary-by-cookie

  • Cookie に基づく段階的リリースを指定します。例:nginx.ingress.kubernetes.io/canary-by-cookie: foo

  • Cookie の値:

    • alwaysfoo=always の場合、トラフィックはカナリアサービスにルーティングされます。

    • neverfoo=never の場合、トラフィックはカナリアサービスにルーティングされません。

  • Cookie が存在し、その値が always の場合にのみ、トラフィックが転送されます。

≥v0.22.0

nginx.ingress.kubernetes.io/canary-weight

  • 重みに基づく段階的リリースを指定します。

  • 値の範囲は 0 から合計重みまでです。

  • 合計重みが設定されていない場合、デフォルトは 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. デプロイメントおよびサービスを作成します。

    1. 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
    2. 次のコマンドを実行して、デプロイメントおよびサービスを作成します。

      kubectl apply -f nginx.yaml
  2. Ingress をデプロイします。

    1. 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
    2. 次のコマンドを実行して、Ingress をデプロイします。

      kubectl apply -f ingress.yaml
  3. アクセスをテストします。

    1. 次のコマンドを実行して、外部 IP アドレスを取得します。

      kubectl get ingress
    2. 次のコマンドを実行して、ルーティングアクセスを確認します。

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

      期待される出力:

      old

ステップ 2:新サービスバージョンの段階的リリース

Nginx サービスの新バージョンを公開し、ルーティングルールを構成します。

  1. デプロイメントおよびサービスの新バージョンをデプロイします。

    1. 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
    2. 次のコマンドを実行して、更新されたデプロイメントおよびサービスをデプロイできます。

      kubectl apply -f nginx1.yaml
  2. 新サービスバージョンにアクセスするためのルーティングルールを設定します。

    ACK では、次の 3 種類のルーティングルールがサポートされています。要件に応じて選択してください。

    • 特定のルールを満たすクライアントからのみ、新サービスバージョンへのアクセスを許可します。次の例では、リクエストヘッダーに foo=bar が含まれている場合にのみ、リクエストを新サービスバージョンにルーティングします。

      1. 上記の条件に基づき、ingress1.yaml ファイル内に gray-release-canary という名前の新しい Ingress リソースを作成します。

        v1.19 以降のクラスターの場合

        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:
          name: gray-release-canary
          annotations:
            # Canary を有効化します。
            nginx.ingress.kubernetes.io/canary: "true"
            # リクエストヘッダーは foo です。
            nginx.ingress.kubernetes.io/canary-by-header: "foo"
            # foo ヘッダーの値が bar の場合にのみ、リクエストを新サービスバージョン new-nginx にルーティングします。
            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:
            # Canary を有効化します。
            nginx.ingress.kubernetes.io/canary: "true"
            # リクエストヘッダーは foo です。
            nginx.ingress.kubernetes.io/canary-by-header: "foo"
            # foo ヘッダーの値が bar の場合にのみ、リクエストを新サービスバージョン new-nginx にルーティングします。
            nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
        spec:
          rules:
          - host: www.example.com
            http:
              paths:
              # サービスの新バージョン。
              - path: /
                backend:
                  serviceName: new-nginx
                  servicePort: 80
      2. 次のコマンドを実行して、Ingress をデプロイします。

        kubectl apply -f ingress1.yaml
      3. 次のコマンドを実行して、外部 IP アドレスを取得します。

        kubectl get ingress
      4. ルーティングアクセスを検証します。

        1. 次のコマンドを実行して、サービスにアクセスします。

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

          期待される出力:

          old
        2. ヘッダーに foo=bar を含むクライアントリクエストを使用して、次のコマンドを実行してサービスにアクセスします。

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

          期待される出力:

          new

        コマンドを再度実行します。出力から、ヘッダー foo=bar を含むクライアントリクエストのみが、新サービスバージョンにルーティングされていることがわかります。

    • 特定のルールに一致しないリクエストのうち、一定の割合を新しいアプリケーションバージョンにルーティングします。たとえば、必要な foo=bar ヘッダーを含まないリクエストについて、50 % のトラフィックを新しいアプリケーションバージョンにルーティングできます。

      1. ステップ 2 で作成した Ingress を、次の内容で変更します。

        v1.19 以降のクラスターの場合

        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:
          name: gray-release-canary
          annotations:
            # Canary を有効化します。
            nginx.ingress.kubernetes.io/canary: "true"
            # リクエストヘッダーは foo です。
            nginx.ingress.kubernetes.io/canary-by-header: "foo"
            # foo ヘッダーの値が bar の場合にのみ、リクエストを新サービスバージョン new-nginx にルーティングします。
            nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
            # 上記のルールを満たさない場合、50% のトラフィックを新サービスバージョン new-nginx にルーティングします。
            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:
            # Canary を有効化します。
            nginx.ingress.kubernetes.io/canary: "true"
            # リクエストヘッダーは foo です。
            nginx.ingress.kubernetes.io/canary-by-header: "foo"
            # foo ヘッダーの値が bar の場合にのみ、リクエストを新サービスバージョン new-nginx にルーティングします。
            nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
            # 上記のルールを満たさない場合、50% のトラフィックを新サービスバージョン new-nginx にルーティングします。
            nginx.ingress.kubernetes.io/canary-weight: "50"
        spec:
          rules:
          - host: www.example.com
            http:
              paths:
              # サービスの新バージョン。
              - path: /
                backend:
                  serviceName: new-nginx
                  servicePort: 80
      2. 次のコマンドを実行して、Ingress をデプロイします。

        kubectl apply -f ingress.yaml
      3. 次のコマンドを実行して、外部 IP アドレスを取得します。

        kubectl get ingress
      4. ルーティングアクセスを検証します。

        1. 次のコマンドを実行して、サービスにアクセスします。

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

          期待される出力:

          old

        2. ヘッダーに foo=bar を含むクライアントリクエストを使用して、次のコマンドを実行してサービスにアクセスします。

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

          期待される出力:

          new
        • foo=bar リクエストヘッダーあり:

          トラフィックの 100 % が新しい new-nginx サービスにルーティングされます。これは canary-by-header および canary-by-header-value によって制御されています。

        • foo=bar リクエストヘッダーなし:

          トラフィックの 50 % が新しい new-nginx サービスにルーティングされます。これは canary-weight によって制御されています。

    • リクエストの特定の割合を新サービスバージョンにルーティングします。次の例では、50 % のトラフィックを新サービスバージョンにルーティングします。

      1. ステップ 2 で作成した Ingress を、次の内容で変更します。

        v1.19 以降のクラスターの場合

        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:
          name: gray-release-canary
          annotations:
            # Canary を有効化します。
            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:
            # Canary を有効化します。
            nginx.ingress.kubernetes.io/canary: "true"
            # トラフィックの 50% を新サービスバージョン new-nginx にルーティングします。
            # デフォルトの合計値は 100 です。
            nginx.ingress.kubernetes.io/canary-weight: "50"
        spec:
          rules:
          - host: www.example.com
            http:
              paths:
              # サービスの新バージョン。
              - path: /
                backend:
                  serviceName: new-nginx
                  servicePort: 80
      2. 次のコマンドを実行して、Ingress をデプロイします。

        kubectl apply -f ingress.yaml

      3. 次のコマンドを実行して、外部 IP アドレスを取得します。

        kubectl get ingress

      4. 次のコマンドを実行して、ルーティングアクセスを検証します。

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

      コマンドを再度実行します。出力から、50 % のトラフィックが新サービスバージョンにルーティングされていることがわかります。

ステップ 3:旧サービスバージョンの削除

新サービスバージョンが安定しており、期待通りに動作することを確認したら、旧サービスバージョンをオフラインにして、新バージョンのみを実行状態にします。これを行うには、旧サービスを新バージョンのデプロイメントを指すように変更し、その後旧デプロイメントおよび新サービスを削除します。

  1. 旧サービスファイル nginx.yaml を変更して、新サービスを指すようにします。

    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
  2. 次のコマンドを実行して、サービスの旧バージョンをデプロイします。

    kubectl apply -f nginx.yaml
  3. 次のコマンドを実行して、外部 IP アドレスを取得します。

    kubectl get ingress
  4. 次のコマンドを実行して、ルーティングを確認します。

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

    期待される出力:

    new

    コマンドを再度実行します。すべてのリクエストが新サービスバージョンにルーティングされていることが確認できます。

  5. 次のコマンドを実行して、カナリア Ingress リソース gray-release-canary を削除します。

    kubectl delete ingress gray-release-canary
  6. 旧デプロイメントおよび新サービスを削除します。

    1. 次のコマンドを実行して、旧デプロイメントを削除します。

      kubectl delete deploy old-nginx
    2. 次のコマンドを実行して、新サービスを削除します。

      kubectl delete svc new-nginx

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

重要

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

アノテーションの説明

Nginx Ingress Controller では、アプリケーションサービスの段階的リリースをサポートするために、次のアノテーションを使用します。

  • nginx.ingress.kubernetes.io/service-match

    このアノテーションは、新サービスバージョンのルーティングルールを構成します。

    nginx.ingress.kubernetes.io/service-match: | 
        <service-name>: <match-rule>
    # メトリックの説明:
    # service-name: サービス名。match-rule に一致するリクエストはこのサービスにルーティングされます。
    # match-rule: ルーティングルール。
    #
    # ルーティングルール:
    # 1. サポートされるマッチタイプ
    # - header: リクエストヘッダーに基づく。正規表現マッチおよび完全一致をサポート。
    # - cookie: Cookie に基づく。正規表現マッチおよび完全一致をサポート。
    # - query: リクエストパラメーターに基づく。正規表現マッチおよび完全一致をサポート。
    #
    # 2. マッチ方法
    # - 正規表現マッチ形式: /{regular expression}/。スラッシュ (/) は正規表現マッチを示します。
    # - 完全一致形式: "{exact expression}"。二重引用符 ("") は完全一致を示します。

    ルーティングルール構成の例:

    # foo ヘッダーが正規表現 ^bar$ に一致するリクエストは、新サービスバージョン new-nginx に転送されます。
    new-nginx: header("foo", /^bar$/)
    # foo ヘッダーが bar と完全に一致するリクエストは、新サービスバージョン new-nginx に転送されます。
    new-nginx: header("foo", "bar")
    # foo Cookie が正規表現 ^sticky-.+$ に一致するリクエストは、新サービスバージョン new-nginx に転送されます。
    new-nginx: cookie("foo", /^sticky-.+$/)
    # foo クエリパラメーターが bar と完全に一致するリクエストは、新サービスバージョン new-nginx に転送されます。
    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-svc-name: 新サービスバージョンの名前。
    new-svc-weight: 新サービスバージョンの重み。
    old-svc-name: 旧サービスバージョンの名前。
    old-svc-weight: 旧サービスバージョンの重み。

    サービスの重み構成の例:

    nginx.ingress.kubernetes.io/service-weight: | 
        new-nginx: 20, old-nginx: 60

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

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

  1. デプロイメントおよびサービスを作成します。

    1. 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
    2. 次のコマンドを実行して、デプロイメントおよびサービスを作成します。

      kubectl apply -f nginx.yaml
  2. Ingress をデプロイします。

    1. 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
    2. 次のコマンドを実行して、Ingress をデプロイします。

      kubectl apply -f ingress.yaml
  3. アクセスをテストします。

    1. 次のコマンドを実行して、外部 IP アドレスを取得します。

      kubectl get ingress
    2. 次のコマンドを実行して、ルーティングアクセスを確認します。

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

      期待される出力:

      old

ステップ 2:新サービスバージョンの段階的リリース

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

  1. デプロイメントおよびサービスの新バージョンをデプロイします。

    1. 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
    2. デプロイメントおよびサービスの新バージョンをデプロイします。

      kubectl apply -f nginx1.yaml
  2. 新サービスバージョンにアクセスするためのルーティングルールを設定します。

    ACK では、次の 3 種類のルーティングルールがサポートされています。要件に応じて選択してください。

    • 特定のルールを満たすクライアントからのみ、新サービスバージョンへのリクエストをルーティングします。次の例では、リクエストヘッダーに foo=bar が含まれている場合にのみ、リクエストを新サービスバージョンにルーティングします。

      1. ステップ 2 で作成した Ingress を、次の内容で変更します。

      v1.19 以降のクラスターの場合

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: gray-release
        annotations:
          # foo ヘッダーが正規表現 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:
          # foo ヘッダーが正規表現 foo=bar に一致するリクエストは、新サービスバージョン new-nginx にルーティングされます。
          nginx.ingress.kubernetes.io/service-match: | 
            new-nginx: header("foo", /^bar$/)
      spec:
        rules:
        - host: www.example.com
          http:
            paths:
            # サービスの旧バージョン。
            - path: /
              backend:
                serviceName: old-nginx
                servicePort: 80
            # サービスの新バージョン。
            - path: /
              backend:
                serviceName: new-nginx
                servicePort: 80
      1. 次のコマンドを実行して、Ingress をデプロイします。

        kubectl apply -f ingress.yaml
      2. 次のコマンドを実行して、外部 IP アドレスを取得します。

        kubectl get ingress
      3. ルーティングアクセスを確認します。

        1. 次のコマンドを実行して、サービスにアクセスします。

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

          期待される出力:

          old

        2. ヘッダーに foo=bar を含むクライアントリクエストを使用して、次のコマンドを実行してサービスにアクセスします。

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

          期待される出力:

          new

      コマンドを再度実行します。出力から、ヘッダー foo=bar を含むクライアントリクエストのみが、新サービスバージョンにルーティングされていることがわかります。

    • 特定のルールを満たすリクエストのうち、一定の割合を新サービスバージョンにルーティングします。次の例では、ヘッダーに foo=bar を含むクライアントリクエストのうち、50 % のトラフィックを新サービスバージョンにルーティングします。

      1. ステップ 2 で作成した Ingress を、次の内容で変更します。

        v1.19 以降のクラスターの場合

        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:
          name: gray-release
          annotations:
            # foo ヘッダーが正規表現 foo=bar に一致するリクエストは、新サービスバージョン new-nginx にルーティングされます。
            nginx.ingress.kubernetes.io/service-match: |
                new-nginx: header("foo", /^bar$/)
            # 上記のルールに基づき、トラフィックの 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:
            # foo ヘッダーが正規表現 foo=bar に一致するリクエストは、新サービスバージョン new-nginx にルーティングされます。
            nginx.ingress.kubernetes.io/service-match: |
                new-nginx: header("foo", /^bar$/)
            # 上記のルールに基づき、トラフィックの 50% のみが新サービスバージョン new-nginx にルーティングされます。
            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
      2. 次のコマンドを実行して、Ingress をデプロイします。

        kubectl apply -f ingress.yaml
      3. 次のコマンドを実行して、外部 IP アドレスを取得します。

        kubectl get ingress

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

        1. 次のコマンドを実行して、サービスにアクセスします。

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

          期待される出力:

          old

        2. ヘッダーに foo=bar を含むクライアントリクエストを使用して、次のコマンドを実行してサービスにアクセスします。

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

          期待される出力:

          new

        コマンドを再度実行します。出力から、ヘッダー foo=bar を含むクライアントリクエストのうち、50 % のトラフィックのみが新サービスバージョンにルーティングされていることがわかります。

    • リクエストの一定の割合を新サービスバージョンにルーティングします。次の例では、50 % のトラフィックを新サービスバージョンにルーティングします。

      1. ステップ 2 で作成した Ingress を、次の内容で変更します。

        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:
              # トラフィックの 50% を新サービスバージョン new-nginx にルーティングします。
              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
      2. 次のコマンドを実行して、Ingress をデプロイします。

        kubectl apply -f ingress.yaml
      3. 次のコマンドを実行して、外部 IP アドレスを取得します。

        kubectl get ingress

      4. 次のコマンドを実行して、ルーティングアクセスを確認します。

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

        コマンドを再度実行します。出力から、50 % のトラフィックが新サービスバージョンにルーティングされていることがわかります。

ステップ 3:旧サービスバージョンの削除

新サービスバージョンが一定期間安定して動作し、期待通りの結果が得られた後は、旧サービスバージョンをオフラインにして、新バージョンのみを実行状態にします。

  1. ステップ 2 で作成した Ingress を、次の内容で変更します。

    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
  2. 次のコマンドを実行して、Ingress をデプロイします。

    kubectl apply -f ingress.yaml
  3. 次のコマンドを実行して、外部 IP アドレスを取得します。

    kubectl get ingress

  4. 次のコマンドを実行して、ルーティングアクセスを確認します。

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

    期待される出力:

    new

    コマンドを再度実行します。出力から、すべてのリクエストが新サービスバージョンにルーティングされていることがわかります。

  5. 旧デプロイメントおよびサービスを削除します。

    1. 次のコマンドを実行して、旧デプロイメントを削除します。

      kubectl delete deploy <Deployment_name>
    2. 次のコマンドを実行して、旧サービスを削除します。

      kubectl delete svc <Service_name>