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

:Spring Cloud サービスの管理

最終更新日:Apr 16, 2025

Spring Cloud アプリケーションを Service Mesh (ASM) に接続することで、クラウドネイティブなサービスガバナンス機能を使用して、アプリケーションコードを変更することなく Spring Cloud サービスを管理できます。このトピックでは、ASM を使用して Spring Cloud サービスを管理する方法について説明します。

前提条件

背景情報

Spring Cloud は、Spring Cloud Netflix、Spring Cloud Alibaba、Spring Cloud Consul など、さまざまな実装を持つ標準です。ASM では、Spring Cloud の実装における主な違いはサービスレジストリにあります。次の表は、これらの Spring Cloud 実装を使用して開発されたアプリケーションを ASM に移行できるかどうかを示しています。

Spring Cloud の実装

サービスレジストリ

コード変更なしの移行がサポートされているかどうか

Spring Cloud Alibaba

マイクロサービスエンジン (MSE) Nacos (Alibaba Cloud サービス)

はい

Spring Cloud Alibaba

セルフマネージド Nacos

はい

Spring Cloud Netflix

Eureka

サポートされています。ASM インスタンスのバージョンは 1.13.4.53 以降である必要があります。

Spring Cloud Consul

Consul

サポートされています。ASM インスタンスのバージョンは 1.13.4.53 以降である必要があります。

Spring Cloud Zookeeper

Zookeeper

サポートされています。ASM インスタンスのバージョンは 1.13.4.53 以降である必要があります。

デモの紹介

この例では、Nacos レジストリを使用した Spring Cloud を使用します。デモのサンプルコードは、GitHub の nacos-examples リポジトリからダウンロードできます。

Spring Cloud サービスには、コンシューマーサービスとプロバイダーサービスが含まれています。プロバイダーサービスには、V1 と V2 の 2 つのバージョンがあります。プロバイダーサービスの両方のバージョンが Nacos レジストリに登録されています。コンシューマーサービスは、Nacos レジストリから 2 つのバージョンのプロバイダーサービスのエンドポイントを取得し、負荷分散方式でエンドポイントにリクエストを送信します。コンシューマーサービスはポート 8080 を公開し、エコーインターフェイスを提供します。リクエストがプロバイダーサービスに転送されると、プロバイダーサービスは対応するレスポンスを返し、コンシューマーサービスはレスポンスを配信します。プロバイダーサービスの異なるバージョンは、異なるレスポンスを返します。

  • V1 のプロバイダーサービスは、エコーリクエストに対して次の情報で応答します。Hello Nacos Discovery From v1xxx

  • V2 のプロバイダーサービスは、エコーリクエストに対して次の情報で応答します。Hello Nacos Discovery From v2xxx

レスポンスの xxx 文字列は、対応するエコーリクエストの特定のパラメーターを示します。たとえば、/echo/world リクエストが V1 のプロバイダーサービスに送信されると、Hello Nacos Discovery From v1world レスポンスが返されます。demo

コンシューマーサービスとプロバイダーサービスが ASM インスタンスにデプロイされていない場合、つまり、サービスポッドに対してサイドカープロキシインジェクションが有効になっていない場合は、サービスにアクセスできますが、Istio リソースを使用してサービスを管理することはできません。

手順 1:ASM コントロールプレーンで Spring Cloud のサポートを有効にする

方法 1:すべての Spring Cloud の実装とレジストリに適用可能

説明

ASM インスタンスのバージョンは 1.13.4.32 以降である必要があります。

重要

制限事項:

  • Kubernetes サービスは、デスティネーションサービスとして作成する必要があります。サービスポートとデスティネーションポートは、Server Load Balancer (SLB) インスタンスを介してアプリケーションがルーティングされるポートである必要があります。

  • 1.23.6.32 以降の ASM インスタンスを使用する場合は、REGISTRY_ONLY を無効にする必要があります。

  1. kubectl を使用して、コントロールプレーンのクラスターに接続します。詳細については、「コントロールプレーンで kubectl を使用して Istio リソースにアクセスする」をご参照ください。

  2. ASM インスタンスに追加された ACK クラスタに Envoy フィルタを作成します。

    1. 次の内容で any-spring-cloud-support.yaml という名前のファイルを作成します。

      apiVersion: networking.istio.io/v1alpha3
      kind: EnvoyFilter
      metadata:
        labels:
          provider: "asm"
          asm-system: "true"
        name: any-spring-cloud-support
        namespace: istio-system
      spec:
        configPatches:
        - applyTo: HTTP_FILTER
          match:
            proxy:
              proxyVersion: "^1.*"
            context: SIDECAR_OUTBOUND
            listener:
              portNumber: 8070
              filterChain:
                filter:
                  name: "envoy.filters.network.http_connection_manager"
                  subFilter:
                    name: "envoy.filters.http.router"
          patch:
            operation: INSERT_BEFORE
            value: # reverse_dns フィルタの仕様
             name: com.aliyun.reverse_dns
             typed_config:
               "@type": "type.googleapis.com/udpa.type.v1.TypedStruct"
               type_url: type.googleapis.com/envoy.config.filter.reverse_dns.v3alpha.CommonConfig
               value:
                 pod_cidrs:
                 - "10.0.128.0/18"

      ビジネス要件に基づいて、ファイル内のパラメーター設定を変更します。いくつかのパラメーターは次のように説明されています。

      • portNumber: Spring Cloud サービスのポート番号を指定します。複数のポートがある場合は、このパラメーターを削除できます。ポートを統合できる場合は、複数の Envoy フィルタを作成し、各 Envoy フィルタでポート番号を設定できます。

      • pod_cidrs: ACK または ACK Serverless クラスタのポッド CIDR ブロックを指定します。Container Service for Kubernetes (ACK) コンソール にログインし、[クラスター] ページに移動して、目的のクラスターをクリックします。表示されるクラスター詳細ページで、[クラスターリソース] タブをクリックします。次に、VPC セクションのリンクをクリックして、[VPC] の vSwitch の CIDR ブロックを表示します。

    2. 次のコマンドを実行して、サービスに対して com.aliyun.reverse_dns フィルタを有効にします。

      kubectl apply -f any-spring-cloud-support.yaml

方法 2:Nacos レジストリのみに適用可能

  1. kubectl を使用して、コントロールプレーンのクラスターに接続します。詳細については、「コントロールプレーンで kubectl を使用して Istio リソースにアクセスする」をご参照ください。

  2. サービスエントリを作成します。

    1. 次の内容を含む external-nacos-svc.yaml ファイルを作成します。

      kind: ServiceEntry
      metadata:
        name: external-nacos-svc
      spec:
        hosts:
        - "NACOS_SERVER_HOST" ## この変数を Nacos サーバーホストのエンドポイントに置き換えます。例: mse-xxx-p.nacos-ans.mse.aliyuncs.com。
        location: MESH_EXTERNAL
        ports:
        - number: 8848
          name: http
        resolution: DNS

      上記の YAML ファイルでは、ポート 8848 は、Nacos で使用されるデフォルト ポートです。セルフマネージド Nacos サーバーと別のポートを使用する場合は、number パラメーターを使用するポート番号に設定します。

    2. 次のコマンドを実行して、サービスエントリを作成します。

      kubectl apply -f external-nacos-svc.yaml
  3. Envoy フィルタを作成します。

    1. 次の内容を含む external-envoyfilter.yaml ファイルを作成します。

      apiVersion: networking.istio.io/v1alpha3
      kind: EnvoyFilter
      metadata:
        labels:
          provider: "asm"
          asm-system: "true"
        name: nacos-subscribe-lua
        namespace: istio-system
      spec:
        configPatches:
          # 最初のパッチは、リスナー/ HTTP 接続マネージャーに lua フィルタを追加します。
        - applyTo: HTTP_FILTER
          match:
            proxy:
              proxyVersion: "^1.*"
            context: SIDECAR_OUTBOUND
            listener:
              portNumber: 8848
              filterChain:
                filter:
                  name: "envoy.filters.network.http_connection_manager"
                  subFilter:
                    name: "envoy.filters.http.router"
          patch:
            operation: INSERT_BEFORE
            value: # lua フィルタの仕様
             name: envoy.lua
             typed_config:
                "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
                inlineCode: |
                   -- 著作権: ASM (Alibaba Cloud ServiceMesh)
                   function envoy_on_request(request_handle)
                     local request_headers = request_handle:headers()
                     -- /nacos/v1/ns/instance/list?healthyOnly=false&namespaceId=public&clientIP=10.122.63.81&serviceName=DEFAULT_GROUP%40%40service-provider&udpPort=53174&encoding=UTF-8
                     local path = request_headers:get(":path")
                     if string.match(path,"^/nacos/v1/ns/instance/list") then
                       local servicename = string.gsub(path,".*&serviceName.*40([%w.\\_\\-]+)&.*","%1")
                       request_handle:streamInfo():dynamicMetadata():set("context", "request.path", path)
                       request_handle:streamInfo():dynamicMetadata():set("context", "request.servicename", servicename)
                       request_handle:logInfo("serviceName のサブスクライブ: " .. servicename)
                     else
                       request_handle:streamInfo():dynamicMetadata():set("context", "request.path", "")
                     end
                   end
                   function envoy_on_response(response_handle)
                     local request_path = response_handle:streamInfo():dynamicMetadata():get("context")["request.path"]
                     if request_path == "" then
                        return
                     end
                     local servicename = response_handle:streamInfo():dynamicMetadata():get("context")["request.servicename"]
                     response_handle:logInfo("レスポンス IP を serviceName に変更しました:" .. servicename)
                     local bodyObject = response_handle:body(true)
                     local body= bodyObject:getBytes(0,bodyObject:length())
                     body = string.gsub(body,"%s+","")
                     body = string.gsub(body,"(ip\":\")(%d+.%d+.%d+.%d+)","%1"..servicename)
                     response_handle:body():setBytes(body)
                   end
    2. 次のコマンドを実行して、Envoy フィルタを作成します。

      kubectl apply -f external-envoyfilter.yaml

手順 2:ACK クラスタに Spring Cloud サービスをデプロイする

説明
  • 登録プロセスをインターセプトするために、デプロイメントを作成する前に Envoy フィルタが作成されていることを確認してください。Envoy フィルタを作成する前に特定のデプロイメントが作成されている場合は、デプロイメントのローリングアップデートを有効にする必要があります。

  • Spring Cloud サービスの場合、Kubernetes サービスリソースを作成し、クラスタ IP アドレスを提供する必要があります。

  1. kubectl を使用して、データプレーンのクラスターに接続します。詳細については、「クラスターの kubeconfig ファイルを取得し、kubectl を使用してクラスターに接続する」をご参照ください。

  2. 次のコマンドを実行して、Spring Cloud サービスをデプロイします。

    export NACOS_ADDRESS=xxxx # xxxx を MSE Nacos レジストリまたはセルフマネージド Nacos レジストリのエンドポイントに置き換えます。仮想プライベートクラウド (VPC) のエンドポイントを使用することをお勧めします。
    wget https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/springcloud/demo.yaml -O demo.yaml
    sed -e "s/NACOS_SERVER_CLUSTERIP/$NACOS_ADDRESS/g" demo.yaml |kubectl apply -f -
  3. 次のコマンドを実行して、Spring Cloud サービスを確認します。

     kubectl get pods

    予期される出力:

    consumer-bdd464654-jn8q7       2/2     Running     0          25h
    provider-v1-66bc67fb6d-46pgl   2/2     Running     0          25h
    provider-v2-76568c45f6-85z87   2/2     Running     0          25h

手順 3:Istio ゲートウェイと仮想サービスを作成する

  1. Istio ゲートウェイを作成します。

    1. 次の内容を含む test-gateway.yaml ファイルを作成します。

      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: test-gateway
      spec:
        selector:
          istio: ingressgateway # istio デフォルトコントローラーを使用
        servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
          - "*"
    2. kubeconfig ファイルの情報に基づいて kubectl を使用して ASM インスタンスに接続し、次のコマンドを実行して Istio ゲートウェイを作成します。

      kubectl apply -f test-gateway.yaml
  2. 仮想サービスを作成します。

    1. 次の内容を含む consumer.yaml ファイルを作成します。

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: consumer
      spec:
        hosts:
        - "*"
        gateways:
        - test-gateway
        http:
        - match:
          - uri:
              prefix: /
          route:
          - destination:
              host: consumer.default.svc.cluster.local
              port:
                number: 8080
    2. 次のコマンドを実行して、仮想サービスを作成します。

      kubectl apply -f consumer.yaml

手順 4:ASM が Spring Cloud サービスを管理できるかどうかを確認する

  1. イングレスゲートウェイの IP アドレスをクエリします。

    1. ASM コンソール にログインします。左側のナビゲーションウィンドウで、[サービスメッシュ] > [メッシュ管理] を選択します。

    2. [メッシュ管理] ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションウィンドウで、[ASM ゲートウェイ] > [イングレスゲートウェイ] を選択します。

    3. [イングレスゲートウェイ] ページで、イングレスゲートウェイの [サービスアドレス] を表示します。

  2. 次のコマンドを実行して、イングレスゲートウェイから Spring Cloud コンシューマーサービスへのリクエストを開始します。

    curl <イングレスゲートウェイの IP アドレス>/echo/world

    予期される出力:

    Hello Nacos Discovery From v1world
    Hello Nacos Discovery From v2world
    Hello Nacos Discovery From v1world
    Hello Nacos Discovery From v2world

    出力は、トラフィックがデフォルトでポーリングモードでプロバイダーサービスの V1 と V2 にルーティングされていることを示しています。

  3. デスティネーションルールと仮想サービスを作成します。

    1. 次の内容を含む service-provider.yaml ファイルを作成します。

      ---
      apiVersion: networking.istio.io/v1alpha3
      kind: DestinationRule
      metadata:
        name: service-provider
      spec:
        host: service-provider
        subsets:
        - name: v1
          labels:
            label: v1
        - name: v2
          labels:
            label: v2
                                      
    2. 次のコマンドを実行して、デスティネーションルールを作成します。

      kubectl apply -f service-provider.yaml
    3. 次の内容を含む service-provider1.yaml ファイルを作成します。

      作成される仮想サービスは、/echo/hello リクエストが V1 のプロバイダーサービスにルーティングされ、他のリクエストが V2 のプロバイダーサービスにルーティングされることを定義しています。

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: service-provider
      spec:
        hosts:
        - service-provider
        http:
        - name: "hello-v1"
          match:
          - uri:
              prefix: "/echo/hello"
          route:
          - destination:
              host: service-provider
              subset: v1
        - name: "default"
          route:
          - destination:
              host: service-provider
              subset: v2
    4. 次のコマンドを実行して、仮想サービスを作成します。

      kubectl apply -f service-provider1.yaml
  4. 次のコマンドを実行して、Spring Cloud コンシューマーサービスへのリクエストを開始します。

    curl <イングレスゲートウェイの IP アドレス>/echo/hello

    予期される出力:

    Hello Nacos Discovery From v1hello
    Hello Nacos Discovery From v1hello

    出力は、/echo/hello リクエストが V1 のプロバイダーサービスにルーティングされ、他のリクエストが V2 のプロバイダーサービスにルーティングされていることを示しています。これは、Spring Cloud トラフィックが Istio によって引き継がれ、Istio によって提供されるカスタムリソース定義 (CRD) を使用してルーティングルールを設定できることを示しています。この場合、ASM は Spring Cloud サービスを管理できます。

FAQ

デプロイした Spring Cloud サービスが有効にならない場合はどうすればよいですか?

  1. Nacos のポートまたは IP アドレスに対してトラフィックブロックが有効になっているかどうかを確認します。

    • 逆引き DNS ルックアップを使用する場合は、ポッドの IP アドレスをブロックする必要があります。

    • Lua スクリプトを使用する場合は、Nacos サーバーの IP アドレスとクラスタ IP アドレスをブロックする必要があります。

  2. 登録プロセスをインターセプトするために、デプロイメントを作成する前に Envoy フィルタが作成されていることを確認してください。Envoy フィルタを作成する前に特定のデプロイメントが作成されている場合は、デプロイメントのローリングアップデートを有効にする必要があります。

  3. Kubernetes サービスリソースを作成し、Spring Cloud サービスにクラスタ IP アドレスを提供したかどうかを確認します。

  4. ASM コントロールプレーンで Spring Cloud のサポートを有効にする方法を確認します。

    方法 2 を使用する場合は、Nacos のクライアント SDK が 2.0 より前のバージョンである必要があります。 v2.0 以降のクライアント SDK は、gRPC を使用してサーバーに接続します。方法 2 は適用できません。方法 1 は Nacos のバージョン要件がなく、すべての Nacos バージョンに適用できます。

  5. サービスのサイドカーバージョンを確認します。サイドカーイメージのバージョンが 1.13.4.32 より前の場合、ASM インスタンスのコントロールプレーンのみを更新し、データプレーンを更新していない可能性があります。この場合、サービスのデプロイメントのローリングアップデートを有効にします。