使用率の低さと配置予算の空きは異なる
一言でいうと
requestsは席を選ぶための約束で、limitsは実行中に使える量を制限する設定です。CPU使用率が低いという事実だけで、新しいPodが入る席があると判断してはいけません。
なぜ必要なのか
教室に人が5人しか座っていないのに、新しい受講生が入れません。席が空いているように見えますが、残りの椅子は午後の授業のために予約されています。今座っている人数と、予約された座席は、別の帳簿です。Kubernetesでも、現在の使用量と、スケジューリングに使うリソースの要求量は異なります。予約の比喩は、配置の判断を理解するためのものであり、CPUコア1つを特定のコンテナに物理的に専有で割り当てるという意味ではありません。
チームで小さなPythonアプリをデプロイしたのに、PodがPendingのままだとしましょう。コードは眠っているだけなので、CPUをほとんど使いません。ところが、マニフェストには誤ってrequests.cpuが8と書かれていて、どのノードもそれより小さいです。アプリがどれだけ暇かは、この問題を解決しません。アプリが起動する前に、宣言された要求がすでに、配置可能なノードの大きさを超えているからです。
どう動くのか
まず、4つの数字を区別します。
| 数字 | どんな質問に答えるか | 確認する場所 |
|---|---|---|
| capacity | ノードが報告するリソースの総量はいくらか | Node.status.capacity |
| allocatable | Podの配置に使えるリソース量はいくらか | Node.status.allocatable |
| requests | このPodを配置するときに計算する要求量はいくらか | コンテナのresources.requests |
| 実際の使用量 | 特定の観測区間でどれだけ使ったか | リソースメトリクスAPI・モニタリング |
このレッスンは、通常のコンテナのCPU・メモリの要求に集中します。initコンテナ、Podオーバーヘッド、Podレベルのリソース設定、拡張リソースなどがある場合は、計算ルールを追加で確認する必要があります。単純な1つのコンテナの算数を、すべてのワークロードにそのまま適用してはいけません。
たとえば、あるノードのallocatable CPUが2で、すでに配置された要求の合計が1.4なら、新しい要求800mを加えた合計は2.2です。CPUの条件だけでも合いません。実際の使用量が200mと観測されても、要求の合計はひとりでに減りません。逆に、要求の合計が合うからといって、配置の成功が保証されるわけではありません。メモリ、ノードの選択条件、taint、ボリュームなど、ほかの条件も満たす必要があります。
CPU 1は1CPU単位で、1000mと同じです。250mは0.25 CPUであり、ノード全体の250パーセントではありません。メモリのMiとMも同じではありません。64Miは64×1024×1024バイトで、64Mは64×1000×1000バイトです。リソースの問題を読むとき、単位を省略すると、異なる帳簿を同じ数字で比較することになります。
limitsは別の軸です。CPUの制限は、実行時間を制限するthrottlingとして、メモリの制限は、状況によってOOM終了として現れることがあります。requestsを超えたからといって、すぐに終了されるわけではありません。要求量を低く、制限量を高く書くと、余裕があるときにより多く使うこともできます。だからといって、要求を無条件に下げるのが解決策ではありません。過小な要求は、あまりに多くの作業を同じノードに送り込み、性能の競合と圧迫を生むことがあります。
現場での姿
失敗した箇所を絞り込む順序を練習します。
kubectl -n kcna-capacity get pod oversized -o json
kubectl -n kcna-capacity describe pod oversized
kubectl get nodes -o json
1つ目に、Podオブジェクトが実際に存在するかを見ます。2つ目に、spec.nodeNameがあるかと、PodScheduled条件を見ます。3つ目に、そのPod UIDに該当するFailedSchedulingイベントを読みます。名前が同じ過去のPodのイベントを持ってくると、入れ替え前のエラーを現在の原因と誤解することがあります。Pendingはイメージのダウンロードなどほかの準備の過程も含むので、その一語だけでCPU不足と結論づけません。
ここでInsufficient cpuが確認されたら、宣言した要求とノードのallocatable、そして既存の要求を照合します。要求が本当に必要な大きさなら、より大きなノード、作業の分割、不要な予約の整理のような選択肢を検討します。タイプミスなら、根拠を持って直します。運用中のほかのチームのPodを削除したり、ノードの状態を直したりして、数字だけを合わせることは診断ではありません。
あとのラボですること
個人用のk3sの実際のallocatableより大きなCPU要求を宣言しますが、CPUを使い尽くす負荷プログラムは実行しません。APIに保存されたPodが配置されない証拠を収集したあと、そのUIDの試験用Podだけを回収し、50mの要求の小さなPodが起動するかを比較します。別のネームスペースの正常な比較群は、最後まで維持します。この実験は、CPUの飽和・throttling・OOMを直接測定する実験とは異なります。