Google Kubernetes Engine(GKE)で水平 Pod 自動スケーリングが想定どおりに機能しない場合、ワークロードが正しくスケーリングされない可能性があります。この問題により、アプリケーションが負荷を処理できなくなり、パフォーマンスの問題や停止が発生する可能性があります。CPU 使用率が高いにもかかわらず Pod が増加しない、HorizontalPodAutoscaler のステータスに <unknown> と表示される指標値がある、スケーリング オペレーションがまったく発生しない、といった状況が発生する可能性があります。
このドキュメントでは、HorizontalPodAutoscaler オブジェクトの初期構成ミスから指標パイプライン内のより複雑な障害まで、水平 Pod 自動スケーリングに関する一般的な問題を診断して解決する方法について説明します。これらのトラブルシューティングの手順に沿って対応することで、需要に基づいてアプリケーションを効率的かつ確実にスケーリングし、HorizontalPodAutoscaler リソースを効果的に活用できます。
この情報は、HorizontalPodAutoscaler オブジェクトを構成し、アプリケーションが正しくスケーリングされるようにする必要があるアプリケーション デベロッパーにとって重要です。また、プラットフォーム管理者と運用担当者が、すべての自動スケーリング ワークロードに影響する指標パイプラインまたはクラスタ構成の問題をトラブルシューティングする際にも役立ちます。 Google Cloud のコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE ユーザーのロールとタスクをご覧ください。
始める前に
- Deployment や StatefulSet などのスケーラブルなワークロードで HorizontalPodAutoscaler オブジェクトを使用してください。スケーリングできないワークロード(DaemonSet など)では、水平 Pod 自動スケーリングを使用できません。
-
GKE で水平 Pod 自動スケーリングのトラブルシューティング(HorizontalPodAutoscaler オブジェクトの検査やクラスタログの表示など)に必要な権限を取得するには、プロジェクトに対する次の IAM ロールを付与するよう管理者に依頼してください。
ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。
GKE クラスタと通信するように
kubectlコマンドライン ツールを構成します。gcloud container clusters get-credentials CLUSTER_NAME \ --location LOCATION \ --project PROJECT_ID次のように置き換えます。
CLUSTER_NAME: クラスタの名前。LOCATION: クラスタの Compute Engine のリージョンまたはゾーン(us-central1やus-central1-aなど)。PROJECT_ID: 実際の Google Cloud プロジェクト ID。
HorizontalPodAutoscaler の問題を診断する
HorizontalPodAutoscaler の問題を診断するには、kubectl コマンドまたは Google Cloud コンソールを使用してステータスと構成を調べます。
HorizontalPodAutoscaler の説明を取得する
リアルタイム計算と最近のスケーリングの決定を表示するには、kubectl describe hpa コマンドを使用します。
kubectl describe hpa HPA_NAME -n NAMESPACE_NAME
次のように置き換えます。
HPA_NAME: HorizontalPodAutoscaler オブジェクトの名前。NAMESPACE_NAME: HorizontalPodAutoscaler オブジェクトの Namespace。
出力は次のようになります。
Name: php-apache-hpa
Namespace: default
Reference: Deployment/php-apache
Metrics: ( current / target )
resource cpu on pods (as a percentage of request): 1% (1m) / 50%
Min replicas: 1
Max replicas: 10
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True ReadyForNewScale recommended size matches current size
ScalingActive True ValidMetricFound the HorizontalPodAutoscaler was able to successfully calculate a replica count
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulRescale 39m horizontal-pod-autoscaler New size: 4; reason: cpu resource utilization...
Normal SuccessfulRescale 26m horizontal-pod-autoscaler New size: 1; reason: cpu resource utilization...
出力では、次の 3 つのセクションが問題の診断に役立ちます。
Metrics: 現在の指標値が目標値と比較して表示されます。<unknown>指標値は、HorizontalPodAutoscaler が指標を取得していないか、指標パイプラインが破損していることを示します。Conditions: HorizontalPodAutoscaler が指標(AbleToScale)を取得してスケーリング計算(ScalingActive)を実行できるかどうかを示します。これらの条件のいずれかでFalseステータスが表示された場合は、失敗を示します。Events: HorizontalPodAutoscaler コントローラからの最近のスケーリング アクション、警告、エラーをログに記録します。多くの場合、FailedGetScaleやFailedGetResourceMetricなどの特定のエラー メッセージや理由が最初に表示されます。
HorizontalPodAutoscaler のマニフェストを確認する
HorizontalPodAutoscaler オブジェクトの YAML マニフェストを使用すると、構成とその現在の状態に関する情報を確認できます。
YAML マニフェストを表示するには、次のいずれかのオプションを選択します。
コンソール
Google Cloud コンソールで、[オブジェクト ブラウザ] ページに移動します。
[オブジェクトの種類] リストで、[HorizontalPodAutoscaler] チェックボックスをオンにして、[OK] をクリックします。
autoscaling API グループに移動し、HorizontalPodAutoscaler の展開矢印をクリックします。
検査する HorizontalPodAutoscaler オブジェクトの名前をクリックします。
[YAML] セクションで、HorizontalPodAutoscaler オブジェクトの完全な構成を確認します。
kubectl
次のコマンドを実行します。
kubectl get hpa HPA_NAME -n NAMESPACE_NAME -o yaml
次のように置き換えます。
HPA_NAME: HorizontalPodAutoscaler オブジェクトの名前。NAMESPACE_NAME: HorizontalPodAutoscaler オブジェクトの Namespace。
マニフェストを取得したら、次の重要なセクションを探します。
spec(構成内容):scaleTargetRef: HorizontalPodAutoscaler がスケーリングするように構成されているワークロード(Deployment など)。minReplicasとmaxReplicas: レプリカの最小値と最大値の設定。metrics: スケーリング用に構成された指標(CPU 使用率やカスタム指標など)。
status(HorizontalPodAutoscaler のライブ状態):currentMetrics: HorizontalPodAutoscaler が観測した最新の指標値。currentReplicasとdesiredReplicas: 現在の Pod の数と、HorizontalPodAutoscaler がスケーリングする数。conditions: HorizontalPodAutoscaler の健全性を示します。AbleToScale: HorizontalPodAutoscaler がターゲットと指標を見つけられるかどうかを示します。ScalingActive: HorizontalPodAutoscaler がスケーリングの計算と実行を許可されているかどうかを示します。ScalingLimited: HorizontalPodAutoscaler がスケールアップを必要としているときに、minReplicasまたはmaxReplicasの設定によって上限が設定されているかどうかを示します。
イベントログを表示する
HorizontalPodAutoscaler オブジェクトの詳細な分析情報を取得するには、次のタイプのログを使用します。
Cloud Logging で HorizontalPodAutoscaler イベントを表示する: ログフィルタを使用して、特定のクラスタのすべての HorizontalPodAutoscaler イベントを見つけます。次に例を示します。
Google Cloud コンソールで、[ログ エクスプローラ] ページに移動します。
クエリペインに次のクエリを入力します。
resource.type="k8s_cluster" resource.labels.cluster_name="CLUSTER_NAME" resource.labels.location="LOCATION" logName="projects/PROJECT_ID/logs/events" jsonPayload.involvedObject.kind="HorizontalPodAutoscaler"次のように置き換えます。
CLUSTER_NAME: HorizontalPodAutoscaler が属するクラスタの名前。LOCATION: クラスタの Compute Engine のリージョンまたはゾーン(us-central1やus-central1-aなど)。PROJECT_ID: プロジェクト ID。
[クエリを実行] をクリックして、出力を確認します。
水平 Pod 自動スケーリング イベントを表示する: これらのログは、HorizontalPodAutoscaler が推奨事項を計算する方法を説明する、人間が読める形式の構造化されたログを提供します。これにより、意思決定プロセスに関する詳細な分析情報が提供されます。
HorizontalPodAutoscaler 構成エラーのトラブルシューティング
以降のセクションでは、HorizontalPodAutoscaler マニフェストの構成ミス(フィールドの入力ミス、無効な指標ターゲット、構成の競合など)について説明します。
ターゲット ワークロードが見つかりません
現象
Events セクションには、次のようなメッセージを含む FailedGetScale の条件があります。
the HorizontalPodAutoscaler controller was unable to get the target's current scale: WORKLOAD_TYPE.apps "TARGET_WORKLOAD" not found
この出力には次の値が含まれます。
WORKLOAD_TYPE: ワークロードのタイプ(Deployment、StatefulSetなど)。TARGET_WORKLOAD: ワークロードの名前。
原因
HorizontalPodAutoscaler コントローラが、管理するように構成されているワークロード(Deployment や StatefulSet など)を見つけられません。この問題は、HorizontalPodAutoscaler のマニフェスト内の scaleTargetRef フィールドの構成ミスが原因で発生します。指定されたリソースが存在しないか、削除されたか、スペルミスがある可能性があります。
解決策
次の解決策を試してください。
- HorizontalPodAutoscaler のマニフェストの
scaleTargetRefフィールドを確認する:scaleTargetRefフィールドのname、kind、apiVersionの値が、ターゲット ワークロードの対応するメタデータと完全に一致していることを確認します。ワークロード名が正しくない場合は、HorizontalPodAutoscaler のscaleTargetRefフィールドを更新して、正しい名前を指すようにします。 - ワークロードが存在することを確認する: ターゲット ワークロードが HorizontalPodAutoscaler と同じ Namespace に存在することを確認します。これを確認するには、
kubectl get deployment DEPLOYMENT_NAMEなどのコマンドを実行します。ワークロードを意図的に削除した場合は、対応する HorizontalPodAutoscaler オブジェクトを削除してクラスタをクリーンアップします。ワークロードを再作成する必要がある場合、HorizontalPodAutoscaler はワークロードが使用可能になると自動的に検出するため、エラーは解決します。 - HorizontalPodAutoscaler とワークロードが同じ Namespace にあることを確認する: HorizontalPodAutoscaler とそのターゲット ワークロードは同じ Namespace に存在する必要があります。
kubectlコマンドでオブジェクトを作成するときに Namespace の指定を忘れると、Kubernetes はオブジェクトをdefaultNamespace に配置します。この動作により、HorizontalPodAutoscaler がdefaultNamespace にあり、ワークロードが別の Namespace にある場合(またはその逆の場合)に、不一致が発生する可能性があります。両方のオブジェクトの Namespace を確認し、一致していることを確認します。
HorizontalPodAutoscaler がターゲットを正常に特定すると、条件 AbleToScale が True になり、メッセージが the HorizontalPodAutoscaler controller was able to get the target's current scale に変わります。
無効な指標
現象
構成の問題により HorizontalPodAutoscaler が必要なレプリカを計算できない場合、Events セクションに FailedComputeMetricsReplicas の理由と次のようなメッセージが表示されます。
invalid metrics (1 invalid out of 1)
原因
このエラーは通常、指標 type と HorizontalPodAutoscaler マニフェストで定義した target の間に不一致があることを意味します。たとえば、type を Utilization に指定したのに、averageUtilization ではなく averageValue のターゲット値を指定したとします。
解決策
target フィールドの値が指標 type と一致するように、HorizontalPodAutoscaler マニフェストを修正します。
typeがUtilizationの場合、targetフィールドの値はaverageUtilizationにする必要があります。typeがAverageValueの場合、targetフィールドの値はaverageValueにする必要があります。
指標ラベルは使用できません
現象
次のエラーが表示されます。
unable to fetch metrics from external metrics API: googleapi: Error 400: Metric label: 'LABEL_NAME' is not allowed
この出力で、LABEL_NAME は正しくないラベルの名前です。
原因
HorizontalPodAutoscaler マニフェストの metric.selector.matchLabels セクションで無効なラベルキーが指定されており、Cloud Monitoring はこのキーを認識せず、指標に使用することも許可しません。
解決策
この問題を解決するには、次の操作を行います。
- エラー メッセージから、許可されていないラベル名を特定します。
- HorizontalPodAutoscaler マニフェストの
metric.selector.matchLabelsセクションで、このラベルキーを削除するか修正します。 - その指標の Cloud Monitoring ドキュメントを参照して、有効なフィルタリング可能なラベルキーを見つけます。
複数の HorizontalPodAutoscaler が同じワークロードをターゲットにしている
現象
HorizontalPodAutoscaler のステータス内に、この競合を直接示す特定の Condition または Reason はありません。代わりに、次のような症状が見られることがあります。
- ワークロードのレプリカ数が予期せず変動することがあります。
- スケーリングの決定が、単一の HorizontalPodAutoscaler で定義された指標に対応していないように見えることがあります。
- イベントを表示すると、異なる HorizontalPodAutoscaler オブジェクトから
SuccessfulRescaleイベントが交互に表示されたり、矛盾するイベントが表示されることがあります。
原因
この問題は、同じ Namespace 内の複数の HorizontalPodAutoscaler オブジェクトが spec.scaleTargetRef フィールドでまったく同じワークロードを指定しているために発生します。各 HorizontalPodAutoscaler はレプリカ数を個別に計算し、独自の指標とターゲットのセットに基づいてワークロードのスケーリングを試みます。Kubernetes はこの構成をブロックしませんが、HorizontalPodAutoscaler が互いに競合するため、スケーリング調整が不安定になります。
解決策
競合を避けるため、すべてのスケーリング指標を 1 つの HorizontalPodAutoscaler オブジェクトで定義します。各 HorizontalPodAutoscaler は独自の spec.metrics フィールドからスケーリングの必要性を計算するため、それらを統合すると、選択した HorizontalPodAutoscaler オブジェクトは CPU や 1 秒あたりのリクエスト数などのすべての要素をまとめて考慮します。
同じワークロードをターゲットとする HorizontalPodAutoscaler を特定するには、各 HorizontalPodAutoscaler オブジェクトの YAML マニフェストを取得します。出力の
spec.scaleTargetRefフィールドに注意してください。kubectl get hpa -n NAMESPACE_NAME -o yamlNAMESPACE_NAMEは、HorizontalPodAutoscaler オブジェクトの Namespace に置き換えます。異なる HorizontalPodAutoscaler リソースの
scaleTargetRefフィールド内で、apiVersion、kind、nameの値が同じであるインスタンスを探します。指標を単一の HorizontalPodAutoscaler オブジェクトに統合します。
- 保持する HorizontalPodAutoscaler オブジェクトを 1 つ選択します。この HorizontalPodAutoscaler を変更します。
- 同じワークロードをターゲットとする他の HorizontalPodAutoscaler オブジェクトの各マニフェストの
spec.metricsセクションを確認します。 - 重複する HorizontalPodAutoscaler オブジェクトの
spec.metricsセクションから、保持する指標定義をコピーします。 - コピーした指標定義を、保持する HorizontalPodAutoscaler の
spec.metrics配列に貼り付けます。
変更を適用するには、以下のコマンドを使用します。
kubectl apply -f MANIFEST_NAMEMANIFEST_NAMEは、保持する HorizontalPodAutoscaler マニフェストの名前に置き換えます。同じワークロードをターゲットにしていた他の HorizontalPodAutoscaler オブジェクトを削除します。
kubectl delete hpa DUPLICATE_MANIFEST_NAME -n NAMESPACE_NAMEDUPLICATE_MANIFEST_NAMEは、削除する冗長な HorizontalPodAutoscaler オブジェクトの名前に置き換えます。
ワークロードとサービスのエラーのトラブルシューティング
以降のセクションでは、HorizontalPodAutoscaler オブジェクト自体ではなく、ターゲット ワークロードまたは関連する Service が原因で発生するエラーについて説明します。
スケーリング計算のリソース リクエストがない
現象
ScalingActive 条件は、Reason が FailedGetResourceMetric の False です。通常、次のようなメッセージも表示されます。
the HorizontalPodAutoscaler was unable to compute the replica count
原因
HorizontalPodAutoscaler は、ワークロードをスケーリングするためにリソース使用率を割合として計算する必要がありますが、Pod 仕様内の少なくとも 1 つのコンテナに対応するリソース(cpu または memory)の resources.requests 定義がないため、この計算を実行できません。
解決策
この問題を解決するには、Deployment、StatefulSet、またはその他のコントローラ内の Pod マニフェストを更新して、HorizontalPodAutoscaler が Pod 内のすべてのコンテナでスケーリングしようとしているリソース(cpu または memory)の resources.requests フィールドを含めます。次に例を示します。
apiVersion: v1
kind: Pod
metadata:
name: example-pod
# Multiple lines are omitted here
spec:
containers:
- name: example-container
resources:
requests:
cpu: "100m"
memory: "128Mi"
Pod の指標を取得できない
現象
次のようなメッセージが継続的に表示されます。
unable to fetch pod metrics for pod
指標サーバーの起動時にこのメッセージが一時的に表示されるのは、正常な状態です。
原因
リソース使用率(cpu や memory など)に基づいてスケーリングするには、HorizontalPodAutoscaler オブジェクトのターゲットとなる Pod 内のすべてのコンテナに、その特定のリソースに対して resources.requests フィールドが定義されている必要があります。そうでないと、HorizontalPodAutoscaler が必要な計算を実行できないため、その指標に関連する処理を行いません。
解決策
これらのエラー メッセージが引き続き表示され、ワークロードの Pod がスケーリングされない場合は、ワークロード内のコンテナごとにリソース リクエストを指定していることを確認してください。
複数のサービスが同じターゲットを選択している
現象
次のエラーが表示されます。
multiple services selecting the same target of HPA_NAME: SERVICE_NAME
この出力には次の値が含まれます。
HPA_NAME: HorizontalPodAutoscaler の名前。SERVICE_NAME: Service の名前。
原因
トラフィック ベースの自動スケーリングが構成されていますが、複数の Kubernetes Service が HorizontalPodAutoscaler の scaleTargetRef フィールドをターゲットにしています。トラフィック ベースの自動スケーリングでは、Service と自動スケーリングされたワークロード間の 1 対 1 の関係のみがサポートされます。
解決策
この問題を解決するには、ワークロードの Pod と一致する Service のラベルセレクタが 1 つだけであることを確認します。
ワークロードの Pod ラベルを見つけます。
kubectl get deployment HPA_TARGET_DEPLOYMENT \ -n NAMESPACE \ -o jsonpath='{.spec.template.metadata.labels}'次のように置き換えます。
HPA_TARGET_DEPLOYMENT: HorizontalPodAutoscaler がターゲットとする Deployment の名前。NAMESPACE: Deployment の Namespace。
出力は次のようになります。
{"app":"my-app", "env":"prod"}Namespace 内のすべての Service の
spec.selectorフィールドを確認して、これらのラベルに一致するすべての Service を見つけます。kubectl get services -n NAMESPACE -o yamlセレクタが前のステップのラベルと一致するすべての Service を特定します。たとえば、
{"app": "my-app"}と{"app": "my-app", "env": "prod"}の両方が Pod のラベルの例と一致します。次のいずれかのオプションを選択して、競合を解決します。
- Deployment の
spec.template.metadata.labelsフィールドに新しい一意のラベルを追加して、目的の Service のセレクタを一意にします。次に、目的の Service のspec.selectorフィールドを更新して、この新しいラベルを含めます。 - 競合するすべての他の Service の
spec.selectorフィールドを変更して、他の Service セレクタをより制限的にし、ワークロードの Pod と一致しないようにします。
- Deployment の
変更を適用するには、以下のコマンドを使用します。
kubectl apply -f MANIFEST_NAMEMANIFEST_NAMEは、更新された Service または Deployment マニフェストを含む YAML ファイルの名前に置き換えます。
指標 API とデータの可用性のトラブルシューティング
以降のセクションでは、HorizontalPodAutoscaler が指標 API との通信を試みるか、指標バックエンドにクエリを実行しようとしたときに発生するエラーの解決方法について説明します。
カスタム指標と外部指標のトラブルシューティング
HorizontalPodAutoscaler がデフォルトの CPU やメモリ以外のソースの指標に依存している場合、カスタム指標または外部指標のパイプライン内で問題が発生する可能性があります。このパイプラインは、次の図に示すように、HorizontalPodAutoscaler コントローラ、Kubernetes 指標 API サーバー、指標アダプタ、指標ソース(Cloud Monitoring や Prometheus など)で構成されています。
現象
指標パイプラインの問題の最も一般的な症状は次のとおりです。
- 指標の値は
<unknown>と表示されます。 - HorizontalPodAutoscaler イベントに
FailedGetExternalMetricやFailedGetCustomMetricなどのエラーが表示されます。
原因
カスタム指標または外部指標のパイプライン内に問題があります。
解決策
次の手順に沿ってパイプラインをデバッグします。
指標アダプタが登録されて使用可能かどうかを確認する: 指標アダプタは、指標を提供するためにメインの Kubernetes API サーバーに登録する必要があります。このアクションは、アダプタが実行されていて API サーバーから到達可能かどうかを確認する最も直接的な方法です。
kubectl get apiservice | grep -E 'NAME|metrics.k8s.io'出力には、
v1beta1.custom.metrics.k8s.ioまたはv1beta1.external.metrics.k8s.ioのエントリと、Available列にTrueの値が表示されます。次に例を示します。NAME SERVICE AVAILABLE AGE v1beta1.metrics.k8s.io kube-system/metrics-server True 18dAvailable列の値がFalseであるか、欠落している場合、アダプタがクラッシュしているか、正しく構成されていない可能性があります。kube-systemまたはcustom-metricsNamespace でアダプタの Pod ログを調べて、権限、指標ソースへのネットワーク接続、指標が見つからなかったことを示すメッセージに関連するエラーがないか確認します。値が
Trueの場合は、次のステップに進みます。
指標 API を直接クエリする: アダプタが使用可能な場合は、HorizontalPodAutoscaler をバイパスして、Kubernetes API に指標を直接リクエストします。このコマンドは、API サーバーから指標アダプタ、データソースまでのパイプライン全体をテストします。
外部指標をクエリするには、次のコマンドを実行します。
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/NAMESPACE_NAME/METRIC_NAME" | jq .カスタム Pod 指標をクエリするには、次のコマンドを実行します。
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/NAMESPACE_NAME/pods/*/METRIC_NAME" | jq .次のように置き換えます。
NAMESPACE_NAME: Pod が実行されている Namespace。METRIC_NAME: クエリを実行しようとしているカスタム指標または外部指標の名前。たとえば、requests_per_secondやqueue_depthです。
コマンド出力を分析する: 前のコマンドの結果から、問題の発生場所を特定します。出力に一致するシナリオを選択します。
- 値を含む JSON レスポンスが成功した場合: 指標パイプラインは正しく機能しています。この問題は、HorizontalPodAutoscaler マニフェストの構成の問題である可能性があります。指標名にスペルミスがないか、
matchLabelsが正しくないかを確認します。 Error: Error from server (Service Unavailable): このエラーは通常、ネットワーク接続の問題を示します。多くの場合、ネットワーク分離を使用するクラスタのファイアウォールの問題です。指標アダプタ サービスを特定します。通常は、
custom-metricsまたはkube-systemNamespace にあります。kubectl get service -n custom-metrics,kube-system | grep -E 'adapter|metrics'アダプタがリッスンしているポートを確認します。
kubectl get service ADAPTER_SERVICE -n ADAPTER_NAMESPACE -o yaml次のように置き換えます。
ADAPTER_SERVICE: デプロイした指標アダプタに関連付けられている Kubernetes Service の名前。この Service は、前の手順で確認した Service です。この Service は、Kubernetes API サーバーなど、クラスタの他の部分にアダプタの機能を公開します。ADAPTER_NAMESPACE: アダプタ サービスが存在する Namespace(custom-metrics、kube-systemなど)。
クラスタのコントロール プレーンのインバウンド ファイアウォール ルールを確認します。
gcloud compute firewall-rules list \ --filter="name~gke-CLUSTER_NAME-[0-9a-z]*-master"CLUSTER_NAMEは、使用するクラスタの名前に置き換えます。アダプタの
targetPortをルールに追加します。現在のルールを取得して、既存の許可ポートを確認します。
gcloud compute firewall-rules describe FIREWALL_RULE_NAMEFIREWALL_RULE_NAMEは、Kubernetes クラスタのコントロール プレーンへのネットワーク トラフィックを制御するファイアウォール ルールの名前に置き換えます。アダプタポートをリストに追加するようにルールを更新します。
gcloud compute firewall-rules update FIREWALL_RULE_NAME \ --allow tcp:443,tcp:10250,tcp:ADAPTER_PORTADAPTER_PORTは、指標アダプタがリッスンしているネットワーク ポートに置き換えます。
Kubernetes ネットワーク ポリシーが指標アダプタ Pod へのトラフィックをブロックしていないことを確認します。
kubectl get networkpolicy -n custom-metrics,kube-systemポリシーを確認して、コントロール プレーンまたは API サーバーから
ADAPTER_PORTのADAPTER_SERVICEへの上り(内向き)トラフィックが許可されていることを確認します。
空のリスト
[]: この出力は、アダプタは実行されているが、特定の指標を取得できないことを意味します。これは、アダプタの構成または指標ソース自体に問題があることを示しています。アダプタ Pod の問題: 指標アダプタ Pod または Pod のログを調べて、API 呼び出し、認証、指標の取得に関連するエラーを確認します。ログを検査する手順は次のとおりです。
アダプタ Pod の名前を確認します。
kubectl get pods -n ADAPTER_NAMESPACEログを表示します。
kubectl logs ADAPTER_POD_NAME \ -n ADAPTER_NAMESPACE次のように置き換えます。
ADAPTER_POD_NAME: 前の手順で特定したアダプタ Pod の名前。ADAPTER_NAMESPACE: アダプタ Pod が存在する Namespace(custom-metricsやkube-systemなど)。
ソースにデータがない: 指標がソースシステムに存在しない可能性があります。Metrics Explorer などのモニタリング ツールを使用して、指標が存在し、名前とラベルが正しいことを確認します。
- 値を含む JSON レスポンスが成功した場合: 指標パイプラインは正しく機能しています。この問題は、HorizontalPodAutoscaler マニフェストの構成の問題である可能性があります。指標名にスペルミスがないか、
指標バージョンが見つからないか、アダプタが使用できない
現象
次のエラーが表示されます。
unable to fetch metrics from custom metrics API: no known available metric versions found
原因
このエラーは、クラスタ内の通信障害を示しており、指標ソース(Cloud Monitoring など)の問題を示しているわけではありません。一般的な原因は次のとおりです。
- Kubernetes API サーバーが一時的に使用できない(クラスタのアップグレードやコントロール プレーンの修復中など)。
- 指標アダプタ Pod(
custom-metrics-stackdriver-adapterなど)が異常な状態であるか、実行されていない。あるいは、API サーバーに正しく登録されていない。
解決策
この問題は一時的なものであることがよくあります。問題が解決しない場合は、次の解決策を試しください。
Kubernetes コントロール プレーンの健全性を確認する:
Google Cloud コンソールで、クラスタの健全性とステータスを確認します。
[Kubernetes クラスタ] ページに移動します。
クラスタの [ステータス] 列と [通知] 列を確認します。
[ 通知] をクリックして、アップグレードや修理など、進行中のオペレーションがないか確認します。この間、API サーバーが一時的に使用できなくなることがあります。
Cloud Audit Logs で、コントロール プレーン コンポーネントに関連するエラーを確認します。これらのログを表示する方法については、GKE 監査ロギング情報をご覧ください。
指標アダプタ Pod の健全性とログを確認する: 指標アダプタ Pod が
Runningステータスであり、最近再起動されていないことを確認します。kubectl get pods -n custom-metrics,kube-system -o widePod のステータスが
Running以外の場合や、再起動回数が多い場合は、Pod を調べて根本原因を特定します。トラブルシューティングのヒントについては、Kubernetes ドキュメントの Pod のデバッグをご覧ください。指標 API が登録され、使用可能であることを確認する:
kubectl get apiservice | grep metrics.k8s.io指標 API が正常な場合、出力は次のようになります。
NAME SERVICE AVAILABLE AGE v1beta1.custom.metrics.k8s.io custom-metrics/custom-metrics-stackdriver-adapter True 18d v1beta1.external.metrics.k8s.io custom-metrics/custom-metrics-stackdriver-adapter True 18d v1beta1.metrics.k8s.io kube-system/metrics-server True 18dAVAILABLE列の値がFalseの場合、完全な APIService マニフェストのMessage列に詳細情報が記載されていることがあります。次のコマンドを使用すると、マニフェスト全体を表示できます。
kubectl get apiservice API_SERVICE_NAME -o yamlAPI_SERVICE_NAMEは、APIService オブジェクトの名前(v1beta1.custom.metrics.k8s.ioなど)に置き換えます。
指標クエリが時系列を返さない
現象
次のエラーが表示されます。
unable to fetch metrics from custom or external metrics API: googleapi: Error
400: The supplied filter [...] query will not return any time series
原因
Cloud Monitoring に送信されたクエリは有効ですが、データは返されません。これは、フィルタに一致するデータポイントが存在しないことを意味します(値が 0 の指標が見つかった場合とは異なります)。この問題で最も可能性の高い原因は、カスタム指標の生成を担当するアプリケーションまたはワークロードが、エラー報告時に Cloud Monitoring にデータを書き込んでいなかったことです。
解決策
次の解決策を試してください。
- 構成を確認する: HorizontalPodAutoscaler オブジェクトの指標名とラベルが、アプリケーションによって出力されるものと正確に一致していることを確認します。
- 権限を確認する: Cloud Monitoring に指標を公開するために必要な権限と API エンドポイントを使用して、アプリケーションが正しく構成されていることを確認します。
- アプリケーションのアクティビティを確認する: 指標を担当するアプリケーションが動作しており、HorizontalPodAutoscaler の警告が発生した期間中に Cloud Monitoring にデータを送信しようとしていたことを確認します。
- エラーを調査する: 同じ期間のアプリケーションのログを調べて、接続エラー、無効な認証情報、形式の問題など、関連する明示的なエラーが指標の出力にないか確認します。
スケーリング動作が正常だが予期しない場合のトラブルシューティング
以降のセクションでは、HorizontalPodAutoscaler の構成が有効で指標が使用可能であるにもかかわらず、スケーリング アクションが想定どおりに実行されないシナリオについて説明します。
HorizontalPodAutoscaler は正常だがスケーリングされない
現象
HorizontalPodAutoscaler は正常に動作しているように見え、条件は True を報告し、イベントにエラーは表示されません。ただし、スケーリング アクションは実行されません。
原因
この想定される動作を引き起こす要因はいくつかあります。
- レプリカの上限: 現在のレプリカ数が、HorizontalPodAutoscaler 構成の
minReplicasフィールドまたはmaxReplicasフィールドで設定された上限に達しています。 - 許容範囲: Kubernetes は、デフォルトの 10% の許容範囲を使用して、指標のわずかな変動によるスケーリングを防ぎます。スケーリングは、現在の指標と目標指標の比率が 0.9~1.1 の範囲外になった場合にのみ行われます。たとえば、CPU の目標が 85% で、現在の使用率が 93% の場合、比率は約 1.094(93/85≈1.094)になります。この値は 1.1 未満であるため、HorizontalPodAutoscaler はスケールアップしません。
- 準備ができていない Pod: HorizontalPodAutoscaler は、
Readyステータスの Pod のみをスケーリング計算に含めます。Pendingステータスのままになっている Pod や、ヘルスチェックの失敗やリソースの問題によりReadyにならない Pod は無視され、スケーリングが妨げられる可能性があります。 - 同期期間の遅延: HorizontalPodAutoscaler コントローラは指標を定期的にチェックします。指標がしきい値を超えてからスケーリング アクションが開始されるまでの遅延は、通常 15~30 秒です。
- 新しい指標のレイテンシ: HorizontalPodAutoscaler が新しいカスタム指標を初めて使用する場合、数分のレイテンシが 1 回発生することがあります。この遅延が発生するのは、最初のデータポイントが書き込まれたときに、モニタリング システム(Cloud Monitoring など)が新しい時系列を作成する必要があるためです。
- 複数の指標の計算: 複数の指標を構成すると、HorizontalPodAutoscaler は各指標に必要なレプリカ数を個別に計算し、計算された値のうち最も大きい値を最終的なレプリカ数として選択します。この動作により、ワークロードは最もニーズの高い指標の需要を満たすようにスケーリングされます。たとえば、CPU 指標で 9 個のレプリカが必要と計算され、1 秒あたりのリクエスト数指標で 15 個のレプリカが必要と計算された場合、HorizontalPodAutoscaler は Deployment を 15 個のレプリカにスケーリングします。
解決策
次の解決策を試してください。
- レプリカの上限: HorizontalPodAutoscaler マニフェストまたは
kubectl describeコマンドの出力でminReplicas値とmaxReplicas値を確認します。必要なスケーリングが妨げられている場合は、これらの上限を調整します。 - 許容範囲: デフォルトの許容範囲内でスケーリングが必要な場合は、別の許容範囲の値を構成します。それ以外の場合は、指標が 0.9~1.1 の比率から外れるまで待ちます。
- 準備ができていない Pod: Pod が
Pendingである理由またはReadyでない理由を調査し、根本的な問題(リソースの制約、準備状況プローブの失敗など)を解決します。トラブルシューティングのヒントについては、Kubernetes ドキュメントの Pod のデバッグをご覧ください。 - 同期期間の遅延と新しい指標のレイテンシ: これらのレイテンシは正常です。同期期間が完了するか、新しいカスタム指標の時系列が作成されるまで待ちます。
- 複数の指標の計算: これは想定どおりの動作です。1 つの指標(1 秒あたりのリクエスト数など)に基づいてスケールアップが行われている場合、別の指標の低い計算(CPU など)が正しくオーバーライドされます。
HorizontalPodAutoscaler がスケールダウンに失敗する
現象
HorizontalPodAutoscaler はワークロードを正常にスケールアップしますが、CPU 使用率などの指標が低い場合でもスケールダウンできません。
原因
この動作は、不完全な情報に基づいて迅速にスケールアップ / ダウンしたり、スケールダウンすることを防ぐように設計されています。主な理由は次のとおりです。
- 複数の指標を使用する: HorizontalPodAutoscaler は、最も多くのレプリカを必要とする指標に基づいてスケーリングします。複数の指標がある場合、すべての指標がレプリカの減少を示していない限り、ワークロードはスケールダウンされません。多くのレプリカ数が必要な指標が 1 つでもあると、他の指標が低くてもスケールダウンが防止されます。
- 使用できない指標: 指標が使用できなくなった場合(多くの場合
<unknown>と表示されます)、HorizontalPodAutoscaler はワークロードのスケールダウンを拒否します。使用量が実際にゼロであるか、指標パイプラインが破損しているかによって、指標が欠落しているかどうかを判断できません。この問題は、レートベースのカスタム指標(messages_per_secondなど)でよく発生します。アクティビティがないとデータのレポートが停止し、HorizontalPodAutoscaler が指標を利用不可と認識して、スケールダウン オペレーションが停止します。 - スケーリング ポリシーからのスケールダウンの遅延: HorizontalPodAutoscaler の
behaviorフィールドを使用すると、スケーリング ポリシーを構成できます。スケールダウンのデフォルト ポリシーには、300 秒(5 分)の安定化ウィンドウが含まれています。この期間中、指標の値が目標しきい値を下回っても、HorizontalPodAutoscaler はレプリカ数を減らしません。このウィンドウにより急激な変動は防止されますが、スケールダウンが予想よりも遅くなる可能性があります。
解決策
次の解決策を試してください。
複数の指標と使用できない指標については、問題の原因となっている指標を診断します。
kubectl describe hpa HPA_NAME -n NAMESPACE_NAME出力の
Metricsセクションでステータスが<unknown>の指標を探し、EventsセクションでFailedGetCustomMetricやFailedGetExternalMetricなどの警告を探します。パイプラインのデバッグの詳細については、カスタム指標と外部指標のトラブルシューティングをご覧ください。使用できない指標で、トラフィックが少ない期間に指標が使用できなくなった場合(レートベースの指標でよくある)、次のいずれかの解決策を試してください。
- 可能な場合は、レートベースの指標ではなくゲージベースの指標を使用します。キュー内のメッセージの合計数(
subscriptionやnum_undelivered_messagesなど)のようなゲージ指標は、値が0であっても値を一貫して報告するため、HorizontalPodAutoscaler はスケーリングの決定を確実に行うことができます。 - 指標ソースがゼロ値を報告していることを確認します。カスタム指標を制御する場合は、データをまったく送信しないのではなく、非アクティブ期間中に
0を公開するように構成します。
- 可能な場合は、レートベースの指標ではなくゲージベースの指標を使用します。キュー内のメッセージの合計数(
スケーリング ポリシーからのスケールダウンの遅延については、スケールダウンのデフォルトの安定化ウィンドウ(5 分間)が長すぎる場合は、カスタマイズします。HorizontalPodAutoscaler マニフェストの
spec.behavior.scaleDownセクションを調べます。stabilizationWindowSecondsを小さくすると、指標が低下した後にオートスケーラーがより迅速にスケールダウンできるようになります。これらのポリシーの構成の詳細については、Kubernetes ドキュメントのスケーリング ポリシーをご覧ください。
次のステップ
このドキュメントで問題を解決できない場合は、サポートを受けるで、次のトピックに関するアドバイスなど、詳細なヘルプをご覧ください。
- Cloud カスタマーケアに問い合わせて、サポートケースを登録する。
- StackOverflow で質問する、
google-kubernetes-engineタグを使用して類似の問題を検索するなどして、コミュニティからサポートを受ける。#kubernetes-engineSlack チャネルに参加して、コミュニティ サポートを利用することもできます。 - 公開バグトラッカーを使用して、問題の報告や機能リクエストの登録を行う。