Kubernetes環境で「FailedScheduling」というエラーに直面しましたか?ご安心ください、これは多くのKubernetesユーザーが経験する一般的な問題の一つです。このエラーは、PodがKubernetesクラスタ内のどのノードにも適切に配置(スケジューリング)できなかったことを意味します。ですが、ほとんどの場合、適切な手順を踏めば速やかに解決できます。
この記事では、Windowsユーザーの方向けに、この厄介なエラーの原因を特定し、最も迅速に解決するための具体的な手順をPowerShell/Cmdコマンドを交えて解説します。結論から申し上げると、ほとんどの場合、リソース不足かTaint/Tolerationの設定ミスが原因です。焦らず、以下の手順を試してみてください。
目次
1. Kubernetes FailedScheduling とは?(概要と緊急度)
FailedSchedulingは、KubernetesがPodをクラスタ内の利用可能なノードに配置しようとしたものの、何らかの理由でその試みが失敗したことを示すステータスです。
具体的には、Podが要求するCPU、メモリ、その他のリソースがどのノードにも不足している場合や、ノードに設定された特定の制約(Taint)とPodが許容する制約(Toleration)が一致しない場合などに発生します。このエラーが発生すると、対象のPodは「Pending」状態のままで起動せず、そのPodが提供するサービスは利用できません。
サービスによっては緊急度が高い問題となりますが、多くの場合、原因は比較的単純であり、適切な対処をすれば短時間で解決可能です。まずは落ち着いて、次に示す「最速の解決策」を試してみましょう。
2. 【最速】今すぐ試すべき解決策
FailedSchedulingエラーが発生したPodを特定し、そのPodのイベントログを確認することが、原因を特定し解決への道を切り開く最も速い方法です。まずは、以下のコマンドでエラーの詳細を確認しましょう。
解決策1:Podのイベントログから原因メッセージを確認する
エラーが発生しているPodの名前がわかっている場合、以下のkubectl describeコマンドを実行して、Podのイベントログを確認します。これにより、スケジューリングに失敗した具体的な理由が示されます。
kubectl describe pod <Pod名> -n <Namespace名>
実行例:
kubectl describe pod my-nginx-pod-xxxxxx -n default
このコマンドの出力の「Events」セクションに注目してください。FailedSchedulingイベントの後に、スケジューラがPodを配置できなかった具体的な理由が示されます。よくあるメッセージの例は以下の通りです。
- リソース不足の場合:
0/3 nodes are available: 3 Insufficient cpu, 3 Insufficient memory.
(3つのノード全てでCPUまたはメモリが不足していることを示します。) - Taint/Tolerationの不一致の場合:
0/3 nodes are available: 3 node(s) had untolerated taint {key: "dedicated", value: "test", effect: "NoSchedule"}.
(特定のTaintを持つノードがあり、PodがそのTaintを許容するTolerationを持っていないことを示します。)
このメッセージに基づき、以下の簡単な対処を試みてください。
もし「Insufficient cpu」や「Insufficient memory」と表示されたら:
これは、クラスタ内のどのノードも、Podが要求するCPUやメモリのリソースを満たせないことを意味します。最も手軽な一時的な解決策は、そのPodのリソース要求を緩和するか、クラスタ内の別のPodを削除してリソースを解放することです。
- Podのリソース要求を一時的に減らす(推奨はしませんが緊急時には有効):
PodのYAMLファイルを編集し、resources.requestsのcpuやmemoryの値を減らします。その後、Podを再作成します。kubectl edit pod <Pod名> -n <Namespace名>注意:
kubectl editは一時的な対処であり、DeploymentなどのコントローラによってPodが再作成されると元の設定に戻ります。恒久的な変更には、Deployment等のYAMLファイルを直接編集してください。 - 他の不要なPodを削除してリソースを解放する:
クラスタ内で現在動作しているが重要度の低い他のPodがあれば、それらを一時的に削除してリソースを解放し、問題のPodがスケジューリングされるスペースを作ります。kubectl get pods -A # 全てのnamespaceのPodを確認 kubectl delete pod <削除したいPod名> -n <Namespace名> - ノードの現在のリソース使用状況を確認する:
どのノードがどれくらいリソースを使用しているかを確認し、特定のノードに余裕がないか調べます。kubectl top nodeこのコマンドは、ノードごとのCPUとメモリの使用率を表示します。リソースに余裕のあるノードがない場合、ノードの増強を検討する必要があります。
もし「node(s) had untolerated taint」と表示されたら:
これは、特定のノードに設定されたTaint(Podの配置を制限するマーカー)を、Podが許容するToleration(Taintを許容する設定)を持っていないためにスケジューリングできなかったことを意味します。
- PodにTolerationを追加する:
問題のPodのYAMLファイル(通常はDeploymentなどのコントローラのYAML)に、該当するTaintを許容するTolerationを追加します。# PodのYAMLファイル(例: Deployment)に以下を追加 apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: template: spec: tolerations: - key: "dedicated" operator: "Equal" value: "test" effect: "NoSchedule" # ...他のPod設定...YAMLファイルを編集したら、
kubectl apply -f <ファイル名.yaml>で適用し、Podの再作成を待ちます。 - ノードからTaintを一時的に削除する(緊急時またはテスト時):
これはクラスタ全体に影響を与える可能性があるため、注意して行ってください。特定のノードからTaintを削除することで、そのノードにPodがスケジューリングされるようになります。kubectl taint nodes <ノード名> <Taintキー>=<Taint値>:<Effect>-実行例:
kubectl taint nodes my-node-1 dedicated=test:NoSchedule-末尾の
-はTaintを削除する指示です。
3. Kubernetes FailedScheduling が発生する主要な原因(複数)
上記で確認したEventsセクションのメッセージは、FailedSchedulingの具体的な原因を示唆しています。主な原因は以下の通りです。
3.1. CPU/メモリリソースの不足
クラスタ内のどのノードも、Podがresources.requestsで指定したCPUまたはメモリを満たせない場合に発生します。
- Insufficient CPU/Memory: ノードのキャパシティが、Podの要求するリソースに対して単純に不足している状態です。
- Overcommitment: ノードに既に多くのPodが配置されており、見かけ上リソースがあっても、実際に利用可能なリソースが不足している場合があります。
3.2. TaintとTolerationの不一致
ノードに特定のTaintが設定されているにもかかわらず、PodがそのTaintを許容するTolerationを持っていない場合に発生します。
- ノードの役割分離: 特定のワークロード(例: GPUを使うPod、管理者用Pod)専用のノードにTaintを設定し、一般的なPodが配置されないようにしているケース。
- ノードのメンテナンス: ノードをメンテナンスモードにするためにTaintを設定しているケース。
3.3. NodeSelectorやNodeAffinityの不一致
PodがnodeSelectorやnodeAffinityを使って特定のノードのラベルを要求しているが、クラスタ内にそのラベルを持つノードが存在しない、または条件を満たすノードがない場合に発生します。
- ラベルのタイプミス: Podの
nodeSelectorで指定したラベルキーや値が、実際のノードのラベルと一致していない。 - 適切なノードの不足: 特定の要件を持つノード(例: 特定のハードウェア、OS)がクラスタ内に存在しない。
3.4. ポート競合
PodがhostPortを使用している場合、ターゲットノードでそのポートがすでに他のPodやプロセスによって使用されているとスケジューリングできません。
3.5. クラスタの状態異常
ノードがNotReady状態であったり、ネットワークの問題でノードとマスターが適切に通信できていない場合も、Podはスケジューリングされません。
4. Kubernetesで恒久的に再発を防ぐには
一時的な解決策だけでなく、FailedSchedulingエラーの再発を防ぐための恒久的な対策を講じることが重要です。
4.1. リソース管理の最適化
- 適切なResource Requests/Limitsの設定: PodのYAMLファイルで
resources.requestsとresources.limitsを正確に設定します。requestsはスケジューリング時に使用され、limitsはPodが利用できる最大リソースを制限します。これにより、ノードのリソースを適切に予約し、過剰な消費を防ぎます。resources: requests: cpu: "200m" # 0.2 CPUコアを要求 memory: "256Mi" # 256MBメモリを要求 limits: cpu: "500m" # 最大0.5 CPUコアまで memory: "512Mi" # 最大512MBメモリまで - クラスタオートスケーラー (Cluster Autoscaler) の導入: クラスタのリソースが不足した場合に、自動的にノードを追加する仕組みを導入することで、リソース不足によるスケジューリング失敗を防ぎます。
- 垂直Podオートスケーラー (Vertical Pod Autoscaler: VPA) または水平Podオートスケーラー (Horizontal Pod Autoscaler: HPA) の利用:
- VPA: Podの過去のリソース使用状況に基づいて、Podのリソース要求・制限を動的に調整します。
- HPA: PodのCPU使用率などのメトリクスに基づいて、Podのレプリカ数を自動的に増減させます。
- 監視とアラート: PrometheusやGrafanaなどの監視ツールを導入し、ノードやPodのリソース使用率を常に監視します。リソース枯渇の兆候を早期に検知し、アラートを設定することで、問題が顕在化する前に対応できます。
4.2. TaintとToleration戦略の見直し
- 明確なTaintポリシーの定義: どのようなノードに、どのような目的でTaintを設定するのかを明確なポリシーとして定義します。
- Tolerationの適切な適用: 必要なPodにのみ適切なTolerationを設定し、意図しないノードにPodが配置されないようにします。
- Taintの定期的な確認: 不要になったTaintがノードに残っていないか定期的に確認し、クリーンアップします。
4.3. ノードの増強と健全性の維持
- ノードのキャパシティ計画: 将来的なワークロードの増加を見越して、ノードのCPU、メモリ、ストレージのキャパシティを計画的に増強します。
- ノードの健全性監視: ノードが
Ready状態であるか、ディスク容量が十分であるかなど、ノードの健全性を継続的に監視します。問題のあるノードは速やかに修復または交換します。
4.4. NodeSelector/NodeAffinityの正確な利用
- ラベルの一貫性: ノードに適用するラベルは一貫性を持たせ、Podが要求するラベルと正確に一致するようにします。
- Affinity/Anti-affinityの活用: 複雑なスケジューリング要件がある場合は、
nodeAffinityやpodAffinity/podAntiAffinityを利用して、Podの配置をより柔軟に制御します。
これらの対策を講じることで、FailedSchedulingエラーの発生を大幅に減らし、安定したKubernetesクラスタ運用が可能になります。問題が解決しない場合は、Kubernetesの公式ドキュメントやコミュニティフォーラムも参考にしてみてください。