このドキュメントでは、Google Cloud Managed Service for Prometheus 用に水平 Pod 自動スケーリング(HPA)を有効にする方法について説明します。HPA を有効にするには、次のいずれかを行います。
- Google Cloud が開発およびサポートしている Custom Metrics Stackdriver Adapter ライブラリを使用する。
- サードパーティの Prometheus アダプタ ライブラリを使用する。
いずれかの方法を選択する必要があります。トラブルシューティングで説明されているように、リソース定義が重複しているため、両方を使用することはできません。
カスタム指標 Stackdriver アダプタを使用する
v0.13.1 のアダプタから、カスタム指標 Stackdriver アダプタは Managed Service for Prometheus からの指標のクエリをサポートしています。
カスタム指標 Stackdriver アダプタを使用してサンプルの HPA 構成を設定するには、次の操作を行います。
- クラスタのマネージド コレクションを設定します。
カスタム指標 Stackdriver アダプタをクラスタにインストールします。
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml
Prometheus 指標のエクスポータと HPA リソースをデプロイします。
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/examples/prometheus-to-sd/custom-metrics-prometheus-sd.yaml
このコマンドは、指標
foo
と HPA リソースを出力するエクスポータ アプリケーションをデプロイします。HPA は、このアプリケーションを 5 つのレプリカにスケーリングして、指標foo
のターゲット値を達成します。Workload Identity Federation for GKE を使用している場合は、アダプタが実行されているサービス アカウントにもモニタリング閲覧者ロールを付与する必要があります。Kubernetes クラスタで Workload Identity Federation for GKE が有効になっていない場合は、この手順をスキップしてください。
export PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format 'get(projectNumber)') gcloud projects add-iam-policy-binding projects/PROJECT_ID \ --role roles/monitoring.viewer \ --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter
podmonitoring.yaml
という名前のファイルに次の構成を記述して、PodMonitoring リソースを定義します。apiVersion: monitoring.googleapis.com/v1 kind: PodMonitoring metadata: name: prom-example spec: selector: matchLabels: run: custom-metric-prometheus-sd endpoints: - port: 8080 interval: 30s
新しい PodMonitoring リソースをデプロイします。
kubectl -n default apply -f podmonitoring.yaml
数分以内に、Managed Service for Prometheus はエクスポータからスクレイピングされた指標を処理し、長い形式の名前で Cloud Monitoring に保存します。Prometheus の指標は次の規則で保存されます。
prometheus.googleapis.com
接頭辞。- 通常、この接尾辞は
gauge
、counter
、summary
、histogram
のいずれかですが、型なしの指標の場合、unknown
またはunknown:counter
という接尾辞が含まれることがあります。接尾辞を確認するには、Metrics Explorer を使用して Cloud Monitoring で指標を検索します。
デプロイされた HPA を更新して、Cloud Monitoring から指標をクエリします。指標
foo
はprometheus.googleapis.com/foo/gauge
として取り込まれます。デプロイされた HorizontalPodAutoscaler リソースで指標をクエリできるようにするため、デプロイされた HPA で長い形式の名前を使用しますが、すべてのスラッシュ(/
)をパイプ文字(|
)に置き換える必要があります(prometheus.googleapis.com|foo|gauge
)。詳細については、カスタム指標 Stackdriver アダプタ リポジトリの Stackdriver セクションで使用可能な指標をご覧ください。次のコマンドを実行して、デプロイされた HPA を更新します。
kubectl edit hpa custom-metric-prometheus-sd
pods.metric.name
フィールドの値をfoo
からprometheus.googleapis.com|foo|gauge
に変更します。spec
セクションは次の例のようになります。spec: maxReplicas: 5 metrics: - pods: metric: name: prometheus.googleapis.com|foo|gauge target: averageValue: "20" type: AverageValue type: Pods minReplicas: 1
この例の HPA 構成では、指標
prometheus.googleapis.com/foo/gauge
の平均値は20
になります。Deployment は指標の値が40
に設定されているため、HPA コントローラは Pod の数をmaxReplicas
(5
)フィールドの値まで増やし、すべての Pod の指標の平均値を20
に減らそうと試行します。HPA クエリのスコープは、HPA リソースがインストールされている Namespace とクラスタであるため、他のクラスタと Namespace の同じ指標は自動スケーリングに影響しません。
ワークロードがスケールアップされたことを確認するには、次のコマンドを実行します。
kubectl get hpa custom-metric-prometheus-sd --watch
REPLICAS
フィールドの値が1
から5
に変わります。NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE custom-metric-prometheus-sd Deployment/custom-metric-prometheus-sd 40/20 1 5 5 *
Deployment をスケールダウンするには、エクスポートした指標値よりもターゲット指標の値を大きくします。この例では、Deployment の
prometheus.googleapis.com/foo/gauge
指標の値が40
に設定されます。ターゲット値を40
より大きい値に設定すると、Deployment はスケールダウンされます。たとえば、
kubectl edit
を使用して、HPA 構成のpods.target.averageValue
フィールドの値を20
から100
に変更します。kubectl edit hpa custom-metric-prometheus-sd
spec セクションを次のように変更します。
spec: maxReplicas: 5 metrics: - pods: metric: name: prometheus.googleapis.com|foo|gauge target: averageValue: "100" type: AverageValue type: Pods minReplicas: 1
次のコマンドを実行して、ワークロードのスケールダウンを監視します。
kubectl get hpa custom-metric-prometheus-sd --watch
REPLICAS
フィールドの値が5
から1
に変わります。設計上、これは Pod 数をスケールアップする場合よりも遅くなります。NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE custom-metric-prometheus-sd Deployment/custom-metric-prometheus-sd 40/100 1 5 1 *
デプロイされたサンプルをクリーンアップするには、次のコマンドを実行します。
kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/examples/prometheus-to-sd/custom-metrics-prometheus-sd.yaml kubectl delete podmonitoring/prom-example
詳細については、カスタム指標 Stackdriver アダプタ リポジトリの Prometheus の例またはアプリケーションのスケーリングをご覧ください。
Prometheus アダプタを使用する
既存の prometheus-adapter 構成ファイルは、いくつかの変更を行うだけで自動スケーリングに使用できます。Managed Service for Prometheus を使用してスケーリングするように prometheus-adapter を構成する場合は、アップストリーム Prometheus を使用してスケーリングする場合と比較して、2 つの制限が加わります。
Prometheus API または UI を使用して Managed Service for Prometheus のクエリを実行する場合と同様に、クエリは Prometheus フロントエンド UI プロキシ経由でルーティングされる必要があります。Prometheus アダプタの場合は、
prometheus-adapter
デプロイを編集して、prometheus-url
値を次のように変更する必要があります。--prometheus-url=http://frontend.NAMESPACE_NAME.svc:9090/
ここで、NAMESPACE_NAME はフロントエンドがデプロイされている Namespace です。
ルール構成ファイルの
.seriesQuery
フィールドの指標名に正規表現マッチャーは使用できません。代わりに、完全な指標名を指定する必要があります。
アップストリームの Prometheus と比較して Managed Service for Prometheus ではデータが利用可能になるまでに少し時間がかかる場合があります。過剰な自動スケーリング ロジックを構成すると、望ましくない動作が発生する可能性があります。データの鮮度は保証されませんが、通常はネットワーク レイテンシを除いて Managed Service for Prometheus に送信した 3~7 秒後にデータはクエリの実行に使用できます。
prometheus-adapter によって発行されるすべてのクエリは、グローバル スコープです。つまり、同じ名前の指標を出力する 2 つの名前空間にアプリケーションがある場合、その指標を使用する HPA 構成は両方のアプリケーションのデータを使用してスケーリングされます。間違ったデータを使用してスケーリングしないように、PromQL では常に namespace
または cluster
フィルタを使用することをおすすめします。
prometheus-adapter とマネージド コレクションを使用して HPA 構成の例を設定するには、次の手順を行います。
- クラスタのマネージド コレクションを設定します。
- クラスタに Prometheus フロントエンド UI プロキシをデプロイします。Workload Identity Federation for GKE を使用する場合は、サービス アカウントを構成して認可する必要があります。
- prometheus-engine リポジトリ内の
examples/hpa/
ディレクトリにマニフェストをデプロイします。example-app.yaml
: 指標を出力するデプロイとサービスの例。pod-monitoring.yaml
: サンプル指標のスクレイピングを構成するリソース。hpa.yaml
: ワークロードのスケーリングを構成する HPA リソース。
クラスタに
prometheus-adapter
がインストールされていることを確認します。これを行うには、サンプルのインストール マニフェストをクラスタにデプロイします。このマニフェストは次のように構成されています。default
Namespace にデプロイされたフロントエンド プロキシをクエリします。- PromQL を発行して、サンプル デプロイから
http_requests_per_second
指標を計算して返します。
それぞれ個別のターミナル セッションで、以下のコマンドを実行します。
prometheus-example-app
サービスに対する HTTP の負荷を生成します。kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://prometheus-example-app; done"
- HorizontalPodAutoscaler を確認します。
kubectl get hpa prometheus-example-app --watch
- ワークロードのスケールアップを確認します。
kubectl get po -lapp.kubernetes.io/name=prometheus-example-app --watch
Ctrl+C を使用して HTTP 負荷の生成を停止し、ワークロードのスケールダウンを確認します。
トラブルシューティング
カスタム指標 Stackdriver アダプタでは、Prometheus アダプタと同じ名前のリソース定義(prometheus-adapter)を使用します。この名前の重複のため、同じクラスタ内で複数のアダプタを実行すると、エラーが発生します。
以前に「カスタム指標 Stackdriver アダプタ」がインストールされているクラスタに Prometheus Adapter をインストールすると、名前の競合により、FailedGetObjectMetric
などのエラーがスローされる場合があります。この問題を解決するには、以前にカスタム指標アダプタによって登録された v1beta1.external.metrics.k8s.io
、v1beta1.custom.metrics.k8s.io
、v1beta2.custom.metrics.k8s.io
の各 API サービスの削除が必要になる場合があります。
トラブルシューティングのヒント:
Pub/Sub 指標など、一部の Cloud Monitoring システム指標は 60 秒以上遅延します。Prometheus アダプタは現在のタイムスタンプを使用してクエリを実行するため、Prometheus アダプタを使用してこれらの指標をクエリすると、データが返されないことがあります。遅延した指標をクエリするには、PromQL の
offset
修飾子を使用して、クエリの時間オフセットを変更して必要な時間を設定します。フロントエンド UI プロキシが想定どおりに動作し、権限に問題がないことを確認するには、ターミナルで次のコマンドを実行します。
kubectl -n NAMESPACE_NAME port-forward svc/frontend 9090
次に、別のターミナルを開いて次のコマンドを実行します。
curl --silent 'localhost:9090/api/v1/series?match%5B%5D=up'
フロントエンド UI プロキシが正常に機能している場合、2 番目のターミナルでのレスポンスは次のようになります。
curl --silent 'localhost:9090/api/v1/series?match%5B%5D=up' | jq . { "status": "success", "data": [ ... ] }
403 エラーが発生した場合は、フロントエンド UI プロキシが正しく構成されていません。403 エラーを解決する方法については、サービス アカウントの構成と認可ガイドをご覧ください。
カスタム指標の apiserver が使用可能であることを確認するには、次のコマンドを実行します。
kubectl get apiservices.apiregistration.k8s.io v1beta1.custom.metrics.k8s.io
apiserver が使用可能な場合、レスポンスは次のようになります。
$ kubectl get apiservices.apiregistration.k8s.io v1beta1.custom.metrics.k8s.io NAME SERVICE AVAILABLE AGE v1beta1.custom.metrics.k8s.io monitoring/prometheus-adapter True 33m
HPA が意図したとおりに機能していることを確認するには、次のコマンドを実行します。
$ kubectl describe hpa prometheus-example-app Name: prometheus-example-app Namespace: default Labels:
Annotations: Reference: Deployment/prometheus-example-app Metrics: ( current / target ) "http_requests_per_second" on pods: 11500m / 10 Min replicas: 1 Max replicas: 10 Deployment pods: 2 current / 2 desired Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale True ReadyForNewScale recommended size matches current size ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from pods metric http_requests_per_second ScalingLimited False DesiredWithinRange the desired count is within the acceptable range Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulRescale 47s horizontal-pod-autoscaler New size: 2; reason: pods metric http_requests_per_second above target レスポンスに
FailedGetPodsMetric
などのステートメントが含まれている場合、HPA は失敗しています。HPA が失敗した場合のdescribe
呼び出しのレスポンスを以下に示します。$ kubectl describe hpa prometheus-example-app Name: prometheus-example-app Namespace: default Reference: Deployment/prometheus-example-app Metrics: ( current / target ) "http_requests_per_second" on pods:
/ 10 Min replicas: 1 Max replicas: 10 Deployment pods: 1 current / 1 desired Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale True ReadyForNewScale recommended size matches current size ScalingActive False FailedGetPodsMetric the HPA was unable to compute the replica count: unable to get metric http_requests_per_second: unable to fetch metrics from custom metrics API: the server could not find the metric http_requests_per_second for pods ScalingLimited False DesiredWithinRange the desired count is within the acceptable range Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedGetPodsMetric 104s (x11 over 16m) horizontal-pod-autoscaler unable to get metric http_requests_per_second: unable to fetch metrics from custom metrics API: the server could not find the metric http_requests_per_second for pods HPA が失敗した場合は、
load-generator
で指標を生成していることを確認します。カスタム指標 API は、次のコマンドで直接確認できます。kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/" | jq .
正常な場合の出力は次のようになります。
$ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/" | jq . { "kind": "APIResourceList", "apiVersion": "v1", "groupVersion": "custom.metrics.k8s.io/v1beta1", "resources": [ { "name": "namespaces/http_requests_per_second", "singularName": "", "namespaced": false, "kind": "MetricValueList", "verbs": [ "get" ] }, { "name": "pods/http_requests_per_second", "singularName": "", "namespaced": true, "kind": "MetricValueList", "verbs": [ "get" ] } ] }
指標がない場合、出力の
"resources"
の下にデータはありません。次に例を示します。kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/" | jq . { "kind": "APIResourceList", "apiVersion": "v1", "groupVersion": "custom.metrics.k8s.io/v1beta1", "resources": [] }