なぜ今、AIワークロードのcgroup v2隔離が問われるのか
LLM推論サービスや分散学習ジョブをオンプレミスのKubernetesクラスターや専用サーバーへ相乗りさせる運用が、2024〜2025年にかけて一気に広まりました。GPUへのアクセス集中だけでなく、AIワークロードは「メモリを大量に確保してから実際の計算を開始する」「I/Oバーストが予測しにくい」という特性を持つため、同一ホスト上の既存テナントへの影響が従来のWebアプリやバッチ処理とは質的に異なります。
Linuxカーネルのcgroup v2(unified hierarchy)は、CPUやメモリ、ブロックI/Oを単一の階層で制御でき、プロセスの重複カウントを排除した正確な計測が可能です。一方でcgroup v1と設定インターフェースが大きく変わっており、「とりあえずlimits.memoryを設定しておけばいい」という旧来の感覚のままでは、隣テナントへのCPUスケジューリング圧や、ページキャッシュの奪い合いを見落とすリスクがあります。
本記事では、systemdスライスによるcgroup v2の隔離設計を起点に、実際の影響検証の手順、運用中に発生しやすい問題と切り戻し方法、そして2026年9月時点の主要ディストリビューション・カーネルでの差分まで整理します。
cgroup v2の設計モデルとAIワークロードの特性を合わせる
cgroup v2ではCPU・メモリ・I/Oの各コントローラーが単一ツリーに統合されています。子グループへコントローラーを伝播させるには、親グループのcgroup.subtree_controlに対象コントローラーを明示的に追加する必要があります。この点を見落とすと「設定したはずのlimitsが一切効いていない」という状況に陥ります。
AIワークロードを隔離設計する際に意識すべき主な特性は次の3点です。
- メモリのバースト確保:モデルロード時に数十〜数百GBを短時間で要求する。
memory.maxだけでなくmemory.highによるソフトスロットリングを活用し、OOM発火前に圧力をかける設計が有効です。 - CPUの爆発的スケジューリング需要:トークン生成やデータローダーのI/O展開時にCPUコアを瞬間的に飽和させます。
cpu.maxでクォータを設定する場合は、100ms周期での割り当て量に換算して適切な余裕を持たせます。 - ランダムI/Oバースト:チェックポイントの書き出しや大規模データセットの読み込みは他テナントのI/Oレイテンシを直撃します。
io.weightによる相対的な優先度調整とio.maxによる上限設定を組み合わせます。
systemdスライスによる隔離単位の設計
systemdを利用している環境では、/etc/systemd/system/ai-workload.sliceを作成してAI系プロセスをまとめる方法が現場での標準的なアプローチです。スライス内のサービスはSlice=ai-workload.sliceディレクティブで所属先を指定します。既存のsystem.slice配下のテナントと階層を分離することで、リソース制御のスコープが明確になります。
以下はスライスファイルの設定例です(コメントは説明のために付けています)。
# /etc/systemd/system/ai-workload.slice
[Unit]
Description=AI Workload Isolation Slice
[Slice]
# メモリ上限(ハード): ホスト実装メモリの60%相当を想定
MemoryMax=240G
# メモリ高水位(ソフトスロットル開始)
MemoryHigh=200G
# CPU割り当て上限: 全CPU時間の70%
CPUQuota=700%
# I/O加重(system.sliceのデフォルト100に対して低優先)
IOWeight=50
systemctl daemon-reloadとsystemctl start ai-workload.sliceで即時適用できます。スライスの設定変更は実行中のプロセスにも反映されるため、再起動なしに調整できる点が運用上の大きな利点です。
設定適用後の影響検証手順
設定が意図どおりに機能しているかを確認するには、cgroup階層の直接観察とアプリケーションレベルの計測を組み合わせる必要があります。
cgroup v2コントローラーの疎通確認
まず/sys/fs/cgroup/ai-workload.slice/cgroup.controllersとcgroup.subtree_controlの内容を照合します。設定したコントローラーがsubtree_controlに現れていなければ子プロセスへの伝播が止まっています。次にsystemd-cglsでスライス配下のプロセスツリーを目視し、対象プロセスが正しい階層に属しているかを確認します。
実際のリソース消費はsystemd-cgtopで監視するか、/sys/fs/cgroup/ai-workload.slice/memory.current・cpu.statを直接読み出します。cpu.statのnr_throttledとthrottled_usecがゼロ以外であれば、AIワークロードがCPUクォータに当たっていることを意味します。
他テナントへの影響を定量的に測る
影響検証では、AIワークロードを意図的に高負荷状態で動かしながら、同一ホスト上の既存サービスの応答時間やスループットを計測します。現場で採用されている手法の代表例は次の2つです。
- レイテンシ計測ループ:既存テナントのHTTPエンドポイントに対して
wrkやheyで継続的に負荷をかけ、AIジョブ開始前後のp99レイテンシを比較します。cgroup v2の隔離が適切であれば、p99の悪化は数%以内に収まるはずです。 - I/Oレイテンシの観察:
iostat -xz 1やiopingでAIジョブ稼働中のディスクI/O待ち時間を監視します。io.maxの上限値が低すぎるとAIジョブ自体のチェックポイント保存が遅延するため、実ワークロードのI/Oプロファイルを事前に計測してから上限値を決める手順が推奨されます。
メモリ圧力の確認には/sys/fs/cgroup/ai-workload.slice/memory.pressureのPSI(Pressure Stall Information)ファイルが有用です。full avg10が継続して5%を超えるようであれば、ページ回収がボトルネックになっており、他テナントのメモリ帯域に干渉している可能性があります。
問題発生時の切り戻しと注意点
cgroup v2の設定変更はsystemctl set-propertyでオンザフライに行えますが、永続化(--runtimeなし)された設定は/etc/systemd/system.control/配下のファイルに書き込まれます。予期しない動作が発生した場合は以下の手順で元の状態に戻せます。
systemctl revert ai-workload.sliceでsystem.controlの上書き設定を削除し、スライスファイルの初期値に戻します。- スライスファイル自体を変更していた場合は
gitなどのバージョン管理から旧ファイルを復元し、systemctl daemon-reloadとsystemctl restart ai-workload.sliceを実行します。 - 設定変更後に既存テナントのサービスが異常な高CPU状態になる場合、AIワークロードのクォータ上限を引き下げるだけでなく、
CPUShares相当のCPUWeightを既存スライスで引き上げる対処が有効なケースがあります。
注意すべき落とし穴として、memory.swap.maxの設定を省略するとスワップ使用の制限が効かず、AIワークロードが大量にスワップを消費して他テナントの実メモリ確保を圧迫する事例が報告されています。スワップを意図的に活用しない運用であればMemorySwapMax=0を明示的に指定することが推奨されます。
2026年現行環境における差分と留意事項
2026年9月時点でのLinuxカーネルおよびディストリビューションの状況を整理します。
カーネルとsystemdのバージョン動向
Ubuntu 24.04 LTS(カーネル6.8系)・RHEL 9.x(カーネル5.14系、ただし6.xへのバックポートが進行中)・Debian 13(Trixie、カーネル6.12系)が現行の主要環境です。カーネル6.7以降ではcgroup v2のmemory_recursiveprotがデフォルト有効になり、子グループのmemory.min/memory.low設定が親グループの設定を超えないよう自動補正されます。これにより過保護な設定を書いてしまっても親の上限で自動的に丸め込まれる挙動が変わっています。
systemd 255(Ubuntu 24.04に同梱)以降ではsystemd-oomdがcgroup v2のPSI情報を参照して積極的にOOM処理を行うようになっています。AIワークロードがmemory.highを超えて継続的な圧力をかけると、systemd-oomdがそのスライス内のプロセスを終了させる場合があります。ManagedOOMMemoryPressure=killとManagedOOMMemoryPressureLimit=の設定を明示的に調整することで、OOMDの介入閾値をコントロールできます。
