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

Alibaba Cloud Service Mesh:ASM メトリックを使用したワークロードの自動スケーリングの実装

最終更新日:May 14, 2025

Service Mesh (ASM) は、非侵入型の手法で Container Service for Kubernetes (ACK) クラスタと Container Compute Service (ACS) クラスタのテレメトリデータを収集します。これにより、クラスタ内のサービス通信を可観測化できます。このテレメトリ機能により、サービスの動作を可観測化できるようになり、O&M スタッフはメンテナンスコストを増やすことなく、Service Meshのトラブルシューティング、メンテナンス、最適化を行うことができます。レイテンシ、トラフィック、エラー、飽和の 4 つの主要なメトリックに基づいて、ASM は管理対象のサービスに対して一連のメトリックを生成します。このトピックでは、ASM メトリックを使用してワークロードの自動スケーリングを実装する方法について説明します。

前提条件

背景

ASM は、管理対象のサービスに対して一連のメトリックを生成します。詳細については、「Istio 標準メトリック」をご参照ください。

自動スケーリングとは、リソース使用量に基づいてワークロードを自動的にスケールアップまたはスケールダウンするために使用されるアプローチです。Kubernetes では、自動スケーリングを実装するために 2 つの自動スケーラーが使用されます。

  • Cluster Autoscaler (CA): CA は、クラスタ内のノード数を増減するために使用されます。

  • Horizontal Pod Autoscaler (HPA): HPA は、アプリケーションのデプロイに使用されるポッド数を増減するために使用されます。

Kubernetes の集約レイヤーにより、サードパーティ アプリケーションは API アドオンとして自身を登録することで Kubernetes API を拡張できます。これらのアドオンを使用してカスタムメトリック API を実装し、HPA が任意のメトリックをクエリできるようにすることができます。HPA は、リソースメトリック API を使用して、CPU 使用率やメモリ使用量などのコアメトリックを定期的にクエリします。さらに、HPA はカスタムメトリック API を使用して、ASM によって提供される可観測性メトリックなどのアプリケーション固有のメトリックをクエリします。

手順 1: ASM インスタンスの Prometheus モニタリングを有効にする

詳細については、「Managed Service for Prometheus にメトリックを収集する」をご参照ください。

手順 2: カスタムメトリック API 用のアダプタをデプロイする

  1. アダプタをダウンロードして ACK クラスタにインストールします。

    helm -n kube-system install asm-custom-metrics ./kube-metrics-adapter  --set prometheus.url=http://prometheus.istio-system.svc:9090 // ASM インスタンスを監視する Prometheus インスタンスの URL を指定します。
  2. kube-metrics-adapter が有効になっているかどうかを確認します。

    1. 次のコマンドを実行して、autoscaling/v2beta が存在することを確認します。

      kubectl api-versions |grep "autoscaling/v2beta"

      予期される出力:

      autoscaling/v2beta
    2. 次のコマンドを実行して、kube-metrics-adapter のポッドのステータスを確認します。

      kubectl get po -n kube-system |grep metrics-adapter

      予期される出力:

      asm-custom-metrics-kube-metrics-adapter-85c6d5d865-2****          1/1     Running   0          19s
    3. 次のコマンドを実行して、kube-metrics-adapter によって提供されるカスタムメトリックをクエリします。

      kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | jq .

      予期される出力:

      {
        "kind": "APIResourceList",
        "apiVersion": "v1",
        "groupVersion": "external.metrics.k8s.io/v1beta1",
        "resources": []
      }

手順 3: サンプル アプリケーションをデプロイする

  1. test という名前の 名前空間を作成します。 名前空間に対して自動サイドカープロキシインジェクションを有効にします。詳細については、「名前空間とリソースクォータを管理する」および「グローバル名前空間を管理する」をご参照ください。

  2. サンプル アプリケーションをデプロイします。

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

      詳細を表示するにはクリックしてください

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: podinfo
        namespace: test
        labels:
          app: podinfo
      spec:
        minReadySeconds: 5
        strategy:
          rollingUpdate:
            maxUnavailable: 0
          type: RollingUpdate
        selector:
          matchLabels:
            app: podinfo
        template:
          metadata:
            annotations:
              prometheus.io/scrape: "true" // Prometheus がメトリックを収集できるように注釈を追加します。
            labels:
              app: podinfo
          spec:
            containers:
            - name: podinfod
              image: stefanprodan/podinfo:latest
              imagePullPolicy: IfNotPresent
              ports:
              - containerPort: 9898
                name: http
                protocol: TCP
              command:
              - ./podinfo
              - --port=9898
              - --level=info
              livenessProbe:
                exec:
                  command:
                  - podcli
                  - check
                  - http
                  - localhost:9898/healthz
                initialDelaySeconds: 5
                timeoutSeconds: 5
              readinessProbe:
                exec:
                  command:
                  - podcli
                  - check
                  - http
                  - localhost:9898/readyz
                initialDelaySeconds: 5
                timeoutSeconds: 5
              resources:
                limits:
                  cpu: 2000m
                  memory: 512Mi
                requests:
                  cpu: 100m
                  memory: 64Mi
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: podinfo
        namespace: test
        labels:
          app: podinfo
      spec:
        type: ClusterIP
        ports:
          - name: http
            port: 9898
            targetPort: 9898
            protocol: TCP
        selector:
          app: podinfo
    2. 次のコマンドを実行して、podinfo アプリケーションをデプロイします。

      kubectl apply -n test -f podinfo.yaml
  3. 自動スケーリングをトリガーするには、リクエストをトリガーするためのロードテスト サービスを test 名前空間にデプロイする必要があります。

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

      詳細を表示するにはクリックしてください

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: loadtester
        namespace: test
        labels:
          app: loadtester
      spec:
        selector:
          matchLabels:
            app: loadtester
        template:
          metadata:
            labels:
              app: loadtester
            annotations:
              prometheus.io/scrape: "true" // Prometheus がメトリックを収集できるように注釈を追加します。
          spec:
            containers:
              - name: loadtester
                image: weaveworks/flagger-loadtester:0.18.0
                imagePullPolicy: IfNotPresent
                ports:
                  - name: http
                    containerPort: 8080
                command:
                  - ./loadtester
                  - -port=8080
                  - -log-level=info
                  - -timeout=1h // タイムアウト値を 1 時間に設定します。
                livenessProbe:
                  exec:
                    command:
                      - wget
                      - --quiet
                      - --tries=1
                      - --timeout=4
                      - --spider
                      - http://localhost:8080/healthz
                  timeoutSeconds: 5
                readinessProbe:
                  exec:
                    command:
                      - wget
                      - --quiet
                      - --tries=1
                      - --timeout=4
                      - --spider
                      - http://localhost:8080/healthz
                  timeoutSeconds: 5
                resources:
                  limits:
                    memory: "512Mi"
                    cpu: "1000m"
                  requests:
                    memory: "32Mi"
                    cpu: "10m"
                securityContext:
                  readOnlyRootFilesystem: true
                  runAsUser: 10001
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: loadtester
        namespace: test
        labels:
          app: loadtester
      spec:
        type: ClusterIP
        selector:
          app: loadtester
        ports:
          - name: http
            port: 80
            protocol: TCP
            targetPort: http
    2. 次のコマンドを実行して、ロードテスト サービスをデプロイします。

      kubectl apply -n test -f loadtester.yaml
  4. サンプル アプリケーションとロードテスト サービスがデプロイされているかどうかを確認します。

    1. 次のコマンドを実行して、ポッドステータスを確認します。

      kubectl get pod -n test

      予期される出力:

      NAME                          READY   STATUS    RESTARTS   AGE
      loadtester-64df4846b9-nxhvv   2/2     Running   0          2m8s
      podinfo-6d845cc8fc-26xbq      2/2     Running   0          11m
    2. 次のコマンドを実行して、ロードテスト用の コンテナーにログインし、hey コマンドを実行して負荷を生成します。

      export loadtester=$(kubectl -n test get pod -l "app=loadtester" -o jsonpath='{.items[0].metadata.name}')
      kubectl -n test exec -it ${loadtester} -c loadtester -- hey -z 5s -c 10 -q 2 http://podinfo.test:9898

      負荷が生成されます。これは、サンプル アプリケーションとロードテスト サービスがデプロイされていることを示します。

手順 4: ASM メトリックを使用して HPA を構成する

podinfo アプリケーションが 1 秒あたりに受信するリクエスト数に基づいて、podinfo アプリケーションのワークロードをスケーリングする HPA を定義します。平均して 1 秒あたりに 10 件を超えるリクエストを受信すると、HPA はレプリカ数を増やします。

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

    apiVersion: autoscaling/v2beta2
    kind: HorizontalPodAutoscaler
    metadata:
      name: podinfo
      namespace: test
      annotations:
        metric-config.external.prometheus-query.prometheus/processed-requests-per-second: |  // カスタムメトリックの名前を定義します。
          sum(
              rate(
                  istio_requests_total{  // ASM によって提供されるメトリック名。
                    destination_workload="podinfo", // デプロイされた アプリケーションの名前。
                    destination_workload_namespace="test", // アプリケーションがデプロイされている 名前空間。
                    reporter="destination"
                  }[1m]
              )
          ) 
    spec:
      maxReplicas: 10
      minReplicas: 1
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: podinfo
      metrics:
        - type: External
          external:
            metric:
              name: prometheus-query
              selector:
                matchLabels:
                  query-name: processed-requests-per-second
            target:
              type: AverageValue
              averageValue: "10" // しきい値。
  2. 次のコマンドを実行して、HPA をデプロイします。

    kubectl apply -f hpa.yaml
  3. 次のコマンドを実行して、HPA がデプロイされているかどうかを確認します。

    次のコマンドを実行して、kube-metrics-adapter によって提供されるカスタムメトリックをクエリします。

    kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | jq .

    予期される出力:

    {
      "kind": "APIResourceList",
      "apiVersion": "v1",
      "groupVersion": "external.metrics.k8s.io/v1beta1",
      "resources": [
        {
          "name": "prometheus-query",
          "singularName": "",
          "namespaced": true,
          "kind": "ExternalMetricValueList",
          "verbs": [
            "get"
          ]
        }
      ]
    }

    出力にはカスタム ASM メトリックのリストが含まれています。これは、HPA がデプロイされていることを示します。

自動スケーリングを確認する

  1. 次のコマンドを実行して、ロードテスト用の コンテナーにログインし、hey コマンドを実行して負荷を生成します。

    kubectl -n test exec -it ${loadtester} -c loadtester -- hey -z 5m -c 10 -q 5 http://podinfo.test:9898
  2. 次のコマンドを実行して、自動スケーリングの効果を確認します。

    説明

    メトリックはデフォルトで 30 秒ごとに同期されます。 コンテナーは 3 ~ 5 分ごとに 1 回だけスケーリングできます。こうすることで、HPA は競合戦略が実行される前に自動スケーリングのための時間を確保できます。

    watch kubectl -n test get hpa/podinfo

    予期される出力:

    NAME      REFERENCE            TARGETS          MINPODS   MAXPODS   REPLICAS   AGE
    podinfo   Deployment/podinfo   8308m/10 (avg)   1         10        6          124m

    HPA は、1 秒あたりのリクエスト数が指定されたしきい値を下回るまで、1 分でワークロードのスケールアップを開始します。ロードテストが完了すると、1 秒あたりのリクエスト数はゼロに減少します。その後、HPA はポッド数の削減を開始します。数分後、レプリカ数は上記の出力の値から 1 に減少します。