Service Mesh (ASM) は、非侵入型の手法で Container Service for Kubernetes (ACK) クラスタと Container Compute Service (ACS) クラスタのテレメトリデータを収集します。これにより、クラスタ内のサービス通信を可観測化できます。このテレメトリ機能により、サービスの動作を可観測化できるようになり、O&M スタッフはメンテナンスコストを増やすことなく、Service Meshのトラブルシューティング、メンテナンス、最適化を行うことができます。レイテンシ、トラフィック、エラー、飽和の 4 つの主要なメトリックに基づいて、ASM は管理対象のサービスに対して一連のメトリックを生成します。このトピックでは、ASM メトリックを使用してワークロードの自動スケーリングを実装する方法について説明します。
前提条件
ACK クラスタまたは ACS クラスタが作成されていること。詳細については、「ACK マネージドクラスターを作成する」または「ACS クラスタを作成する」をご参照ください。
ASM インスタンスが作成されていること。詳細については、「ASM インスタンスを作成する」をご参照ください。
Prometheus インスタンスと Grafana インスタンスがクラスタにデプロイされていること。詳細については、「オープンソースの Prometheus を使用して ACK クラスタを監視する」をご参照ください。
ASM インスタンスを監視するために Prometheus インスタンスがデプロイされていること。詳細については、「セルフマネージド Prometheus インスタンスを使用して 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 用のアダプタをデプロイする
アダプタをダウンロードして ACK クラスタにインストールします。
helm -n kube-system install asm-custom-metrics ./kube-metrics-adapter --set prometheus.url=http://prometheus.istio-system.svc:9090 // ASM インスタンスを監視する Prometheus インスタンスの URL を指定します。
kube-metrics-adapter が有効になっているかどうかを確認します。
次のコマンドを実行して、
autoscaling/v2beta
が存在することを確認します。kubectl api-versions |grep "autoscaling/v2beta"
予期される出力:
autoscaling/v2beta
次のコマンドを実行して、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
次のコマンドを実行して、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: サンプル アプリケーションをデプロイする
test という名前の 名前空間を作成します。 名前空間に対して自動サイドカープロキシインジェクションを有効にします。詳細については、「名前空間とリソースクォータを管理する」および「グローバル名前空間を管理する」をご参照ください。
サンプル アプリケーションをデプロイします。
podinfo.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。
次のコマンドを実行して、podinfo アプリケーションをデプロイします。
kubectl apply -n test -f podinfo.yaml
自動スケーリングをトリガーするには、リクエストをトリガーするためのロードテスト サービスを test 名前空間にデプロイする必要があります。
loadtester.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。
次のコマンドを実行して、ロードテスト サービスをデプロイします。
kubectl apply -n test -f loadtester.yaml
サンプル アプリケーションとロードテスト サービスがデプロイされているかどうかを確認します。
次のコマンドを実行して、ポッドステータスを確認します。
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
次のコマンドを実行して、ロードテスト用の コンテナーにログインし、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 はレプリカ数を増やします。
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" // しきい値。
次のコマンドを実行して、HPA をデプロイします。
kubectl apply -f hpa.yaml
次のコマンドを実行して、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 がデプロイされていることを示します。
自動スケーリングを確認する
次のコマンドを実行して、ロードテスト用の コンテナーにログインし、hey コマンドを実行して負荷を生成します。
kubectl -n test exec -it ${loadtester} -c loadtester -- hey -z 5m -c 10 -q 5 http://podinfo.test:9898
次のコマンドを実行して、自動スケーリングの効果を確認します。
説明メトリックはデフォルトで 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 に減少します。