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

:ACK クラスタで ALB Ingress を使用してカナリアリリースを実行する

最終更新日:Dec 27, 2024

カナリアリリースは、一般的に使用されるソフトウェアリリース戦略です。サービスのイテレーション中に本番環境でシステムの安定性を確保するために、新しいサービスバージョンをすべてのユーザーに段階的にプッシュできます。Application Load Balancer (ALB) Ingress を使用すると、カナリアアノテーションを使用して、ヘッダー、Cookie、および重みに基づいてカナリアリリースを実行できます。このトピックでは、カナリアリリースを実行するために ALB Ingress にカナリアアノテーションを追加する方法について説明します。

前提条件

注意事項

  • カナリアアノテーションに基づいて実装されたカナリアリリース規則の優先順位は、ヘッダー > Cookie > 重みです。上記のポリシーがすべて設定されている場合、ヘッダーベースの規則が優先的に使用されます。カナリアアノテーションの詳細については、ALB Ingress カナリアアノテーションを参照してください。

  • ヘッダーベースおよび Cookie ベースの規則は、同じ Ingress で重みベースの規則と設定することはできません。2 つの別々の Ingress で設定するか、カスタムルーティング規則を使用する必要があります。カスタムルーティング規則を使用すると、より複雑なルーティング条件に基づいてカナリアリリースを実行できます。詳細については、ALB Ingress のルーティング規則のカスタマイズを参照してください。

  • カナリアアノテーションを使用してカナリアリリースを実行する場合、ALB Ingress ルーティング規則が有効になる順序は、Ingress の名前空間または名前の辞書順によって異なります。カナリアリリース規則が正しい順序で適用されるようにするには、alb.ingress.kubernetes.io/order アノテーションを使用して順序を定義できます。alb.ingress.kubernetes.io/order の有効な値は 1 ~ 1000 です。デフォルト値は 10 です。値が小さいほど、優先順位が高くなります。たとえば、Ingress の優先順位を上げる場合は、alb.ingress.kubernetes.io/order 設定の値を小さくすることができます。

手順 1: アプリケーションを作成する

  1. tea という名前のサービスをデプロイします。

    1. tea-deploy.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: tea
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: tea
        template:
          metadata:
            labels:
              app: tea
          spec:
            containers:
            - name: tea
              image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx:latest
              ports:
              - containerPort: 80
    2. 次のコマンドを実行して、tea サービスをデプロイします。

      kubectl apply -f tea-deploy.yaml
  2. tea-svc という名前のサービスをデプロイします。

    1. tea-svc.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。

      apiVersion: v1
      kind: Service
      metadata:
        name: tea-svc
      spec:
        ports:
        - port: 80
          targetPort: 80
          protocol: TCP
        selector:
          app: tea
        type: ClusterIP
    2. 次のコマンドを実行して、tea-svc サービスをデプロイします。

      kubectl apply -f tea-svc.yaml
  3. tea-ingress という名前の Ingress をデプロイします。

    1. tea-ingress.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: tea-ingress
      spec:
        ingressClassName: alb
        rules:
         - host: demo.domain.ingress.top # ドメイン名に置き換え、Ingress コントローラーが存在するロードバランサーの IP アドレスに解決できることを確認します。
           http:
            paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: tea-svc
                  port:
                    number: 80
    2. 次のコマンドを実行して、Ingress をデプロイします。

      kubectl apply -f tea-ingress.yaml
  4. デプロイが成功したことを確認します。

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

      curl -H Host:demo.domain.ingress.top http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com

      予期される出力:

      old

手順 2: 新しいサービスバージョンのカナリアリリースを実行する

新しいサービスバージョンと新しい Ingress をデプロイして、location: hz ヘッダーを持つすべてのリクエストを canary という名前の新しいサービスバージョンにルーティングし、他のリクエストの 50% を新しいサービスバージョンにルーティングします。他のリクエストには、他のヘッダーを持つリクエストとヘッダーを持たないリクエストが含まれます。

  1. canary という名前の新しいサービスバージョンをデプロイします。

    1. canary-deploy.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: canary
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: canary
        template:
          metadata:
            labels:
              app: canary
          spec:
            containers:
            - name: canary
              image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx:latest
              ports:
              - containerPort: 80
    2. 次のコマンドを実行して、canary サービスをデプロイします。

      kubectl apply -f canary-deploy.yaml
  2. canary-svc という名前のサービスをデプロイします。

    1. canary-svc.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。

      apiVersion: v1
      kind: Service
      metadata:
        name: canary-svc
      spec:
        ports:
        - port: 80
          targetPort: 80
          protocol: TCP
        selector:
          app: canary
        type: ClusterIP
    2. 次のコマンドを実行して、canary-svc サービスをデプロイします。

      kubectl apply -f canary-svc.yaml
  3. ヘッダーに基づいてリクエストをルーティングする Ingress をデプロイします。

    1. canary-header-ingress.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        annotations:
          alb.ingress.kubernetes.io/canary: "true"
          alb.ingress.kubernetes.io/canary-by-header: "location"
          alb.ingress.kubernetes.io/canary-by-header-value: "hz"
        name: canary-header-ingress
        namespace: default
      spec:
        ingressClassName: alb
        rules:
          - host: demo.domain.ingress.top # ドメイン名に置き換え、Ingress コントローラーが存在するロードバランサーの IP アドレスに解決できることを確認します。
            http:
              paths:
                - backend:
                    service:
                      name: canary-svc
                      port:
                        number: 80
                  path: /
                  pathType: Prefix
      • alb.ingress.kubernetes.io/canarytrue に設定して、カナリアアノテーションを有効にします。

      • alb.ingress.kubernetes.io/canary-by-header および alb.ingress.kubernetes.io/canary-by-header-value を、一致させたいヘッダーのキーと値に設定します。この例では、ヘッダーの KV ペアは location: hz に設定されています。location: hz ヘッダーを持つすべてのリクエストは、新しいサービスバージョンにルーティングされます。他のヘッダーを持つリクエストは、規則の優先順位に基づいて他のカナリアリリース規則と照合され、一致する規則に関連付けられたサービスバージョンにルーティングされます。

    2. 次のコマンドを実行して、ヘッダーに基づいてリクエストをルーティングする Ingress をデプロイします。

      kubectl apply -f canary-header-ingress.yaml
  4. 重みに基づいてリクエストをルーティングする Ingress をデプロイします。

    1. canary-weight-ingress.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        annotations:
          alb.ingress.kubernetes.io/canary: "true"
          alb.ingress.kubernetes.io/canary-weight: "50"
        name: canary-weight-ingress
        namespace: default
      spec:
        ingressClassName: alb
        rules:
          - host: demo.domain.ingress.top # ドメイン名に置き換え、Ingress コントローラーが存在するロードバランサーの IP アドレスに解決できることを確認します。
            http:
              paths:
                - backend:
                    service:
                      name: canary-svc
                      port:
                        number: 80
                  path: /
                  pathType: Prefix

      alb.ingress.kubernetes.io/canary-weight: 新しいサービスバージョンにルーティングされるトラフィックの割合を指定します。この例では、値は 50 に設定されており、トラフィックの 50% が新しいサービスバージョンにルーティングされることを示しています。

    2. 次のコマンドを実行して、重みに基づいてリクエストをルーティングする Ingress をデプロイします。

      kubectl apply -f canary-weight-ingress.yaml
  5. カナリアリリースが成功したかどうかを確認します。

    1. 次のコマンドを実行して、ALB インスタンスの IP アドレスをクエリします。

      kubectl get ingress

      予期される出力:

      NAME                    CLASS   HOSTS                     ADDRESS                                              PORTS   AGE
      canary-header-ingress   alb     demo.domain.ingress.top   alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com   80      8m23s
      canary-weight-ingress   alb     demo.domain.ingress.top   alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com   80      8m16s
      tea-ingress             alb     demo.domain.ingress.top   alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com   80      7m5s
    2. 次のコマンドを複数回実行して、location: hz ヘッダーをサービスに送信するリクエストを送信します。

      curl -H Host:demo.domain.ingress.top -H "location:hz" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com

      予期される出力:

      new

      new は、location: hz ヘッダーを持つリクエストに対して返されます。 location: hz ヘッダーを持つリクエストは、新しいサービスバージョンにルーティングされます。

    3. 次のコマンドを複数回実行して、ヘッダーを含まないリクエストをサービスに送信します。

      curl -H Host:demo.domain.ingress.top http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com

      new は、ヘッダーを含まないリクエストの 50% に対して返され、old は、残りの 50% のリクエストに対して返されます。ヘッダーを含まないリクエストの 50% は、新しいサービスバージョンにルーティングされます。

    4. 次のコマンドを複数回実行して、location: bj ヘッダーを含むリクエストをサービスに送信します。

      curl -H Host:demo.domain.ingress.top -H "location:bj" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com

      new は、location: bj ヘッダーを含むリクエストの 50% に対して返され、old は残りの 50% のリクエストに対して返されます。 location: bj ヘッダーを含むリクエストの 50% は、新しいサービスバージョンにルーティングされます。

    location: hz ヘッダーを持つすべてのリクエストは、canary という名前の新しいサービスバージョンにルーティングされます。他のヘッダーを持ち、ヘッダーを持たないリクエストの50%のみが新しいサービスバージョンにルーティングされます。カナリアリリースは成功しました。

ステップ 3: 古いサービスバージョンの廃止

新しいサービスバージョンが一定期間期待どおりに動作したら、古いサービスバージョンを廃止し、新しいサービスバージョンのみを維持する必要があります。これを行うには、古いサービスバージョンのイングレスのサービスを新しいサービスバージョンに変更して、イングレスが新しいサービスバージョンにトラフィックをルーティングできるようにする必要があります。次に、カナリアイングレスを削除します。

  1. 次のコマンドを実行して、tea-ingress.yaml ファイルを変更します。

    vim tea-ingress.yaml

    次のコマンドを実行して、tea-ingress.yaml ファイルのサービスを tea-svc から canary-svc に変更します。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: tea-ingress
    spec:
      ingressClassName: alb
      rules:
       - host: demo.domain.ingress.top # ドメイン名を置き換え、イングレスコントローラーが存在するロードバランサーの IP アドレスに解決できることを確認します。
         http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: canary-svc # tea-svc を canary-svc に変更します。
                port:
                  number: 80
  2. 変更したイングレスを有効にするには、次のコマンドを実行します。

    kubectl apply -f tea-ingress.yaml
  3. 古いサービスバージョンが廃止されているかどうかを確認します。

    1. 次のコマンドを複数回実行して、location: hz ヘッダーを含むリクエストをサービスに送信します。

      curl -H Host:demo.domain.ingress.top -H "location:hz" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com

      予期される出力:

      new

      newlocation: hz ヘッダーを含むリクエストに対して返されます。location: hz ヘッダーを含むリクエストは、新しいサービスバージョンにルーティングされます。

    2. 次のコマンドを複数回実行して、ヘッダーを含まないリクエストをサービスに送信します。

      curl -H Host:demo.domain.ingress.top http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com

      予期される出力:

      new

      new がヘッダーを含まないリクエストに対して返されます。ヘッダーを含まないリクエストは、新しいサービスバージョンにルーティングされます。

    3. 次のコマンドを複数回実行して、location: bj ヘッダーを含むリクエストをサービスに送信します。

      curl -H Host:demo.domain.ingress.top -H "location:bj" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com

      予期される出力:

      new

      newlocation: bj ヘッダーを含むリクエストに対して返されます。location: bj ヘッダーを含むリクエストは、新しいサービスバージョンにルーティングされます。

    location: hz ヘッダーを含むリクエスト、他のヘッダーを含むリクエスト、およびヘッダーを含まないリクエストはすべて、新しいサービスバージョンにルーティングされます。古いサービスバージョンは廃止されました。

  4. 次のコマンドを実行して、canary-weight-ingress と canary-header-ingress という名前のカナリアイングレスを削除します。

    kubectl delete ingress canary-weight-ingress canary-header-ingress