Linux Cgroups
コンテナのリソース制限の基盤となるCgroups(Control Groups)について学びます。
目次
Cgroupsとは
Cgroupsの概念
┌─────────────────────────────────────────────────────────────┐
│ Cgroups の役割 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Cgroups = プロセスグループに対するリソース制限・計測 │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Linux Kernel │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────┐ │ │
│ │ │ Cgroup コントローラ │ │ │
│ │ │ CPU | Memory | Block I/O | Network | ... │ │ │
│ │ └───────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ Cgroup A │ │ Cgroup B │ │ Cgroup C │ │
│ │ │ │ │ │ │ │
│ │ CPU: 50% │ │ CPU: 30% │ │ CPU: 20% │ │
│ │ Mem: 1GB │ │ Mem: 2GB │ │ Mem: 512MB│ │
│ │ │ │ │ │ │ │
│ │ Process1 │ │ Process3 │ │ Process5 │ │
│ │ Process2 │ │ Process4 │ │ │ │
│ └───────────┘ └───────────┘ └───────────┘ │
│ │
│ Namespace: リソースの「分離」(見え方) │
│ Cgroups: リソースの「制限」(使用量) │
│ │
└─────────────────────────────────────────────────────────────┘
Cgroupsでできること
| 機能 | 説明 |
|---|---|
| リソース制限 | CPU、メモリ、I/Oの使用量を制限 |
| 優先順位付け | CPUやI/Oの優先度を設定 |
| アカウンティング | リソース使用量の計測 |
| 制御 | プロセスグループの一括操作(凍結など) |
Cgroupsのバージョン
cgroup v1 vs v2
┌─────────────────────────────────────────────────────────────┐
│ cgroup v1 vs v2 │
├─────────────────────────────────────────────────────────────┤
│ │
│ cgroup v1 (legacy): │
│ /sys/fs/cgroup/ │
│ ├── cpu/ ← 各コントローラが独立 │
│ │ └── docker/ │
│ ├── memory/ │
│ │ └── docker/ │
│ ├── blkio/ │
│ │ └── docker/ │
│ └── ... │
│ │
│ cgroup v2 (unified): │
│ /sys/fs/cgroup/ │
│ └── system.slice/ ← 統一された階層構造 │
│ └── docker.service/ │
│ ├── cpu.max │
│ ├── memory.max │
│ └── io.max │
│ │
│ v2の利点: │
│ ・単一の階層構造(管理が簡単) │
│ ・プロセスは1つのcgroupにのみ所属 │
│ ・より精密なリソース制御 │
│ │
└─────────────────────────────────────────────────────────────┘
バージョン確認
# マウント状況確認
mount | grep cgroup
# v2の場合
# cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime)
# v1の場合(複数のcgroupマウント)
# cgroup on /sys/fs/cgroup/cpu type cgroup (rw,nosuid,nodev,noexec,relatime,cpu)
# cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
# 統一cgroup v2を使用しているか
cat /sys/fs/cgroup/cgroup.controllers
# cpu memory io ...
リソースコントローラ
主なコントローラ
| コントローラ | 説明 | 制御対象 |
|---|---|---|
| cpu | CPU時間の割り当て | CPU使用率 |
| cpuset | CPUとメモリノードの割り当て | CPUピニング |
| memory | メモリ使用量制限 | RAM, swap |
| io (blkio) | ブロックI/O制限 | ディスクI/O |
| pids | プロセス数制限 | fork bomb防止 |
| devices | デバイスアクセス制御 | /dev/* |
| freezer | プロセスの一時停止 | 一括停止 |
cgroup v2 でのファイル
# cgroup v2 のディレクトリ構造
ls /sys/fs/cgroup/
# 主なファイル
# cgroup.controllers - 利用可能なコントローラ
# cgroup.subtree_control - 子cgroupで有効なコントローラ
# cgroup.procs - このcgroupのプロセス一覧
# cpu.max - CPU制限
# memory.max - メモリ制限
# io.max - I/O制限
CPU制限
cgroup v2 でのCPU制限
# cgroupディレクトリ作成
sudo mkdir /sys/fs/cgroup/mygroup
# CPUコントローラを有効化(親で設定)
echo "+cpu" | sudo tee /sys/fs/cgroup/cgroup.subtree_control
# CPU制限設定(50%に制限)
# 形式: $MAX $PERIOD (マイ クロ秒)
# 100000/100000 = 100%
# 50000/100000 = 50%
echo "50000 100000" | sudo tee /sys/fs/cgroup/mygroup/cpu.max
# プロセスをcgroupに追加
echo $$ | sudo tee /sys/fs/cgroup/mygroup/cgroup.procs
# CPU使用率を確認しながらテスト
while true; do :; done &
top -p $!