計算基盤とスケジューリングのアーキテクチャ
翻訳についての注記: 本ドキュメントは英語原文
15-deployment/07-compute-platform-scheduling.mdを日本語に翻訳したものです。コードブロックおよびMermaidダイアグラムは原文のまま維持しています。
TL;DR
設計したサービスは最終的に、誰かのスケジューラが有限のコア・メモリ・帯域・ファイルディスクリプタを持つマシン上に置いたプロセスとして動く。基盤は実装詳細ではない。レイテンシの尾(CPUクォータの周期、メモリ逼迫下のGC、退避)、爆発半径(悪いテナント1つ、悪いノード1つがどう障害になるか)、そして請求書(パッキング効率)を決定するのは基盤だ。スタッフレベルの設計は基盤との契約を明示する。各ワークロードが何を予約し、どこまでバーストでき、何が最初に殺され、どう停止を通知され、不均衡と障害のためにフリートがどの程度の余裕を保つかまで。リソース制御と配置が他のすべてを支配する2つの機構である。リソース制御はcgroup v2のノブであり、CPU帯域(cpu.max、固定周期で補充されるクォータ)とメモリ上限(memory.high、memory.max)を、宣言されたrequestとlimitから基盤がマッピングしたものだ。そのセマンティクスは非対称で、多くのチームは逆様に覚える: 使われなかったCPU requestはスケジュールの保証だが、使われなかったCPU limitは100ms周期で静かに課税する。一方メモリは一切伸縮しない — 超えれば何かが死ぬ。配置は制約付きビンパッキングの問題で、可用性のために拡散し、コストのために詰める。その2つの目的の差がそのままユーティライゼーションになる。推論: 多くの基盤は容量で失敗する前にライフサイクル規律で失敗する。クリーンに止められないPodは、例行のノードローテーションをユーザーに見えるエラーに変えてしまうからだ。
ワークロード分類と配置契約
配置の意思決定は、クラスタにたまたま空きがあるかどうかからではなく、ワークロードが何かから導き出される。
| クラス | 例 | スケジューリング上の必要 | リソースの方針 |
|---|---|---|---|
| レイテンシ敏感な同期 | APIハンドラ、決済、検索サービング | ゾーン間に拡散、低い充填密度、バースト依存の隣接なし | p95使用量でCPU request、limitは未設定か大きめ。メモリはrequest = limit |
| スループットバッチ | コンパクション、エクスポート、トランスコード | プリエンプションに耐える。安価な容量と高い充填を望む | スポット/プリエンプティブル、通知付きで退避可能、進捗のチェックポイント |
| 状態を持つ単一構成要素 | データベース、ブローカ、リーダ | 逆アフィニティ、トポロジ認識、ストレージクラスとゾーン固定 | Guaranteed QoS、オーバーコミットなし、専用ノードプールが勝つことが多い |
| 長尾の非同期 | ジョブ、ワークフロー、コンシューマ | キュー深度をスケーリング信号に。テナント間の公平性 | Burstable、優先度ティア、低ティアのプリエンプション許可 |
| 分離されたテナント計算 | テナント単位の計算、ノートブック | 硬い分離境界、テナント単位のクォータとノードプール | クォータと独立した障害ドメイン。共有カーネルキャッシュの仮定は禁止 |
アプリケーションチームに公開する契約は、1ページで7つの質問に答えるべきだ。
- requestは何を買うのか(スケジュールの保証か、余剰容量の分け前か)
- limitに達したら何が起きるのか(スロットル、退避、殺害、それともテナントのトラフィック制限か)
- どのノードプールに載ってもよいのか。必要ならそれを指定できるのか
- 一度に許される撹乱はどれだけか(PodDisruptionBudgetは絶対レプリカ数で書く。0に丸まるパーセンテージでなく)
- グレースフル停止は何秒かかり、その締切を誰が強制するのか
- 30秒前の割り込み通知が来たら何が起きるのか
- 余裕(headroom)のコストは誰が払い、アイドル容量はどう回収するのか
この7つの答えが伝承になっている基盤は、サービスごとの恒久的な調整を強いられ続ける。本記事が扱うのは配置・リソース制御のセマンティクス・ライフサイクル・フリートレベルの障害挙動であり、デプロイのロールアウト機構(プログレッシブデリバリー)、オートスケーリングの制御ループ、テナントのアイデンティティと認可(マルチテナンシ)ではない。
カーネルから上のリソース制御
コンテナはlimitをcgroups v2から得る。YAMLの下の層を知っておくと、「基盤が遅い」チケットの大半が説明つく。
CPU帯域。 cpu.maxはquota periodを持ち、kubelet設定の既定周期は100msだ。CPU limitが500mのPodは、全スレッド合わせて100msあたり50msまでしか実行できない。周期の冒頭でクォータを使い切るプロセスは、次の補充までスケジューリングされないため、スロットルは比例したスループット損失ではなく100ms周期のレイテンシスパイクとして現れる。カーネルはこれをcpu.stat(nr_throttled、throttled_usec)で直接公開し、cAdvisorがcontainer_cpu_cfs_throttled_periods_totalとして再輸出する。文書化済み事実: CPUのrequestは重み(cpu.weight)に写り、競合したときだけ効く。一方limitは、ノードが空いていてもコンテナがクォータを超えた瞬間に効く帯域制御をインストールする。
内面に置くべき帰結が2つある。
- マルチスレッドランタイム(多数のGCスレッドを持つJVM、GOMAXPROCSがホストコア数等于のGoプログラム)をCPU limitで縛ると、1つの周期でクォータをすべて消費して停止しうる。ランタイムの並列数を実効CPU割り当てに揃えるほうが、limitを引き上げるより効くことが多い。
- limitなしのCPU requestは、保証された重みと無制限のバーストを与える。専用プール上のレイテンシ敏感サービスが望むのはこれだ。トレードオフは公平性で、暴れるテナントが他のテナントが借りられると前提していた余剰を食い尽くす。だからバーストには「迷信で設定したlimit」ではなく、受け入れの話(プール分離かテナント別クォータ)が必要になる。
メモリ。 メモリは圧縮できず、 まともにスロットルできない。基盤の道具は早期の逼迫(memory.highは割り当てをスロットルする)と死(memory.maxはcgroup内のOOM killerを発動)だけだ。KubernetesのQoSクラスが誰から先に死ぬかを決める: Guaranteedが最も守られ、BestEffortが最も守られず、Burstableはその中間でスケールする。文書化済み事実: kubeletはノードの逼迫(メモリ・ディスク・PIDシグナル)時に追加でPodを退避する。ハード/ソフトの閾値があり、コンテナlimitとは別の機構で、別のイベント(OOMKilledではなくEvicted)を出す。
プラットフォームをまたいで有効な実務規則:
- レイテンシ敏感ワークロードはメモリrequest = limitにする。実使用量より低いrequestは、他のPodが今まさに破っている約束に対してスケジューラに配置されたことを意味し、ノードはその嘘を退避で解決する。
- メモリは平均ではなく、working setのパーセンタイルに最も悪い正当なバースト(キャッシュウォームアップ、大きなコンパクション、1本の病的なクエリ)の余裕を足して決める。
- 何が上限に算入されるかを知る: ページキャッシュは回収可能だが、tmpfs上のファイル・匿名メモリ・カーネルスラブ割り当ては不可能だ。
- 大抵のKubernetesノードはスワップ無効なので、「スワップの激しい往復」の代わりに「OOM kill」が来る。より速く、より容赦がない。
その他の上限。 ファイルディスクリプタ(ulimit -n)、PID(pids.max。スレッドリークで到達)、ノードのnetfilterテーブルのconntrackエントリ(nf_conntrack: table full, dropping packetはCPUに何の兆候もない謎の502として現れる)、ログとイメージレイヤ用のエフェメラルストレージ(disk-pressure退避)、inode枯渇。これら全部がスケジューラ隣接の容量制限で、デプロイマニフェストに一度も現れないため障害で発見される。
配置: 可用性制約付きビンパッキング
スケジューラは3つの決定をする: どのワークロードを配置するか、どのノードが適格か、そして適格なノードのうちどれが最善か。Kubernetesのスケジューリングフレームワークはこれをフィルタリングとスコアリングのプラグインに分けるが、他のスケジューラも語彙が違うだけで形は同じだ。設計上の決定は以下。
パッキング戦略。 最も空きノードを優遇するスコア関数はワークロードを広げる(可用性は良く、コストは悪く、小さいノードが増える)。最も詰まったノードを優遇するスコアはきつく詰める(コストは良く、爆発半径は悪い)。実際の基盤は両方を混ぜる: 障害ドメインの内側では詰め、ドメインの間では広げる。GoogleのBorg論文は、1万台規模でのこの緊張の正典的な記述であり、ジョブを受け入れる前に予約を確認するアドミッション制御と、メモリが尽きたときに優先度クラスを保ったまま退避する方針を含む。
障害ドメインの算数。 レプリカ分散は、障害ドメインが実在するときだけ役に立つ。ゾーン逆アフィニティはAZ独立性を、トポロジ分散制約はノードプール間の均等さを、Pod逆アフィニティは2人のリーダが1ホストに載ることを防ぐ。ドメイン数が可用性の予算を決める — 3ゾーンなら1つの喪失に耐え、5なら余裕を持って1つに耐える。「高可用性」を名乗る2レプリカ・2ゾーンのサービスは、2つ目の障害時にもノード保守中にも余裕がない。
マシン内部のトポロジ。 NUMAはメモリ律速のサービスで効く: 対向ノードのメモリアクセスは局所より明確に遅い。だから大規模マシン上のレイテンシ敏感ワークロードはCPUマネージャとトポロジマネージャの整合を望む(Kubernetesがその前提条件として文書化しているのはGuaranteed QoSと整数CPU数だ)。ハイパースレッドの子は同じコアの実行ユニットを共有するため、子ペア上の「1 CPU」のクォータは物理1コアのスループットではない。これを無視したベンチマークは基盤の不安定性として読まれてしまう。
ギャングおよびバッチスケジューリング。 分散学習ジョブは全か無かの配置を必要とする: 半分がGPUを握ったまま残りを待つのは金の無駄だ。これはPod単位の最善努力ではなく、予約付きのギャングスケジューリング(Volcano、Kueue、YARN capacity queues)を要求する。GPU主体のワークロードはデバイスプラグイン、MIGパーティショニング、そして能力でデバイスを要求するための構造化パラメータ/DRAを追加する。
統合と撹乱。 増設しかしないオートスケーラはフリートを半分空のままにする。コンソリデーション機構(Karpenterのconsolidation、cluster-autoscalerのscale-down)は、Podを他所へ再配置できるならノードを除去する。尊重すべきPodDisruptionBudgetが必要で、まさにここが「3日間アップグレードが止まっている」の発生源だ。予算ルールは最小レプリカ数でも許容撹乱が0に丸まらないように書き、割り込み処理はクラウドが文書化する通知期間(AWS EC2 Spotは回収2分前、GCP Preemptible VMは30秒)をドレン締切として扱って実装する。
ライフサイクル: ワークロードの始め方と止め方
起動と停止はボイラープレートではなく正しさに関わる経路である。
起動。 キャッシュのウォームアップに40秒かかるコンテナは、プロセスがリッスンを開始した時点でreadyではない。Kubernetesは意味の異なる3つのプローブを与える: startupは他をゲートし、readinessはこのPodをエンドポイントに含めるかを決め、livenessは再起動するかどうかを決める。ここを間違えると2つの古典的な障害が生まれる: トラフィックスパイク中にサービスを殺すliveness(死んでいなくて、混雑していただけ)、そして早すぎるreadiness(プランキャッシュも接続プールもないのにトラフィックが来る)。障害モードはクライアント側から読むこと。サービスディスバリ伝播の遅延はロールアウトリスクの一部であり、だからこそレディネスゲートとターゲットグループ登録が効いてくる。
停止。 文書化されたkubeletの手順は: preStopを実行、SIGTERMを送る、terminationGracePeriodSecondsまで待ち、SIGKILL。工学的な帰結は4つ。
- SIGKILLは扱えない。必ず行う後始末は猶予期間内にマージンを残して収める必要がある。実行中リクエストの締切は猶予期間より厳しく短く、猶予期間は基盤自身のドレインタイムアウトより短くする。
- エンドポイント除去と停止が競合する。ロードバランサの登録解除は非同期なので、Podは停止を開始した後もリクエストを受け続けうる。実用的な修正は
preStopでのスリープ加えてreadinessの切替え、または実行中p99より長いLBドレイン遅延だ(Elastic Load Balancingの接続ドレイン既定が5分なのはまさにこのため)。 - コンテナ内のPID 1セマンティクス: シェルのラッパ(
sh -c "java -jar app.jar")はexecやinit: trueを使わないとシグナルを飲み込む。グレースフルシャットダウンが一度も走らない。コンテナイメージで最も多い目に見えない欠陥の一つ。 - ドレインとは新しい仕事を受けることを拒否するだけでなく、仕事を終わらせることだ: 書き込みバッファとコンシューマオフセットをフラッシュし、リースを解放し(または失効を待つ。リース1回分かかる)、終わりきれないキューからの消費をやめ、実行中の仕事が見守った後にプールを閉じる。
ステートレスな同期サービスの停止手順は、コピーする価値のある参照設計として以下。
1. flip readiness to false # stop new traffic admission
2. sleep >= discovery/LB propagation # bounded, measured, not guessed
3. stop accepting new requests # return 503 with Retry-After where honest
4. drain in-flight up to deadline # log what got cut, count it as an error
5. flush sinks (metrics, logs, offsets)
6. close dependency pools and exit 0 # exit non-zero only if something failed状態を持つワークロードはルールを1つ足す: 停止中のプロセスが、他の誰かが待っているロックやリースを持ち続けないこと。意図的に解放し、解放経路をハッピーパスと同じ程度にテストする(リースの記事を参照)。
トラフィックからレプリカへ: サイズのモデル
サイズの連鎖は算数であり、基盤の仕事はその算数を可視化することだ。
1リージョン2,000 RPS・平均レスポンスタイム40ms・Podあたり同時実行数64まで処理できる非同期サーバ・目標使用率0.7というAPIを考える。
- 実行中の並列数(Littleの法則):
2,000 x 0.040 = 80リクエスト - 同時実行上限から必要なPod数:
ceil(80 / 64) = 2。目標使用率0.7ならceil(80 / (64 x 0.7)) = 2。しかし2Podは可用性への回答ではないので、障害ドメインの規則で下限を張る。3ゾーンで1ゾーン喪失に耐えるには最低4Pod必要で、3つが残って各々が33%多い負荷を実行上限を超えずに担える - 実測からのPodあたりCPU request: この同時実行でp95使用量が1.4 vCPUならrequestは1.5 vCPU。メモリはworking set 2 GiBに30%の余裕を足してrequest = limit
- スケールアウトのトリガー: 最初に飽和する信号を選ぶ。CPU使用率が妥当な代用になるのはスレッドが制約である場合だけ。非同期I/O律速のサービスでは実行中の並列数かキュー深度が正直な信号で、バースト中は遅延ベース(コンシューマあたりのキュー長)のスケーリングはCPUより数分早く反応する
- オートスケーラの挙動: 増設は速く(安定化ウィンドウなし)、縮小はゆっくり(文書化された既定の安定化ウィンドウは5分)。早すぎるスケールインは2分のスパイクをコールドスタートの嵐に変えるから
推論: Kubernetesホストのサービスで最も多いサイズの誤りは、レプリカ不足ではなく、リクエスト単位の並列性に対してCPU limitが小さすぎることで、それはレプリカがいくらあっても1リクエストのレイテンシを頭打ちにする。容量を追加する前にスロットルのカウンタを確認すること。使用率35%でp99がひどいフリートは、たいていサイズ不足ではなくスロットルされている。
フリート経済とheadroom
ユーティライゼーションは美徳ではなく予算の決定である。3つの曲線がトレードオフになる。
- パッキング効率は、より詰まった配置とより緩い分散制約で上がる。無駄になった容量の1ポイントは大規模では金になる。Googleはフリート全体のプロファイリングと配置の改善で、計装のコストを正当化できるだけのリソースを回収したと報告している
- 障害headroomは充填とともに減る。定常使用率90%のクラスタは、ノードプールの喪失にも、30%の追加容量を必要とする失敗したデプロイにも、AZ障害後のリバランスにも耐えられない — まさにそのとき、容量は最も高く、最も遅い
- 復旧速度は、安全に返却できるheadroomの量を決める。新しいノードが3分で現れPodが2分でreadyになるなら、GPUノードのプロビジョニングに25分かかる基盤より、常時待機させる予備は少なくてすむ
3つを同時に正直に保つ実用的な構造は、フリートをベースラインプール(予約済み・保護済み・定常負荷+障害ドメイン1つ分)、エラスティックプール(安価またはスポット形状・分散分のサイズ・グレースフルにドレンできる)、バースト枠(悪いと分かっている時間に申請できるクォータ。四半期ごとに訓練済み)に分けるものだ。チームへの請求はrequestではなくworking setのp95にすること。request課金はフリートを40%の幽霊予約で満たす最短の方法だからだ。
セキュリティ、分離、マルチリージョンの注意
- 名前空間の分離はAPIサーバの概念であってハードウェアの境界ではない。テナントが任意コードを実行する状況で爆発半径を縛るのは、ノードプール、RuntimeClass/サンドボックスランタイム、テナント別クォータだ(テナントライフサイクルの半分はマルチテナンシの記事に譲る)
- カーネル共有リソースは情報と干渉を漏らす。最終レベルキャッシュとメモリ帯域は分区しない限り共有される(Intel RDT系の技術か専用プール)ため、騒がしい隣接ワークロードはCPUの兆候ゼロでレイテンシ敏感な隣人を劣化させうる
- ノードのアイデンティティが効く: kubeletの資格情報、ノードのサービスアカウント、そしてコンテナランタイムのソケット(
/var/run/docker.sockやcontainerdソケットのPodマウントはroot等価の許可)は、基盤の脅威モデルに含まれるべきだ - マルチリージョンの配置はリソースのセマンティクスを変える。リージョン間のスケジューリング決定は通常、クラスタのスケジューラではなくDNSかグローバル負荷分散が行う。自分のトラフィックの100%でサイズ設定されたリージョンプールは、隣リーの分を担う瞬間に失敗を保証するものだ。Nリージョンで1つの喪失を吸収する必要があれば、各リージョンを
1 / (N - 1)のグローバルピークでサイズすること
失敗トレース
使用率35%でスロットル。 GoサービスがKubernetesへ移行するとダッシュボードは健康そうなのにp99が倍になった。GOMAXPROCSはホストのコア数、CPU limitは500m、cpu.statはほとんどの周期がスロットル済みと示す。修正: ランタイムの並列数を実効CPUに揃え(auto-GOMAXPROCSか明示値)、再計測する。レプリカは増やさなかった。
自分を殺したキャッシュ。 あるサービスはメモリrequest 1 GiB・limitなしで、バッチジョブと同じBurstable QoSノード上で、設計どおりプロセス内キャッシュを3 GiBまで成長させた。ノードがメモリ逼迫閾値に達し、kubeletは最優先度の低いPodから退避する。キャッシュコールドの再起動が裏側のデータベースを暴走させる。修正: キャッシュはrequest = limit、プロセス内に境界のある退避方針、そしてスタンピードにならないウォームアップ経路(スタンピードの記事を参照)。
ノードローテーション中のPDBデッドロック。 4レプリカの状態を持つStatefulSetがmaxUnavailable: 1を宣言しているが、Podはクォーラムのためにすべてreadyでなければならない。ノードの入れ替えが1つをドレンすると、残り3つはリカバリ中のためいつまでもreadyにならない。ロールアウトは止まる。個々のPodは壊れていない。予算がreadinessの独立性を前提にしていただけだ。
CPUもエラーもない502。 バーストがノードのconntrackテーブルを満たす。カーネルは新規接続のパケットを落とすため既存接続は無事であり、エラー率はランダムに見え、新しいクライアントでのみ増える。修正: nf_conntrack_maxを意図的に引き上げ、establishedタイムアウトを短くし、keep-aliveを積極化し、conntrackドロップを一次級の飽和シグナルとしてアラートする。
火曜日のドレインの嵐。 コンソリデーション機構が平常時に3ノードを同時に除去する。Podはすでに同時実行上限にあるノードへ再配置され、レイテンシは3倍になり、オートスケーラは6分かけて到着する容量を追加する。修正: Pod数だけでなく容量で同時退避に上限を与える撹乱予算と、ドレイン前に代替容量を先取りする増設方針。
停止時に失われた信号。 あるコンシューマは30秒のドレン後にオフセットをコミットする設計だが、terminationGracePeriodSecondsが既定の30秒のまま、実行中の仕事が45秒走っているためSIGKILLされる。下流の重複処理はブローカのせいになった。修正: 猶予期間を実行中p99とフラッシュ時間から導出し、「SIGKILLで終了」をリリースゲートとしてアサートする。
検証戦略
基盤との契約は図ではなく証拠で証明する。
- 飽和カウンタの配線: CPUスロットル率、requestに対するworking set、
oom_kill_total、退避イベント、conntrackの使用とドロップ、FDとPIDの使用量、エフェメラルストレージ、ゾーン別のPod数。それぞれにアラートかSLOダッシュボードのパネルを。USEメソッドはサービスだけでなくリソースにも適用される - スロットルテスト: 1Podのクォータ使用率を50%から110%へ押し上げる負荷プロファイルを実行し、メトリクスに見えるものがユーザーがレイテンシで見るものと一致することを確認する。スロットルがダッシュボードに見えなければ、limitを調整する前にダッシュボードを直す
- 殺害訓練: Pod 1つ、ノード1つ、ゾーン1つを殺し、クライアントに見えるエラーがレプリカと障害ドメインの算数が予言する予算内に収まることをアサートする。ゾーン冗長を名乗るサービスは、実測値付きで通る必要がある
- 停止経路の訓練: 負荷下でSIGTERMを送り、文書化した許容を超えるリクエスト損失がないこと、SIGKILL終了がないこと、オフセット解放が正しいことを検証する。「シャットダウン時のSIGKILL」をCIまたはソークテストで失敗させる
- 統合のリハーサル: 業務時間中に撹乱予算を有効にしたままノード削除を強制し、オートスケーラが退避の後ではなく前に容量を置き換えることを確認する
- クォータ現実チェック: 名前空間ごとにrequestを実測p95使用量と月次で比較する。説明できない予約は回収する。このレポートが最も安い容量になる
判断の枠組み
| 質問 | 推奨 | 避けるべき既定 |
|---|---|---|
| requestとlimitの意味? | request = 保証、limit = 強制。CPUは重み対帯域制御、メモリは上限対OOM方針 | 同じ値を迷信で両方に設定する |
| 詰め方 vs 広げ方? | 障害ドメインの内側では詰め、外側では広げる。レプリカ数はゾーン喪失の算数で下限 | どこでも均等分散(コスト) かどこでも密な充填(爆発半径) |
| スケーリング信号? | 最初に飽和する資源: 並列数、キュー深度、それからCPU | 非同期I/O律速サービスに対するCPU使用率 |
| 安価な容量? | 割り込み予算とチェックポイント付き仕事のエラスティックプール | レイテンシ敏感な同期トラフィックをプリエンプティブルに賭ける |
| 信用できないコードの分離? | 専用ノードプール、クォータ、サンドボックスランタイム、ホストソケットなし | 名前空間だけの分離 |
| グレースピリオド? | 実測の実行中p99 + フラッシュ時間。基盤のドレインタイムアウト未満 | 30秒の既定値、そしてSIGTERMを食べるシェルラッパ |
主要な要点
- requestは約束、limitは強制であり、効く機構が違う: CPUは重み対帯域制御、メモリは上限対OOM方針
- CPU limitは平均ではなくp99に現れる。クォータは固定周期で補充されるからだ。レプリカを買う前にスロットルカウンタを確認する
- メモリは非弾性だ。working setを持つものはrequest = limitにするか、ノードの逼迫が誰を殺すかを決める受け入れる
- 可用性は障害ドメインの算数 — レプリカ数をゾーン数で割り、ドメイン1つの喪失と保守1回分の余裕を残す
- 配置は制約付きビンパッキング。ドメインの内側で詰め、ドメインをまたいで広げ、headroomはリバランス中ではなく予算として支払う
- 停止の経路は正しさの経路だ: readiness切替え、締切のあるドレン、フラッシュ、終了 — 猶予期間は既定値ではなく実測の実行中レイテンシから導出す
- 割り込み可能な容量は、割り込みを設計してあれば問題ない。通知期間はドレイン締切、進捗はチェックポイント、同時退避は容量で縛る撹乱予算
- すべての基盤との約束にはカウンタと訓練が必要: スロットル率、OOM kill、退避、conntrackドロップ、SIGKILL終了、そして四半期に1回のノード殺害
参考文献
- Verma, A., Pedrosa, L., Korupolu, M. ら "Large-Scale Cluster Management at Google with Borg." EuroSys 2015 — 予約に対するアドミッション制御、充填と公平性の緊張、データセンター規模での退避と優先度クラス
- Kubernetesドキュメント: "Manage Resources for Containers"、"Pod Quality of Class"、"Pod Lifecycle and Termination"、"Pod Disruption Budgets"、"Topology Manager"、"Scheduling Framework"
- Linuxカーネルドキュメント: Control Group v2(
cpu.max、cpu.weight、memory.high、memory.max、pidsコントローラ)とCFS帯域制御の説明 - AWSドキュメント: Spotインスタンスの割り込み通知(回収2分前)とElastic Load Balancingの接続ドレインの既定値
- Dean, G., Barroso, L. A. "The Tail at Scale." Communications of the ACM 2013 — 共有資源の干渉がリクエスト単位のレイテンシを決める理由
- Cummins, J. ら "Profiling a Datacenter." SIGMETRICS 2021 — リソース計算が費用対効果を持つというフリート規模の証拠