Cgroups (Control Groups) 是 Linux 核心提供的進程資源隔離與限制機制,廣泛應用於容器技術、批次任務調度、多租戶資源配額等場景。本文從核心概念、子系統架構、安裝部署到實際資源限制操作,提供完整的落地指南。
| 術語 | 定義 | 類比 |
|---|---|---|
| Task | 單一進程 (PID) | 容器中的一個應用程式進程 |
| Control Group (cgroup) | 依據標準劃分的進程集合 | 資源配額桶 |
| Hierarchy | Cgroup 樹狀結構,父子繼承屬性 | 組織架構樹 |
| Subsystem | 資源控制器 (CPU、Memory、I/O 等) | 具體資源計量器 |
關鍵關係:掛載子系統 → 建立 cgroup 節點 → 寫入 PID 與限制參數
# 列出所有可用子系統及掛載點
lssubsys -al
# 或查看已掛載的 cgroup v1 掛載點 (傳統)
ls /sys/fs/cgroup/
# 輸出範例:
# blkio cpu cpuacct cpuset devices freezer hugetlb memory net_cls net_prio perf_event pids systemd
# cgroup v2 統一掛載點 (現代系統)
ls /sys/fs/cgroup/unified/ # 或 /sys/fs/cgroup/ (v2 模式下)
| 子系統 | 控制資源 | 關鍵參數檔案 |
|---|---|---|
cpu | CPU 時間片比例 | cpu.shares (相對權重)、cpu.cfs_quota_us/cpu.cfs_period_us (硬性配額) |
memory | 記憶體使用上限 | memory.limit_in_bytes、memory.memsw.limit_in_bytes (含 Swap) |
blkio | 塊設備 I/O 頻寬 | blkio.throttle.read_bps_device、blkio.weight |
cpuset | CPU 核心/記憶體節點綁定 | cpuset.cpus、cpuset.mems |
pids | 進程/線程數上限 | pids.max |
devices | 裝置節點存取控制 | devices.allow/devices.deny |
apt-get update && apt-get install -y cgroup-bin cgroup-tools
cgroup-bin 提供 cgcreate、cgdelete、cgset、cgget、cgexec 等管理命令;cgroup-tools 包含 systemd 整合與服務。
grep CGROUP /boot/config-$(uname -r)
# 應見 CONFIG_CGROUPS=y 及各子系統 =y
/etc/cgconfig.conf)mount {
cpu = /sys/fs/cgroup/cpu;
memory = /sys/fs/cgroup/memory;
blkio = /sys/fs/cgroup/blkio;
cpuset = /sys/fs/cgroup/cpuset;
}
# 群組範本
group limited_group {
cpu {
cpu.shares = 512; # 相對權重 (預設 1024)
cpu.cfs_quota_us = 50000; # 硬限制:每 100ms 可用 50ms (50% 單核)
cpu.cfs_period_us = 100000;
}
memory {
memory.limit_in_bytes = 1G;
memory.memsw.limit_in_bytes = 1G;
}
blkio {
blkio.throttle.read_bps_device = "8:0 10485760"; # 限制 sda 讀 10MB/s
}
}
systemctl restart cgconfig
systemctl restart cgred # 規則引擎,依 /etc/cgrules.conf 自動歸類進程
# 驗證
mount -t cgroup
ls /sys/fs/cgroup/memory/
# 應見 limited_group 目錄
# 1. 在 memory 子系統建立 cgroup
mkdir /sys/fs/cgroup/memory/test_group
# 2. 設定記憶體硬限制 500MB
echo 524288000 > /sys/fs/cgroup/memory/test_group/memory.limit_in_bytes
# 3. 將目標 PID 加入 cgroup
echo 12345 > /sys/fs/cgroup/memory/test_group/cgroup.procs
# 4. 驗證限制生效
cat /sys/fs/cgroup/memory/test_group/memory.usage_in_bytes
# 進程嘗試分配超過 500MB 將觸發 OOM Killer
# 建立群組
cgcreate -g memory,cpu:myapp
# 設定參數
cgset -r memory.limit_in_bytes=2G myapp
cgset -r cpu.cfs_quota_us=200000 myapp # 2 核配額 (200ms/100ms)
# 在 cgroup 內啟動程式
cgexec -g memory,cpu:myapp /usr/bin/java -jar app.jar
# 既有進程加入
cgclassify -g memory,cpu:myapp 12345
# /etc/systemd/system/myapp.service
[Service]
ExecStart=/usr/bin/myapp
MemoryLimit=2G
CPUQuota=200%
# systemd 自動建立對應 cgroup v2 節點
# 管理命令:systemctl status myapp, systemd-cgtop
# 即時監控所有 cgroup 資源使用
cgtop
# 查看特定群組統計
cgget -r memory.usage_in_bytes -r cpuacct.usage myapp
# 列出群組內進程
cat /sys/fs/cgroup/memory/myapp/cgroup.procs
ps -fp $(cat /sys/fs/cgroup/memory/myapp/cgroup.procs)
| 特性 | v1 (傳統) | v2 (統一) |
|---|---|---|
| 掛載結構 | 每子系統獨立掛載 | 單一統一掛載點 (/sys/fs/cgroup) |
| 控制器啟用 | 掛載時指定 | cgroup.subtree_control 動態啟用 |
| 進程隸屬 | 可同時屬多樹 | 單一層級,進程只屬一個 leaf cgroup |
| 介面工具 | cgroup-bin, libcgroup | systemd, cgroup2fs, cgmanager |
現代發行版 (RHEL 8+, Ubuntu 20.04+, Debian 10+) 預設啟用 v2,建議新部署直接採用 systemd + v2 介面。
memory.memsw.limit_in_bytes:防止 Swap 爆滿導致系統整體卡頓cpu.cfs_quota_us:cpu.shares 僅在 CPU 爭用時生效,無法硬性保護memory.failcnt:計數器增長表示觸發限制,需擴容或優化oom_score_adj:調整核心 OOM Killer 選擇傾向,保護關鍵進程透過 Cgroups 精細化的資源劃分與限制,可實現進程級的服務質量保障 (QoS)、故障隔離與多租戶成本控制,是現代 Linux 基礎設施不可或缺的核心能力。