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

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

最終更新日:Dec 26, 2025

Service Mesh (ASM) は、Alibaba Cloud Container Service for Kubernetes (ACK) および Alibaba Cloud Container Service (ACS) クラスター内でのサービス間通信について、テレメトリデータを生成するための非侵入的な方法を提供します。このテレメトリ機能は、サービスの動作に対する可観測性を提供します。これにより、運用保守 (O&M) エンジニアは、アプリケーションコードを変更することなく、アプリケーションのトラブルシューティング、メンテナンス、および最適化を行うことができます。モニタリングの 4 つのゴールデンシグナル (レイテンシー、トラフィック、エラー、飽和度) に基づいて、ASM は管理対象のサービスの一連のメトリックを生成します。このトピックでは、ASM メトリックを使用してワークロードの自動スケーリングを実装する方法について説明します。

前提条件

背景情報

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

自動スケーリングは、リソース使用量に基づいてワークロードを自動的にスケールアップまたはスケールダウンする方法です。Kubernetes は、自動スケーリングのために 2 つのディメンションを提供します:

  • Cluster Autoscaler (CA):ノードのスケーリング操作を処理し、ノード数を増減させます。

  • Horizontal Pod Autoscaler (HPA):デプロイメント内の Pod 数を自動的にスケーリングします。

Kubernetes の集約レイヤーにより、サードパーティのアプリケーションは API アドオンコンポーネントとして登録することで Kubernetes API を拡張できます。これらのアドオンコンポーネントは Custom Metrics API を実装でき、HPA が任意のメトリックにアクセスできるようにします。HPA は、Resource Metrics API を介して CPU やメモリなどのコアメトリックを定期的にクエリします。また、Custom Metrics API を介して、ASM が提供する可観測性メトリックを含むアプリケーション固有のメトリックを取得します。

ステップ 1:Prometheus モニタリングメトリックの収集の有効化

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

ステップ 2:カスタムメトリック API アダプターのデプロイ

  1. ACK クラスターに kube-metrics-adapter をダウンロードしてインストールします。

    helm -n kube-system install asm-custom-metrics ./kube-metrics-adapter  --set prometheus.url=http://prometheus.istio-system.svc:9090
  2. kube-metrics-adapter が有効になっていることを確認します。

    1. autoscaling/v2 が存在することを確認します。

      kubectl api-versions | grep "autoscaling/v2"

      想定される出力:

      autoscaling/v2
    2. kube-metrics-adapter Pod のステータスを確認します。

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

      想定される出力:

      asm-custom-metrics-kube-metrics-adapter-85c6d5d865-2****          1/1     Running   0          19s
    3. Prometheus アダプターが提供するカスタム外部メトリックをリスト表示します。

      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` という名前のファイルを作成します。

      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"
            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` という名前のファイルを作成します。

      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"
          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
                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. Pod のステータスを確認します。

      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. 負荷テスターコンテナーにログインし、負荷を生成します。

      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 の設定

1 秒あたりの受信リクエスト数に基づいて podinfo ワークロードをスケーリングする HPA を定義します。平均トラフィック負荷が 1 秒あたり 10 リクエストを超えると、HPA はデプロイメントをスケールアウトします。

説明

注:この例では、Kubernetes 1.23 以降に適用される HPA API バージョン `autoscaling/v2` を使用します。Kubernetes 1.26 以降を実行するクラスターでは、バージョン `v2` を使用してください。`v2beta2` バージョンは Kubernetes 1.26 で削除されました。

  1. `hpa.yaml` という名前のファイルを作成します。

    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: podinfo
      namespace: test
      annotations:
        metric-config.external.prometheus-query.prometheus/processed-requests-per-second: |
          sum(
              rate(
                  istio_requests_total{
                    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 がデプロイされていることを確認します。

    Prometheus アダプターが提供するカスタム外部メトリックをリスト表示します。

    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. 負荷テスターコンテナーにログインして、ワークロードリクエストを生成します。

    kubectl -n test exec -it ${loadtester} -c loadtester -- hey -z 5m -c 10 -q 5 http://podinfo.test:9898
  2. 自動スケーリングのステータスを確認します。

    説明

    デフォルトでは、メトリックは 30 秒ごとに同期されます。スケーリング操作は、ワークロードが過去 3〜5 分間に再スケーリングされていない場合にのみ発生します。これにより、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

    1 分後、HPA は 1 秒あたりのリクエスト数がターゲット値を下回るまでワークロードのスケールアップを開始します。負荷テストが完了すると、1 秒あたりのリクエスト数はゼロになり、HPA はワークロード Pod 数のスケールダウンを開始します。数分後、コマンド出力のレプリカ数は 1 に戻ります。