このページでは、Google Kubernetes Engine(GKE)クラスタでクラスタ オートスケーラーがノードをスケールアップしない問題を検出して解決する方法について説明します。
このページは、アプリやサービスで発生した予期しない状況やネガティブな状況を解決したいアプリ デベロッパー、プロダクトやサービスの提供の中断を防ぎたいプラットフォーム管理者およびオペレーターを対象としています。
クラスタ オートスケーラーがノードをスケールアップするタイミングを理解する
トラブルシューティングの手順に進む前に、クラスタ オートスケーラーがノードのスケールアップを試みるタイミングを理解しておくと役に立ちます。クラスタ オートスケーラーは、既存のリソースが不足している場合にのみノードを追加します。
クラスタ オートスケーラーは 10 秒ごとに、スケジュールできない Pod があるかどうかを確認します。Pod がスケジュールできなくなるのは、リソースが不足している、ノードに制約がある、または Pod の要件が満たされていないことが原因で、Kubernetes スケジューラが Pod を既存のノードに配置できない場合です。
クラスタ オートスケーラーは、スケジュールできない Pod を検出した場合、ノードの追加により Pod がスケジュール可能になるかどうかを評価します。ノードの追加により Pod がスケジュール可能になる場合、クラスタ オートスケーラーはマネージド インスタンス グループ(MIG)に新しいノードを追加します。Kubernetes スケジューラは、新しくプロビジョニングされたノードに Pod をスケジュールできるようになります。
スケジュール不可の Pod があるかどうかを確認する
クラスタのスケールアップが必要かどうかを判断するには、スケジュールされていない Pod を確認します。
Google Cloud コンソールの [ワークロード] ページに移動します。
[フィルタ] フィールドに「unschedulable
」と入力して、Enter キーを押します。リストに Pod が表示される場合は、スケジュール不可の Pod があります。スケジュール不可の Pod のトラブルシューティングを行うには、エラー: Pod unschedulable をご覧ください。多くの場合、スケジューリング不可の Pod の根本的な原因を解決すると、クラスタ オートスケーラーがスケールアップできるようになります。クラスタ オートスケーラーに固有のエラーを特定して解決するには、この後の各セクションをご覧ください。
リストに Pod が表示されない場合、クラスタ オートスケーラーはスケールアップする必要がなく、想定どおりに動作しています。
以前にスケジュール不可の Pod があったかどうかを確認する
過去にクラスタ オートスケーラーが失敗した原因を調査している場合は、以前にスケジュール不可の Pod があったかどうかを確認します。
Google Cloud コンソールで、[ログ エクスプローラ] ページに移動します。
表示するログエントリの期間を指定します。
クエリペインに次のクエリを入力します。
logName="projects/PROJECT_ID/logs/events" jsonPayload.source.component="default-scheduler" jsonPayload.reason="FailedScheduling"
PROJECT_ID
は、実際のプロジェクト ID に置き換えます。[クエリを実行] をクリックします。
リストに結果が表示される場合は、指定した期間にスケジュール不可の Pod があります。
問題の原因が制限事項であるかどうかを確認する
スケジュール不可の Pod があることを確認したら、クラスタ オートスケーラーの問題がクラスタ オートスケーラーの制限によるものではないことを確認します。
エラーを確認する
多くの場合、エラー メッセージからスケールアップの問題の原因を診断できます。
エラー メッセージが表示されている場合は、エラー メッセージの表でエラーの解決に関するアドバイスを確認してください。
メッセージが表示されていない場合は、次のいずれかを行います。
- 72 時間以内の問題: Google Cloud コンソールでエラー通知を確認します。
- 72 時間以上前の問題: Cloud Logging のイベントでエラーを確認します。
通知でエラーを確認する
問題が発生して 72 時間以内であれば、Google Cloud コンソールでエラーに関する通知を確認します。これらの通知では、クラスタ オートスケーラーがスケールアップしなかった理由について貴重な分析情報が提供されます。また、エラーを解決する方法や、関連するログを表示して詳細を調査する方法に関するアドバイスも提供されます。
Google Cloud コンソールで通知を表示するには、次の操作を行います。
Google Cloud コンソールで、[Kubernetes クラスタ] ページに移動します。
[通知] 列を確認します。次の通知は、スケールアップの問題に関連しています。
Can't scale up
Can't scale up pods
Can't scale up a node pool
関連する通知をクリックすると、問題の原因とその解決に推奨される対応方法の詳細が表示されます。
省略可: このイベントのログを表示するには、[ログ] をクリックします。この操作を行うと、ログ エクスプローラが開き、スケーリング イベントの詳細な調査に役立つクエリが自動的に設定されます。スケールアップ イベントの仕組みの詳細については、クラスタ オートスケーラー イベントを表示するをご覧ください。
通知に表示されたアドバイスを試しても問題が解決しない場合は、エラー メッセージの表を参照してください。
イベントでエラーを確認する
検出された問題が 72 時間以上前に発生している場合は、Cloud Logging でイベントを表示します。多くの場合、発生したエラーはイベントに記録されます。
Google Cloud コンソールでクラスタ オートスケーラーのログを表示するには、次の操作を行います。
Google Cloud コンソールで、[Kubernetes クラスタ] ページに移動します。
調査するクラスタの名前を選択して、[クラスタの詳細] ページを表示します。
[クラスタの詳細] ページで、[ログ] タブをクリックします。
[ログ] タブで、[オートスケーラー ログ] タブをクリックしてログを表示します。
省略可: 高度なフィルタを適用して結果を絞り込むには、ページの右側にある矢印のボタンをクリックして、ログ エクスプローラでログを表示します。
スケールアップ イベントの詳細については、クラスタ オートスケーラー イベントを表示するをご覧ください。Cloud Logging の使用方法の例については、次のトラブルシューティングの例をご覧ください。
例: 72 時間以上経過した問題のトラブルシューティング
次の例は、クラスタがスケールアップされない問題を調査して解決する方法を示しています。
シナリオ: 過去 1 時間、Pod がスケジュール不可としてマークされています。クラスタ オートスケーラーは、Pod をスケジュールする新しいノードをプロビジョニングしませんでした。
解決策:
- 問題が発生してから 72 時間以上経過しているため、通知メッセージを確認するのではなく、Cloud Logging を使用して問題を調査します。
- Cloud Logging で、イベントのエラーを表示するの説明に従って、クラスタ オートスケーラー イベントのロギングの詳細を確認します。
調査対象の Pod を含む
scaleUp
イベントをtriggeringPods
フィールドで検索します。特定の JSON フィールド値によるフィルタリングなど、ログエントリをフィルタリングできます。詳細については、高度なログクエリをご覧ください。スケールアップ イベントは見つかりません。もし見つかった場合は、
scaleUp
イベントと同じeventId
を含むEventResult
を探してみてください。その後、errorMsg
フィールドで、有効な scaleUp エラー メッセージ一覧を調べます。scaleUp
イベントは見つからなかったため、引き続きnoScaleUp
イベントを検索し、次のフィールドを確認します。unhandledPodGroups
: Pod(または Pod のコントローラ)に関する情報が含まれます。reason
: スケールアップがブロックされる可能性があることを示す代表的な理由を示します。skippedMigs
: 一部の MIG がスキップされる可能性がある理由を示します。
Pod の
noScaleUp
イベントがあります。また、rejectedMigs
フィールド内のすべての MIG について、理由メッセージ ID が"no.scale.up.mig.failing.predicate"
であり、"NodeAffinity"
と"node(s) did not match node selector"
の 2 つのパラメータがあります。
解決策:
エラー メッセージ一覧を調べたところ、保留中の Pod のスケジューリングの述語が失敗したため、クラスタ オートスケーラーがノードプールをスケールアップできないことがわかりました。パラメータは、失敗した述語の名前と失敗した理由です。
この問題を解決するには、Pod のマニフェストを調べ、クラスタ内の MIG と一致しないノードセレクタが Pod のマニフェストに含まれていることを確認します。Pod のマニフェストからこのセレクタを削除し、Pod を再作成します。クラスタ オートスケーラーが新しいノードを追加し、Pod がスケジュールされます。
スケールアップ エラーを解決する
エラーを特定したら、次の表を使用して、エラーの原因と解決方法を確認します。
ScaleUp エラー
scaleUp
イベントのエラー メッセージは、対応する eventResult
イベントの resultInfo.results[].errorMsg
フィールドにあります。
メッセージ | 詳細 | パラメータ | 緩和策 |
---|---|---|---|
"scale.up.error.out.of.resources" |
リソースエラーは、GPU や CPU などの Compute Engine リソースが現在利用できないことが原因でリクエストに対応できないゾーンで、新しいリソースをリクエストしようとした場合に発生します。 | 失敗した MIG ID。 | Compute Engine ドキュメントのリソースの可用性に関するトラブルシューティング手順に沿って対応します。 |
"scale.up.error.quota.exceeded" |
Compute Engine の割り当て超過で MIG の一部を増やすことができなかったため、scaleUp イベントが失敗しました。 | 失敗した MIG ID。 | Google Cloud コンソールで MIG の [エラー] タブをチェックして、超過している割り当てを確認します。どの割り当てが超過しているかを確認したら、手順に沿って割り当ての増加をリクエストします。 |
"scale.up.error.waiting.for.instances.timeout" |
タイムアウトにより、マネージド インスタンス グループのスケールアップに失敗しました。 | 失敗した MIG ID。 | このメッセージは一時的なものです。 問題が解決しない場合は、Cloud カスタマーケアにお問い合わせのうえ、さらに調査を依頼してください。 |
"scale.up.error.ip.space.exhausted" |
一部のマネージド インスタンス グループ内のインスタンスが IP 不足になったため、スケールアップできません。つまり、新しいノードや Pod の追加に使用する未割り振りの IP アドレス空間がクラスタに不足しています。 | 失敗した MIG ID。 | Pod の空き IP アドレス空間が不足しているのトラブルシューティング手順に沿って対応します。 |
"scale.up.error.service.account.deleted" |
サービス アカウントが削除されたため、スケールアップできません。 | 失敗した MIG ID。 | サービス アカウントの削除を取り消すことを試みます。 この手順で問題が解決しない場合は、Cloud カスタマーケアにお問い合わせのうえ、さらに調査を依頼してください。 |
noScaleUp イベントが発生する理由
noScaleUp
イベントは、クラスタ内にスケジュール不可の Pod があり、クラスタ オートスケーラーが Pod に対応するようにクラスタをスケジュールできない場合に定期的に生成されます。noScaleUp
イベントはベスト エフォート型であり、考えられるすべてのケースに対応しているわけではありません。
NoScaleUp の最上位の理由
noScaleUp
イベントの最上位の理由メッセージが noDecisionStatus.noScaleUp.reason
フィールドに表示されます。このメッセージには、クラスタ オートスケーラーがクラスタをスケールアップできない最上位の理由が含まれています。
メッセージ | 詳細 | 緩和策 |
---|---|---|
"no.scale.up.in.backoff" |
スケールアップがバックオフ期間中(一時的にブロック中)であるため、スケールアップされません。これは、多数の Pod のスケールアップ イベント中に発生する可能性のあるメッセージです。 | このメッセージは一時的なものです。数分後にこのエラーを確認します。 このメッセージが続く場合は、Cloud カスタマーケアにお問い合わせのうえ、さらに調査を依頼してください。 |
NoScaleUp のノードの自動プロビジョニングの最上位の理由
noScaleUp
イベントに関するノードの自動プロビジョニングの最上位の理由メッセージが noDecisionStatus.noScaleUp.napFailureReason
フィールドに表示されます。このメッセージには、クラスタ オートスケーラーが新しいノードプールをプロビジョニングできない最上位の理由が含まれています。
メッセージ | 詳細 | 緩和策 |
---|---|---|
"no.scale.up.nap.disabled" |
ノード自動プロビジョニングがクラスタレベルで有効になっていないため、ノード自動プロビジョニングをスケールアップできませんでした。 ノード自動プロビジョニングが無効になっている場合、保留中の Pod に既存のノードプールによって満たすことができない要件があると、新しいノードは自動的にプロビジョニングされません。 |
クラスタ構成を確認し、ノード自動プロビジョニングの有効化を検討してください。 |
NoScaleUp の MIG レベルの理由
noScaleUp
イベントに関する MIG レベルの理由メッセージが noDecisionStatus.noScaleUp.skippedMigs[].reason
フィールドと noDecisionStatus.noScaleUp.unhandledPodGroups[].rejectedMigs[].reason
フィールドに表示されます。このメッセージには、クラスタ オートスケーラーが特定の MIG のサイズを増やすことができない理由が含まれています。
メッセージ | 詳細 | パラメータ | 緩和策 |
---|---|---|---|
"no.scale.up.mig.skipped" |
シミュレーション中に MIG がスキップされたため、MIG をスケールアップできません。 | MIG がスキップされた理由(Pod 要件がないなど)。 | エラー メッセージに含まれるパラメータを確認し、MIG がスキップされた理由に対応します。 |
"no.scale.up.mig.failing.predicate" |
保留中の Pod のスケジューリングの述語に問題があるため、ノードプールをスケールアップできません。 | 失敗した述語の名前と失敗した理由。 | アフィニティ ルール、taint、toleration、リソース要件などの Pod の要件を確認します。 |
NoScaleUp のノード自動プロビジョニングの Pod グループレベルの理由
noScaleUp
イベントに関するノード自動プロビジョニングの Pod グループレベルの理由に関するメッセージが noDecisionStatus.noScaleUp.unhandledPodGroups[].napFailureReasons[]
フィールドに表示されます。このメッセージには、クラスタ オートスケーラーが特定の Pod グループをスケジュールする新しいノードプールをプロビジョニングできない理由が含まれています。
メッセージ | 詳細 | パラメータ | 緩和策 |
---|---|---|---|
"no.scale.up.nap.pod.gpu.no.limit.defined" |
保留中の Pod に GPU リクエストがありますが、GPU リソース上限がクラスタレベルで定義されていないため、ノード自動プロビジョニングでノードグループをプロビジョニングできませんでした。 | リクエストされた GPU タイプ。 | 保留中の Pod の GPU リクエストを確認し、クラスタレベルのノード自動プロビジョニングの GPU 制限についての構成を更新します。 |
"no.scale.up.nap.pod.gpu.type.not.supported" |
ノード自動プロビジョニングで不明な GPU タイプに対するリクエストがあったため、Pod のノードグループがプロビジョニングされませんでした。 | リクエストされた GPU タイプ。 | 保留中の Pod の構成で GPU タイプを確認し、サポートされている GPU タイプと一致していることを確認します。 |
"no.scale.up.nap.pod.zonal.resources.exceeded" |
ノード自動プロビジョニングでこのゾーン内の Pod のノードグループがプロビジョニングされませんでした。これは、プロビジョニングを実施すると、クラスタ全体の最大リソース上限に違反するか、ゾーン内で使用可能なリソースを超過するか、またはリクエストに対応できるマシンタイプがないためです。 | 対象ゾーンの名前。 | クラスタ全体の最大リソース上限、Pod リソースのリクエスト、またはノード自動プロビジョニングに使用できるゾーンを確認して更新します。 |
"no.scale.up.nap.pod.zonal.failing.predicates" |
述語が失敗したため、ノード自動プロビジョニングで、このゾーン内の Pod のノードグループがプロビジョニングされませんでした。 | 対象ゾーンの名前と、述語が失敗した理由。 | アフィニティ ルール、taint、容認機能、リソースの要件など、保留中の Pod の要件を確認します。 |
詳細な調査を行う
以降のセクションでは、ログ エクスプローラと gcpdiag
を使用してエラーに関する追加の分析情報を取得する方法について説明します。
ログ エクスプローラでエラーを調査する
エラー メッセージをさらに調査する場合は、エラーに固有のログを確認します。
Google Cloud コンソールで、[ログ エクスプローラ] ページに移動します。
クエリペインに次のクエリを入力します。
resource.type="k8s_cluster" log_id("container.googleapis.com/cluster-autoscaler-visibility") jsonPayload.resultInfo.results.errorMsg.messageId="ERROR_MESSAGE"
ERROR_MESSAGE
は、調査するメッセージに置き換えます。例:scale.up.error.out.of.resources
[クエリを実行] をクリックします。
gcpdiag を使用してエラーをデバッグする
gcpdiag
は、Google Cloud テクニカル エンジニアのサポートを受けて作成されたオープンソース ツールです。正式にサポートされている Google Cloud プロダクトではありません。
次のいずれかのエラー メッセージが表示された場合は、gcpdiag
を使用して問題のトラブルシューティングを行うことができます。
scale.up.error.out.of.resources
scale.up.error.quota.exceeded
scale.up.error.waiting.for.instances.timeout
scale.up.error.ip.space.exhausted
scale.up.error.service.account.deleted
gcpdiag
ツールのフラグの一覧と説明については、gcpdiag
の使用手順をご覧ください。
複雑なスケールアップ エラーを解決する
以降のセクションでは、緩和策に複数のステップが含まれるエラーと、クラスタ オートスケーラー イベント メッセージが関連付けられていないエラーを解決する方法について説明します。
問題: Pod がノードに適合しない
クラスタ オートスケーラーは、Pod の要件を満たす十分なリソース(GPU、メモリ、ストレージなど)がある場合のみ、ノードに Pod をスケジュールします。これがクラスタ オートスケーラーがスケールアップしなかった理由かどうかを判断するには、リソース リクエストと提供されたリソースを比較します。
次の例は CPU リソースを確認する方法を示していますが、GPU、メモリ、ストレージ リソースでも手順は同じです。CPU リクエストとプロビジョニングされた CPU を比較する手順は次のとおりです。
Google Cloud コンソールの [ワークロード] ページに移動します。
PodUnschedulable
エラー メッセージをクリックします。[詳細] ペインで、Pod の名前をクリックします。Pod が複数ある場合は、最初の Pod から始めて、各 Pod に対して次のプロセスを繰り返します。
Pod の詳細ページで、[イベント] タブに移動します。
[イベント] タブで [YAML] タブに移動します。
Pod 内の各コンテナのリソース リクエストをメモして、リソース リクエストの合計を確認します。たとえば、次の Pod 構成では、Pod に 2 つの vCPU が必要です。
resources: limits: cpu: "3" requests: cpu: "2"
スケジュール不可の Pod があるクラスタのノードプールの詳細を表示します。
Google Cloud コンソールで、[Kubernetes クラスタ] ページに移動します。
Pods unschedulable
エラー メッセージが表示されているクラスタの名前をクリックします。[クラスタの詳細] ページで、[ノード] タブに移動します。
[ノードプール] セクションで、[マシンタイプ] 列の値をメモします。例:
n1-standard-1
リソース リクエストを、マシンタイプが示す vCPU と比較します。たとえば、Pod がリクエストする vCPU が 2 つであっても、使用可能なノードのマシンタイプが
n1-standard-1
の場合、ノードの vCPU は 1 つだけになります。このような構成では、新しいノードが追加されても、この Pod はノードに適合しないため、クラスタ オートスケーラーはスケールアップを実行しません。使用可能なマシンタイプの詳細については、Compute Engine ドキュメントのマシン ファミリーのリソースと比較ガイドをご覧ください。
また、合計リソースの一部がシステム コンポーネントの実行に必要なため、ノードの割り当て可能なリソースは合計リソースよりも少なくなります。この計算方法の詳細については、ノード割り当て可能リソースをご覧ください。
この問題を解決するには、ワークロードに定義されたリソース リクエストがニーズに合っているかどうかを判断します。マシンタイプを変更しない場合は、Pod からのリクエストをサポートできるマシンタイプを使用してノードプールを作成します。Pod リソースのリクエストが正確でない場合は、Pod がノードに適合するように Pod の定義を更新します。
問題: 異常なクラスタが原因でスケールアップできない
クラスタが異常であると判断された場合、クラスタ オートスケーラーはスケールアップを実行しないことがあります。クラスタの異常は、コントロール プレーンの正常性ではなく、正常なノードと準備完了ノードの比率に基づいています。クラスタ内のノードの 45% が異常であるか、準備ができていない場合、クラスタ オートスケーラーはすべてのオペレーションを停止します。
これがクラスタ オートスケーラーがスケールアップしない理由である場合、クラスタ オートスケーラーの ConfigMap に、タイプが Warning
で、理由が ClusterUnhealthy
のイベントがあります。
ConfigMap を表示するには、次のコマンドを実行します。
kubectl describe configmap cluster-autoscaler-status -n kube-system
この問題を解決するには、異常なノードの数を減らします。
一部のノードは、実際には準備完了であっても、クラスタ オートスケーラーでは準備完了と見なされない可能性もあります。これは、接頭辞 ignore-taint.cluster-autoscaler.kubernetes.io/
の taint がノードにある場合に発生します。クラスタ オートスケーラーは、その taint が存在する限り、ノードを NotReady
と見なします。
ignore-taint.cluster-autoscaler.kubernetes.io/.*
taint の存在が原因でこの動作が発生している場合は、この taint を削除します。
次のステップ
- さらにサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。