0

0

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

P粉602998670

P粉602998670

发布时间:2025-09-08 11:07:01

|

739人浏览过

|

来源于php中文网

原创

答案: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用户或容器运行时管理,增强了安全性。

如何选择?

盛世企业网站管理系统1.1.2
盛世企业网站管理系统1.1.2

免费 盛世企业网站管理系统(SnSee)系统完全免费使用,无任何功能模块使用限制,在使用过程中如遇到相关问题可以去官方论坛参与讨论。开源 系统Web代码完全开源,在您使用过程中可以根据自已实际情况加以调整或修改,完全可以满足您的需求。强大且灵活 独创的多语言功能,可以直接在后台自由设定语言版本,其语言版本不限数量,可根据自已需要进行任意设置;系统各模块可在后台自由设置及开启;强大且适用的后台管理支

下载
  • 新部署和容器化环境: 强烈推荐使用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系统上最推荐的做法,它不仅简化了操作,还提高了系统的可维护性和可靠性。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

392

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

572

2023.08.10

k8s和docker区别
k8s和docker区别

k8s和docker区别有抽象层次不同、管理范围不同、功能不同、应用程序生命周期管理不同、缩放能力不同、高可用性等等区别。本专题为大家提供k8s和docker区别相关的各种文章、以及下载和课程。

249

2023.07.24

docker进入容器的方法有哪些
docker进入容器的方法有哪些

docker进入容器的方法:1. Docker exec;2. Docker attach;3. Docker run --interactive --tty;4. Docker ps -a;5. 使用 Docker Compose。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

494

2024.04.08

docker容器无法访问外部网络怎么办
docker容器无法访问外部网络怎么办

docker 容器无法访问外部网络的原因和解决方法:配置 nat 端口映射以将容器端口映射到主机端口。根据主机兼容性选择正确的网络驱动(如 host 或 overlay)。允许容器端口通过主机的防火墙。配置容器的正确 dns 服务器。选择正确的容器网络模式。排除主机网络问题,如防火墙或连接问题。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

399

2024.04.08

docker镜像有什么用
docker镜像有什么用

docker 镜像是预构建的软件组件,用途广泛,包括:应用程序部署:简化部署,提高移植性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

437

2024.04.08

磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

1349

2023.06.21

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

703

2023.06.29

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

72

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.4万人学习

Git 教程
Git 教程

共21课时 | 2.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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