首页 > 运维 > linux运维 > 正文

如何在Linux中限制进程资源 Linux cgroups配置方法

P粉602998670
发布: 2025-09-08 11:07:01
原创
704人浏览过
答案:Linux通过cgroups限制进程资源使用,可防止资源耗尽、保障服务稳定性。具体通过挂载cgroup文件系统,创建控制组并配置CPU、内存等限制(如cpu.cfs_quota_us、memory.limit_in_bytes或cgroup v2的cpu.max、memory.max),再将进程PID写入tasks或cgroup.procs文件实现。cgroups v1为多层级结构,v2为统一层级,更推荐新系统使用。结合systemd可声明式管理资源限制,通过Service单元设置CPUQuota、MemoryLimit等参数,实现持久化、自动化配置,提升系统可靠性与可维护性。

如何在linux中限制进程资源 linux cgroups配置方法

在Linux系统中,要限制进程的资源使用,核心机制就是cgroups (control groups)。它允许我们将进程组织成不同的组,然后对这些组进行资源分配和限制,比如CPU时间、内存、磁盘I/O和网络带宽等。这就像给不同的部门划定预算,确保每个部门都在自己的“配额”内运行,避免某个部门无限制地占用公司资源。

解决方案

要手动配置cgroups来限制进程资源,通常涉及以下几个步骤。这有点像在文件系统里直接操作,虽然有点底层,但能让你明白其原理。

  1. 确认cgroup文件系统已挂载: 大多数现代Linux发行版都会默认挂载cgroup文件系统。你可以通过

    mount -t cgroup
    登录后复制
    mount -t cgroup2
    登录后复制
    来查看。例如,你会看到类似
    /sys/fs/cgroup/cpu
    登录后复制
    /sys/fs/cgroup/memory
    登录后复制
    这样的路径,这些就是不同资源控制器的挂载点。如果你的系统是较新的,可能会看到统一的
    cgroup2
    登录后复制
    挂载点
    /sys/fs/cgroup
    登录后复制

  2. 创建控制组: 在相应的cgroup子系统目录下创建一个目录,这个目录就代表你的控制组。 比如,要在CPU子系统下创建一个名为

    my_limit_group
    登录后复制
    的组:
    sudo mkdir /sys/fs/cgroup/cpu/my_limit_group
    登录后复制
    同样,对于内存:
    sudo mkdir /sys/fs/cgroup/memory/my_limit_group
    登录后复制

  3. 配置资源限制: 进入你创建的控制组目录,你会看到一些文件,通过修改这些文件来设定限制。

    • CPU限制 (cgroup v1 示例)

      cpu.cfs_period_us
      登录后复制
      cpu.cfs_quota_us
      登录后复制
      配合使用,定义一个CPU周期内,该组最多能使用多少CPU时间。 假设周期是100ms (100000微秒),你想限制一个进程组只能使用一个CPU核心的50%:
      echo 100000 > /sys/fs/cgroup/cpu/my_limit_group/cpu.cfs_period_us
      登录后复制
      echo 50000 > /sys/fs/cgroup/cpu/my_limit_group/cpu.cfs_quota_us
      登录后复制
      这意味着在每100ms内,这个组的进程最多只能运行50ms。

      如果你只是想设置CPU份额(相对权重),可以使用

      cpu.shares
      登录后复制
      echo 512 > /sys/fs/cgroup/cpu/my_limit_group/cpu.shares
      登录后复制
      默认值是1024。如果你有两个组,一个512,一个1024,那么在CPU资源紧张时,后者会获得前者的两倍CPU时间。

    • 内存限制 (cgroup v1 示例)

      memory.limit_in_bytes
      登录后复制
      用于设置内存使用上限。
      echo 536870912 > /sys/fs/cgroup/memory/my_limit_group/memory.limit_in_bytes
      登录后复制
      这会将内存限制设置为512MB (512 1024 1024 字节)。
      memory.swappiness
      登录后复制
      也可以调整,控制该组进程的内存回收策略。

    • cgroup v2 示例 (CPU和内存): cgroup v2的配置方式略有不同,它通常在一个统一的层级下。

      sudo mkdir /sys/fs/cgroup/my_limit_group
      登录后复制
      (创建组)
      echo "+cpu +memory" > /sys/fs/cgroup/my_limit_group/cgroup.subtree_control
      登录后复制
      (启用控制器)
      echo 50000 > /sys/fs/cgroup/my_limit_group/cpu.max
      登录后复制
      (CPU限制,格式为
      quota period
      登录后复制
      ,这里是50000微秒/100000微秒)
      echo 536870912 > /sys/fs/cgroup/my_limit_group/memory.max
      登录后复制
      (内存限制)

  4. 将进程添加到控制组: 将目标进程的PID写入到控制组目录下的

    tasks
    登录后复制
    (cgroup v1) 或
    cgroup.procs
    登录后复制
    (cgroup v2) 文件中。 假设你的进程PID是
    12345
    登录后复制
    echo 12345 > /sys/fs/cgroup/cpu/my_limit_group/tasks
    登录后复制
    echo 12345 > /sys/fs/cgroup/memory/my_limit_group/tasks
    登录后复制
    或者对于cgroup v2:
    echo 12345 > /sys/fs/cgroup/my_limit_group/cgroup.procs
    登录后复制

    你也可以在新启动一个进程时直接将其放入某个cgroup,比如使用

    cgexec
    登录后复制
    命令(需要安装
    cgroup-tools
    登录后复制
    包)。

为什么需要限制Linux进程的CPU和内存资源?

这问题,说实话,我个人在生产环境里,就遇到过因为某个日志服务突然飙升内存,直接把整个机器拖垮的惨痛教训。当时整个系统都卡死了,SSH都连不上,最后只能硬重启。所以,限制资源真的不是小题大做,它直接关系到系统的稳定性和可用性。

从更深层次看,限制资源有几个非常实际的理由:

  • 防止“流氓”进程: 任何一个有bug的程序,或者配置不当的服务,都可能在某个时刻失控,无限占用CPU或内存。如果不加限制,它会迅速耗尽系统资源,导致其他正常服务无法运行,甚至整个系统崩溃。这就像一个水龙头突然爆裂,如果没有阀门,整个屋子都会被淹。
  • 保证核心服务SLA: 在一台服务器上跑多个服务是常态。有些服务是核心业务,需要稳定的性能;有些可能只是辅助性的。通过cgroups,你可以给核心服务更高的资源优先级或独占部分资源,即使其他服务出现波动,也不会影响到关键业务的响应速度和稳定性。
  • 资源公平性与隔离: 特别是在多租户或多用户环境中,限制资源能确保每个用户或每个应用都只能使用分配给它的那部分资源,避免“邻居效应”。这在容器技术(如Docker)中体现得淋漓尽致,每个容器其实就是一个被cgroup隔离的进程组。
  • 成本控制与容量规划: 在云环境中,精确的资源管理能帮助你更好地进行容量规划,避免不必要的资源浪费,从而降低运营成本。你能够更准确地知道一个服务需要多少资源,而不是简单地给它一个超大的虚拟机

理解cgroups v1与v2的主要区别与选择

cgroups这东西,一开始接触,v1的独立层级确实让人有点懵,感觉像是一堆独立的开关。每个控制器(CPU、内存、IO等)都有自己独立的层级结构,你可以把一个进程放在不同的控制器层级下的不同组里。这导致一个进程可能在CPU控制器下属于A组,在内存控制器下属于B组,管理起来有点混乱。

但cgroups v2出来后,那种统一管理的思路就清晰多了,虽然上手可能需要一点点适应,但长远看绝对是趋势。

cgroups v1 (传统版本):

  • 多层级结构: 每个资源控制器(如cpu、memory、blkio)都有自己独立的cgroup层级。
  • 进程归属: 一个进程可以在不同的控制器层级中属于不同的cgroup。
  • 控制器互不干涉: 不同的控制器之间关联性不强,配置起来相对分散。
  • 兼容性: 历史悠久,很多老系统和一些工具仍在使用。

cgroups v2 (统一版本):

  • 统一层级结构: 只有一个统一的cgroup层级树。所有的控制器都附加到这个单一的层级上。
  • 进程归属: 一个进程只能属于一个cgroup,且其所有资源限制都由该cgroup及其父cgroup共同决定。
  • 控制器协调: 设计上考虑了控制器之间的协调性,例如,一个cgroup如果启用了某个子控制器,那么其子cgroup必须也启用该控制器。
  • 更清晰的模型: 简化了管理,尤其是在容器和虚拟机场景下,更符合资源隔离的直觉。例如,
    cpu.max
    登录后复制
    替代了
    cpu.cfs_quota_us
    登录后复制
    cpu.cfs_period_us
    登录后复制
    的组合,更加直观。
  • 资源委托: 允许将cgroup的子树委托给非root用户或容器运行时管理,增强了安全性。

如何选择?

冬瓜配音
冬瓜配音

AI在线配音生成器

冬瓜配音 66
查看详情 冬瓜配音
  • 新部署和容器化环境: 强烈推荐使用cgroups v2。现代Linux发行版(如CentOS 8+, Ubuntu 20.04+, Debian 10+)和新的容器运行时(如
    containerd
    登录后复制
    crun
    登录后复制
    )都倾向于或已经默认使用v2。它的设计更合理,功能更强大。
  • 旧系统和特定工具依赖: 如果你的系统较老,或者你使用的某些工具(比如某些监控代理)只支持v1,那么你可能不得不继续使用v1。但即使在v1环境下,了解v2的理念也很有帮助。
  • 混合模式: 某些系统为了兼容性,可能同时挂载了v1和v2的cgroup文件系统。在这种情况下,你需要明确你正在操作的是哪个版本。

如何使用systemd管理cgroups资源限制?

说实话,手动在

/sys/fs/cgroup
登录后复制
里敲命令,那真是有点原始,而且一旦重启就没了。systemd的出现,简直是把cgroups的配置从刀耕火种时代带入了工业革命。我个人现在基本都是通过systemd来搞定这些事,省心太多了。Systemd不仅管理服务,它也深度集成了cgroups,可以让你以声明式的方式为服务设置资源限制。

Systemd通过其Service、Scope、Slice等单元类型,将进程自动归类到cgroups中,并允许你直接在单元文件中定义资源限制。

基本原理: 当你启动一个systemd服务(

.service
登录后复制
单元)时,systemd会自动为这个服务创建一个cgroup,并将服务的所有进程都放入这个cgroup中。然后,你可以通过在
.service
登录后复制
文件中添加特定的配置项来设置资源限制。

配置示例(以一个名为

my-app.service
登录后复制
的服务为例):

  1. 创建或编辑服务文件:

    sudo systemctl edit --full my-app.service
    登录后复制
    (如果文件不存在则创建,如果存在则编辑)

  2. 添加或修改以下参数:

    [Unit]
    Description=My Custom Application
    After=network.target
    
    [Service]
    ExecStart=/usr/local/bin/my_app_executable
    Restart=on-failure
    
    # 启用CPU和内存的会计功能(查看资源使用情况)
    CPUAccounting=true
    MemoryAccounting=true
    
    # CPU限制
    # CPUQuota: cgroup v2 风格,限制CPU使用百分比 (20% CPU)
    CPUQuota=20%
    # CPUShares: cgroup v1 风格,相对CPU份额 (默认1024)
    # CPUShares=512
    
    # 内存限制
    # MemoryLimit: 内存使用上限 (512MB)
    MemoryLimit=512M
    # MemorySwapMax: 交换区使用上限 (0表示禁用交换区,防止进程使用过多交换区)
    MemorySwapMax=0
    
    # I/O限制 (需要blkio控制器支持)
    # IOWeight: I/O相对权重 (默认1000)
    # IOWeight=500
    # IOReadBandwidthMax=/dev/sda 10M # 限制从/dev/sda读取最大10MB/s
    # IOWriteBandwidthMax=/dev/sda 5M # 限制写入/dev/sda最大5MB/s
    
    [Install]
    WantedBy=multi-user.target
    登录后复制
  3. 重新加载systemd配置并启动服务:

    sudo systemctl daemon-reload
    登录后复制
    sudo systemctl start my-app.service
    登录后复制

Systemd管理cgroups的优势:

  • 声明式配置: 你在服务文件中声明你想要的资源限制,systemd负责底层cgroup的创建和管理。这比手动操作
    /sys/fs/cgroup
    登录后复制
    目录下的文件要方便和安全得多。
  • 持久性: 配置写入服务文件后,即使系统重启,资源限制也会自动生效。
  • 集成度高: 与systemd的服务生命周期管理无缝集成,当服务启动、停止、重启时,cgroup也会被正确地创建、清理或重用。
  • 易于监控: 通过
    systemd-cgtop
    登录后复制
    命令可以方便地查看当前cgroup的资源使用情况,或者通过
    systemctl status my-app.service
    登录后复制
    查看服务的资源会计信息。
  • 灵活性: 除了Service单元,Systemd还提供了
    Slice
    登录后复制
    Scope
    登录后复制
    单元来更灵活地组织和管理cgroups,例如,你可以创建一个
    Slice
    登录后复制
    来管理一组相关的服务,并为整个
    Slice
    登录后复制
    设置资源限制。

利用systemd来管理cgroups,是现代Linux系统上最推荐的做法,它不仅简化了操作,还提高了系统的可维护性和可靠性。

以上就是如何在Linux中限制进程资源 Linux cgroups配置方法的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号