#cgroups (Control Group)
プロセスグループのリソースの利用を制限・隔離するLinux カーネルの機能。
##cgroups の仕組み
cgroups はプロセスをグループ単位で管理し、そのグループに対してリソースの制限・計測・優先度付けを行う。
主な役割は以下の 3 つ。
- 制限 (Limiting): CPU・メモリなどの使用量に上限を設ける
- 計測 (Accounting): グループ内のリソース使用量を追跡する
- 制御 (Controlling): プロセスの一時停止・再開などを行う
プロセスは必ずいずれかの cgroup に属しており、子プロセスは親の cgroup を継承する。
##サブシステム (コントローラ)
cgroups はリソース種別ごとに コントローラ (サブシステム) と呼ばれる独立した機能として分かれている。
cat /proc/cgroups
#subsys_name hierarchy num_cgroups enabled
cpuset 0 75 1
cpu 0 75 1
cpuacct 0 75 1
blkio 0 75 1
memory 0 75 1
devices 0 75 1
freezer 0 75 1
net_cls 0 75 1
perf_event 0 75 1
net_prio 0 75 1
hugetlb 0 75 1
pids 0 75 1
rdma 0 75 1
misc 0 75 1
| コントローラ | 概要 |
|---|---|
cpu | CPU 時間のスケジューリングと使用率の制限 |
cpuset | 使用する CPU コアや NUMA ノードの割り当て |
memory | メモリ・スワップの使用量制限と計測 |
blkio | ブロックデバイスへの I/O 帯域の制限 (v1) |
io | ブロック I/O の制限 (v2 での名称) |
pids | グループ内で生成できるプロセス数の制限 |
net_cls | ネットワークパケットへのクラス ID 付与 |
freezer | グループ内プロセスの一時停止・再開 |
##/sys/fs/cgroup の構造
cgroups は仮想ファイルシステムとして /sys/fs/cgroup に公開されている。ファイルを読み書きすることでリソース設定の確認・変更が行える。
# v2 の場合のディレクトリ構造 (例)
/sys/fs/cgroup/
├── cgroup.controllers # 利用可能なコントローラ一覧
├── cgroup.procs # このグループに属するプロセスの PID 一覧
├── memory.max # メモリ上限
├── cpu.max # CPU 使用率上限
└── mygroup/ # 作成したサブグループ
├── cgroup.procs
├── memory.max
└── cpu.max
各ファイルの意味はコントローラごとに決まっており、例えば memory.max はそのグループのメモリ上限 (バイト) を表す。
##基本的な操作
cgroups v2 はディレクトリとファイルの操作だけで管理できる。
# サブグループを作成
mkdir /sys/fs/cgroup/mygroup
# メモリ上限を 256MB に設定
echo "268435456" > /sys/fs/cgroup/mygroup/memory.max
# CPU 使用率を 50% に制限 (100ms 周期で 50ms まで)
echo "50000 100000" > /sys/fs/cgroup/mygroup/cpu.max
# プロセスをグループに追加 (PID を書き込む)
echo $$ > /sys/fs/cgroup/mygroup/cgroup.procs
# グループの削除 (プロセスがいない状態で)
rmdir /sys/fs/cgroup/mygroup
systemd 環境では systemd-cgls や systemctl set-property 経由で操作することも多い。
# cgroup ツリーを表示
systemd-cgls
# サービスのメモリ上限を設定
sudo systemctl set-property nginx.service MemoryMax=512M
##コンテナとの関係
Namespace がプロセスの「見え方」を分離するのに対し、cgroups は「リソース使用量」を制限する。Docker などのコンテナランタイムはこの両者を組み合わせている。
# Docker コンテナにメモリ・CPU 制限を付けて起動
docker run --memory="256m" --cpus="0.5" ubuntu:22.04
# コンテナの cgroup を確認 (v2 環境)
# /sys/fs/cgroup/system.slice/docker-<container_id>.scope/ 以下に作成される
cat /sys/fs/cgroup/system.slice/docker-$(docker ps -q | head -1).scope/memory.max
コンテナに --memory や --cpus オプションを渡すと、ランタイムが対応する cgroup ファイルに値を書き込む仕組みになっている。