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

Microservices Engine:Kruise Rollouts を使用して MSE ベースのエンドツーエンドカナリアリリースを実装する

最終更新日:Jan 08, 2025

Kubernetes アプリケーションデプロイメントツールとして、Kruise Rollouts は、カナリアリリースやブルーグリーンデプロイメントなど、さまざまなカナリアリリースポリシーを提供します。 Kruise Rollouts を Microservices Engine (MSE) マイクロサービスガバナンスと共に使用して、サービス呼び出しプロセス中にアプリケーションの新しいバージョンのスムーズなカナリアリリースを実装できます。 これにより、新しいバージョンの安定性が確保されます。

エンドツーエンドカナリアリリースの概要

従来のカナリアリリースモードでは、マイクロサービスアーキテクチャが使用されているシナリオでの複雑な配信要件を満たすことができません。 エンドツーエンドカナリアリリース機能は、各マイクロサービスアプリケーションのカナリアトラフィックをカナリア環境またはグループにルーティングするために導入されました。 開発者は、トラフィックがアップストリームカナリア環境からダウンストリームカナリア環境に流れることを期待しています。 このようにして、リクエストはカナリア環境内に残り、トラフィックレーンが生成されます。 トラフィックレーンでは、呼び出しプロセスに含まれる一部のマイクロサービスアプリケーションにそれぞれのカナリア環境がない場合でも、これらのマイクロサービスアプリケーションのリクエストをダウンストリームカナリア環境にルーティングできます。 この場合、システムの安定性を確保するために、複数のサービスへの変更を同時にリリースできます。 次の図は、エンドツーエンドカナリアリリースのプロセスを示しています。

image.png

Kruise Rollouts の概要

Kruise Rollouts は、OpenKruise によって提供されるオープンソースのプログレッシブロールアウトフレームワークです。 詳細については、「Kruise Rollouts」をご参照ください。 Kruise Rollouts を使用して、カナリアリリース、ブルーグリーンデプロイメント、A/B テストを実行できます。 また、Kruise Rollouts を使用して、カナリアトラフィックとポッドを制御することもできます。 リリースプロセスはバッチで自動化し、Managed Service for Prometheus のメトリックに基づいて一時停止できます。 Kruise Rollouts はバイパスの認識できない接続も提供し、Deployments、CloneSets、StatefulSets など、さまざまなワークロードと互換性があります。 詳細については、「Kruise Rollouts」をご参照ください。

Kruise Rollouts はバイパスコンポーネントです。 Container Service for Kubernetes (ACK) クラスタに Rollouts リソースを作成するだけで、アプリケーションのリリースと更新を自動化できます。 Kruise Rollouts は、Helm および PaaS プラットフォームとの低コストでのシームレスな統合をサポートしています。 次の図は、Kruise Rollouts を使用したカナリアリリースのアーキテクチャを示しています。image.png

前提条件

手順 1: 準備を行う

  1. Kruise Rollouts コンポーネントをインストールします。

    1. ACK コンソール にログインします。 左側のナビゲーションペインで、[クラスタ] をクリックします。

    2. [クラスタ] ページで、管理するクラスタを見つけて、その名前をクリックします。 左側のナビゲーションペインで、[操作] > [アドオン] を選択します。

    3. コンポーネントの管理 ページで、アプリケーションの管理 タブをクリックします。

    4. [ack-kruise] カードを見つけて、[インストール] をクリックします。

    5. 表示されるメッセージで、[OK] をクリックします。

  2. MSE Ingress Controller コンポーネントをインストールします。 MseIngressConfig リソースと IngressClass リソースを作成します。 詳細については、「MSE Ingress を使用して ACK クラスタ内のアプリケーションにアクセスする」をご参照ください。

  3. アプリケーションのマイクロサービスガバナンスを有効にします。 詳細については、「ACK クラスタ内のマイクロサービスアプリケーションのマイクロサービスガバナンスを有効にする」をご参照ください。

手順 2: デモアプリケーションをデプロイする

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

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

      コードの表示

      # サービス
      apiVersion: v1
      kind: Service
      metadata:
        name: spring-cloud-a
      spec:
        ports:
          - name: http
            port: 20001
            protocol: TCP
            targetPort: 20001
        selector:
          app: spring-cloud-a
      # アプリケーション a
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: spring-cloud-a
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: spring-cloud-a
        template:
          metadata:
            annotations:
              msePilotCreateAppName: spring-cloud-a  # アプリケーション名を設定
            labels:
              app: spring-cloud-a
          spec:
            containers:
              - env:
                  - name: JAVA_HOME
                    value: /usr/lib/jvm/java-1.8-openjdk/jre
                image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-a:mse-2.0.0
                imagePullPolicy: Always
                name: spring-cloud-a
                ports:
                  - containerPort: 20001
      # アプリケーション b
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: spring-cloud-b
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: spring-cloud-b
        template:
          metadata:
            annotations:
              msePilotCreateAppName: spring-cloud-b # アプリケーション名を設定
            labels:
              app: spring-cloud-b
          spec:
            containers:
              - env:
                  - name: JAVA_HOME
                    value: /usr/lib/jvm/java-1.8-openjdk/jre
                image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-b:mse-2.0.0
                imagePullPolicy: Always
                name: spring-cloud-b
      # アプリケーション c
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: spring-cloud-c
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: spring-cloud-c
        template:
          metadata:
            annotations:
              msePilotCreateAppName: spring-cloud-c # アプリケーション名を設定
            labels:
              app: spring-cloud-c
          spec:
            containers:
              - env:
                  - name: JAVA_HOME
                    value: /usr/lib/jvm/java-1.8-openjdk/jre
                image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-c:mse-2.0.0
                imagePullPolicy: Always
                name: spring-cloud-c
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nacos-server
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: nacos-server
        template:
          metadata:
            labels:
              app: nacos-server
          spec:
            containers:
            - env:
              - name: MODE
                value: standalone
              image: nacos/nacos-server:v2.2.0
              imagePullPolicy: Always
              name: nacos-server
            dnsPolicy: ClusterFirst
            restartPolicy: Always
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: nacos-server
      spec:
        type: ClusterIP
        ports:
          - name: nacos-server-8848-8848
            port: 8848
            protocol: TCP
            targetPort: 8848
          - name: nacos-server-9848-9848
            port: 9848
            protocol: TCP
            targetPort: 9848
        selector:
          app: nacos-server
      ---
      apiVersion: v1
      kind: Service
      metadata:
        labels:
          app: demo-mysql
        name: demo-mysql
      spec:
        ports:
          - port: 3306
            targetPort: 3306
        selector:
          app: demo-mysql
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: demo-mysql
      spec:
        selector:
          matchLabels:
            app: demo-mysql
        replicas: 1
        strategy:
          type: Recreate
        template:
          metadata:
            labels:
              app: demo-mysql
          spec:
            containers:
              - args:
                  - --character-set-server=utf8mb4
                  - --collation-server=utf8mb4_unicode_ci
                env:
                  - name: MYSQL_ROOT_PASSWORD
                    value: root
                image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/demo-mysql:3.0.1
                name: demo-mysql
                ports:
                  - containerPort: 3306
    2. 次のコマンドを実行して、ビジネスアプリケーションをデプロイします。

      kubectl apply -f mse-demo.yaml
    3. mse-Ingress.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。

      コードの表示

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        annotations:
          mse.ingress.kubernetes.io/service-subset: ""
        name: spring-cloud-a
      spec:
        ingressClassName: mse
        rules:
          - http:
              paths:
                - backend:
                    service:
                      name: spring-cloud-a
                      port:
                        number: 20001
                  path: /
                  pathType: Prefix
    4. 次のコマンドを実行して、Ingress ルールを作成します。

      kubectl apply -f mse-ingress.yaml
    5. 次のコマンドを実行して、パブリック IP アドレスをクエリします。

      kubectl get ingress

      期待される出力:

      NAME         CLASS    HOSTS   ADDRESS        PORTS   AGE
      spring-cloud-a   <none>   *       EXTERNAL_IP     80     12m
    6. 次のコマンドを実行して、ルートステータスを確認します。 <EXTERNAL_IP> は、前の手順で取得した IP アドレスに置き換えます。

      curl http://<EXTERNAL_IP>/A/a

      期待される出力:

      A[192.168.42.115][config=base] -> B[192.168.42.118] -> C[192.168.42.101]% 

手順 3: Kruise Rollouts を使用して自動エンドツーエンドカナリアリリースを実装する

  1. Kruise Rollouts のカナリアリリースルールを定義します。

    説明

    この例では、カナリアリリースは 3 つのバッチで実行されます。

    1. A/B テストが実行されます。 header[User-Agent]=xiaoming を含むリクエストはカナリアバージョンに転送されます。 その他のリクエストはベースバージョンに転送されます。

    2. ポッドの半分がカナリアバージョンを実行し、リクエストの半分がカナリアバージョンに転送されます。

    3. すべてのポッドがカナリアバージョンを実行し、すべてのリクエストがカナリアバージョンに転送されます。

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

      コードの表示

      # エンドツーエンドカナリアリリースのアプリケーションのロールアウト構成を指定します。
      # ロールアウト構成 a
      apiVersion: rollouts.kruise.io/v1alpha1
      kind: Rollout
      metadata:
        # rollout-b や rollout-c など、他のマイクロサービスアプリケーションの同様の構成。
        name: rollout-a
        annotations:
          rollouts.kruise.io/trafficrouting: mse-traffic
      spec:
        objectRef:
          workloadRef:
            apiVersion: apps/v1
            kind: Deployment
            name: spring-cloud-a
        strategy:
          canary:
            steps:
            - pause: {} # 最初の手順の後で一時停止します。
              replicas: 1 # カナリアレプリカの数を 1 に設定します。
            patchPodTemplateMetadata: # カナリアポッドのメタデータにパッチを適用します。
              labels:
                alicloud.service.tag: gray # カナリアポッドにラベルを追加します。
                opensergo.io/canary-gray: gray # カナリアポッドにラベルを追加します。
      ---
      # ロールアウト構成 b
      apiVersion: rollouts.kruise.io/v1alpha1
      kind: Rollout
      metadata:
        name: rollout-b
        annotations:
          rollouts.kruise.io/trafficrouting: mse-traffic
      spec:
        objectRef:
          workloadRef:
            apiVersion: apps/v1
            kind: Deployment
            name: spring-cloud-b
        strategy:
          canary:
            steps:
              - pause: {} # 最初の手順の後で一時停止します。
                replicas: 1 # カナリアレプリカの数を 1 に設定します。
            patchPodTemplateMetadata: # カナリアポッドのメタデータにパッチを適用します。
              labels:
                alicloud.service.tag: gray # カナリアポッドにラベルを追加します。
                opensergo.io/canary-gray: gray # カナリアポッドにラベルを追加します。
      ---
      # ロールアウト構成 c
      apiVersion: rollouts.kruise.io/v1alpha1
      kind: Rollout
      metadata:
        name: rollout-c
        annotations:
          rollouts.kruise.io/trafficrouting: mse-traffic
      spec:
        objectRef:
          workloadRef:
            apiVersion: apps/v1
            kind: Deployment
            name: spring-cloud-c
        strategy:
          canary:
            steps:
              - pause: {} # 最初の手順の後で一時停止します。
                replicas: 1 # カナリアレプリカの数を 1 に設定します。
            patchPodTemplateMetadata: # カナリアポッドのメタデータにパッチを適用します。
              labels:
                alicloud.service.tag: gray # カナリアポッドにラベルを追加します。
                opensergo.io/canary-gray: gray # カナリアポッドにラベルを追加します。
      
      ---
      # レーンに基づいてエンドツーエンドカナリアリリースを構成します。
      apiVersion: rollouts.kruise.io/v1alpha1
      kind: TrafficRouting
      metadata:
        name: mse-traffic
      spec:
        objectRef:
        - service: spring-cloud-a
          ingress:
            classType: mse
            name: spring-cloud-a
        strategy:
          matches:
          # A/B テストを実行します。 トラフィックはリクエストヘッダーに基づいてルーティングされます。
          - headers:
            - type: Exact
              name: User-Agent
              value: xiaoming
              # リクエストの半分がカナリアバージョンに転送されます。
          # weight 値は 30 です。 リクエストの 30% がカナリアバージョンに転送されます。
          requestHeaderModifier: # リクエストヘッダーを変更します。
            set:
            - name: x-mse-tag # ヘッダー名を設定します。
              value: gray # ヘッダー値を設定します。
      

    2. 次のコマンドを実行して、ACK クラスタに Rollouts リソースをデプロイします。

      kubectl apply -f rollout.yaml
    3. 次のコマンドを実行して、Rollouts リソースのステータスをクエリします。

      kubectl get rollout

      STATUS=Healthy が期待どおりに返された場合、Rollouts リソースは正しく動作しています。

  2. アプリケーションを更新します。

    Kruise Rollouts は共通の構成であり、クラスタに配布するだけで済みます。 新しいアプリケーションバージョンをリリースするには、デプロイメントを更新するだけで済みます。 Kruise Rollouts を再度構成する必要はありません。 たとえば、spring-cloud-a と spring-cloud-c のイメージバージョンを mse-2.0.1 に直接更新してから、kubectl apply -f mse-demo.yaml コマンドを実行して、デプロイメントをクラスタにデプロイできます。 kubectl に加えて、Helm または Vela を使用してデプロイメントをクラスタにデプロイできます。

    • mse-demo.yaml ファイルを変更して、spring-cloud-a と spring-cloud-c のイメージバージョンを mse-2.0.1 に更新します。

      コードの表示

      # アプリケーション a
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: spring-cloud-a
        ...
            containers:
              - env:
                  - name: JAVA_HOME
                    value: /usr/lib/jvm/java-1.8-openjdk/jre
                image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-a:mse-2.0.1 # イメージバージョンを更新
                imagePullPolicy: Always
                name: spring-cloud-a
                ports:
                  - containerPort: 20001
      ...
      # アプリケーション c
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: spring-cloud-c
      spec:
        ...
                image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-c:mse-2.0.1 # イメージバージョンを更新
      
    • 次のコマンドを実行して、Rollouts リソースのステータスをクエリします。

      kubectl get rollouts rollouts-a -n default
      kubectl get rollouts rollouts-c -n default

      期待される出力:

      NAME            STATUS        CANARY_STEP   CANARY_STATE   MESSAGE                                                                         AGE
      rollouts-a   Progressing   1             StepPaused     Rollout is in step(1/1), and you need manually confirm to enter the next step   41m
      rollouts-c   Progressing   1             StepPaused     Rollout is in step(1/1), and you need manually confirm to enter the next step   41m

      STATUS 列と CANARY_STATE 列を確認して、Rollouts リソースのステータスとリリースステージを表示できます。

      • STATUS=Progressing が返された場合、カナリアリリースステージは進行中です。

      • CANARY_STATE=StepPaused が返された場合、現在のバッチがリリースされます。 次のバッチをリリースするには、手動構成が必要です。

  3. カナリアバージョンが期待どおりに実行されていることを確認したら、残りのバッチをリリースできます。

    前の手順では、カナリアバージョンのアプリケーションの一部のみをリリースし、リクエストの一部をカナリアバージョンに転送します。 アプリケーションログとメトリックデータに基づいてカナリアバージョンが期待どおりに実行されていることを確認したら、rollout.rollouts.kruise.io/<rollouts-demo> approved コマンドを実行して、カナリアバージョンの残りのアプリケーションをリリースできます。 <rollouts-demo> は、Rollouts リソースの名前を示します。

  4. オプション。 新しいアプリケーションバージョンが期待どおりに実行されない場合は、アプリケーションバージョンをロールバックします。

    リリースプロセス中にカナリアバージョンが期待どおりに実行されない場合は、デプロイメント構成を変更してから、kubectl apply -f mse-demo.yaml コマンドを実行して、アプリケーションバージョンをロールバックします。 Rollouts リソースで変更操作を実行する必要はありません。

マイクロサービスガバナンスのエンドツーエンドカナリアリリース機能はレーンを提供し、テストとリリース中の検証を大幅に容易にします。 マイクロサービスガバナンスを Kruise Rollouts と共に使用することで、DevOps プロセスにおけるオンラインアプリケーションの安定性を大幅に向上させることができます。