4.4.5 控制组与systemd资源管理
控制组与systemd资源管理#
cgroups(控制组)用于按资源维度分组与限制进程;systemd 作为服务管理器,默认将每个服务挂载到 cgroup 层级,实现资源治理与审计。本节围绕 cgroup v2 与 systemd 结合的配置、验证、排错与练习展开。
1. 原理草图:systemd 与 cgroup 层级关系#
2. 环境检查与基础命令#
- 检查是否启用 cgroup v2
mount | grep cgroup
cat /sys/fs/cgroup/cgroup.controllers
预期:存在 cgroup2 挂载与控制器列表。
- 查看层级与资源统计
systemd-cgls
systemd-cgtop
预期:看到 system.slice/nginx.service 等节点及 CPU/内存占用。
3. 关键资源指标与命令解释#
- CPU:
CPUQuota(硬限制百分比)、CPUWeight(相对权重) - 内存:
MemoryHigh(软限制)、MemoryMax(硬限制) - IO:
IOReadBandwidthMax/IOWriteBandwidthMax - 进程数:
TasksMax - OOM:
OOMPolicy/OOMScoreAdjust
查看当前服务的限制:
systemctl show nginx.service \
-p CPUQuota -p CPUWeight -p MemoryHigh -p MemoryMax -p TasksMax
4. 资源限制配置:临时与永久#
临时生效(动态调参):
# 将 nginx 限制为 50% CPU 与 1G 内存
systemctl set-property nginx.service CPUQuota=50% MemoryMax=1G
# 验证
systemctl show nginx.service -p CPUQuota -p MemoryMax
预期:显示 CPUQuota=50%、MemoryMax=1073741824。
永久生效(drop-in):
sudo mkdir -p /etc/systemd/system/nginx.service.d
sudo tee /etc/systemd/system/nginx.service.d/limit.conf >/dev/null <<'EOF'
[Service]
CPUQuota=40%
MemoryHigh=800M
MemoryMax=1G
TasksMax=1024
EOF
sudo systemctl daemon-reload
sudo systemctl restart nginx.service
5. 临时任务:systemd-run + cgroup 观察#
# 运行压测任务并限制资源
systemd-run --scope -p CPUQuota=30% -p MemoryMax=500M \
stress --cpu 2 --vm 1 --vm-bytes 300M --timeout 60
# 观察限制效果
systemd-cgtop
命令解释:
- --scope:将前台进程纳入 systemd 管理
- -p:设置资源属性
- stress:模拟 CPU/内存消耗
6. cgroup v2 关键文件与验证#
# 进入服务 cgroup 路径
cd /sys/fs/cgroup/system.slice/nginx.service
# 查看限制与当前使用
cat cpu.max
cat memory.max
cat memory.current
预期:
- cpu.max 类似 200000 100000(2核限制)
- memory.max 对应设置的字节值
7. 常见问题与排错步骤#
问题1:限制未生效
systemctl status nginx.service
systemctl show nginx.service -p ControlGroup
排查要点:
- 确认服务由 systemd 启动
- 检查 drop-in 路径与 daemon-reload
问题2:内存 OOM 频繁
journalctl -u systemd-oomd --since "1 hour ago"
systemctl show nginx.service -p MemoryHigh -p MemoryMax -p OOMPolicy
建议:先提高 MemoryHigh,观察 oomd 行为。
问题3:CPU 限制无感
ps -eo pid,comm,ni,cls,rtprio | grep nginx
排查要点:
- 多进程服务会分摊 CPUQuota
- CPUQuota 是硬限制,CPUWeight 是相对权重
8. 综合示例:为批处理任务限速与隔离#
# 创建一个批处理服务单元
sudo tee /etc/systemd/system/batch-job.service >/dev/null <<'EOF'
[Unit]
Description=Batch Job with Resource Limits
[Service]
Type=simple
ExecStart=/usr/bin/bash -c 'for i in {1..5}; do dd if=/dev/zero of=/tmp/batch.$$ bs=1M count=200; sleep 2; done'
CPUQuota=20%
MemoryMax=300M
IOWriteBandwidthMax=/dev/sda 10M
TasksMax=200
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl start batch-job.service
systemctl status batch-job.service
预期:批处理任务占用受控,不挤占核心服务资源。
9. 练习题#
- 将
mysql.service限制为MemoryMax=2G,并验证 cgroup 文件memory.max的值。 - 使用
systemd-run运行stress --cpu 4,设置CPUQuota=25%,观察systemd-cgtop中的 CPU 变化。 - 为
nginx.service设置IOReadBandwidthMax与IOWriteBandwidthMax,并用dd进行读写验证。
10. 最佳实践#
- 核心服务优先使用
CPUWeight+ 高MemoryHigh;非核心服务使用CPUQuota+MemoryMax。 - 结合
systemd-cgtop与 Prometheus 监控持续优化配额。 - 与
nice/renice配合,实现软硬优先级双层控制。