如何使用 cgroups 将除白名单之外的所有进程限制为单个 CPU?

Wil*_*ard 27 resources cgroups cpu-usage

有一个来自 Red Hat 的 cgroups 指南,它可能有点帮助(但没​​有回答这个问题)。

我知道如何在启动该进程的命令期间通过以下方式将特定进程限制为特定 CPU:

首先,将以下*放入/etc/cgconfig.conf

mount {
  cpuset =  /cgroup/cpuset;
  cpu =     /cgroup/cpu;
  cpuacct = /cgroup/cpuacct;
  memory =  /cgroup/memory;
  devices = /cgroup/devices;
  freezer = /cgroup/freezer;
  net_cls = /cgroup/net_cls;
  blkio =   /cgroup/blkio;
}

group cpu0only {
  cpuset {
    cpuset.cpus = 0;
    cpuset.mems = 0;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后启动一个进程并使用以下命令将其专门分配给该 cgroup:

cgexec -g cpuset:cpu0only myprocessname
Run Code Online (Sandbox Code Playgroud)

我可以通过以下方式自动限制特定进程名称的所有实例(我认为这是正确的)/etc/cgrules.conf

# user:process  controller  destination
*:myprocessname cpuset      cpu0only
Run Code Online (Sandbox Code Playgroud)

我的问题是:我怎样才能做相反的事情?

换句话说,如何将除一组特定的白名单进程及其子进程之外的所有进程分配给受限制的 cgroup?


根据我研究过,但还没有测试,我相信,一个局部的解决办法是:

添加一个“不受限制的”cgroup:

group anycpu {
  cpuset {
    cpuset.cpus = 0-31;
    cpuset.mems = 0;  # Not sure about this param but it seems to be required
  }
}
Run Code Online (Sandbox Code Playgroud)

将我的流程明确分配给不受限制的组,并将其他所有内容分配给受限制的组:

# user:process  controller  destination
*:myprocessname cpuset      anycpu
*               cpuset      cpu0only
Run Code Online (Sandbox Code Playgroud)

但是,对此的警告似乎是(来自阅读文档,而不是来自测试,所以一粒盐) 的孩子myprocessname将被重新分配给受限制的cpu0onlycgroup。

一种可能的替代方法是创建一个用户来运行myprocessname并让该用户的所有进程不受限制,而其他一切都受到限制。但是,在我的实际用例中,该进程需要由 root 运行,并且还有其他进程也必须由 root 运行,应该受到限制。

我怎样才能用 cgroups 做到这一点?


如果 cgroups 无法做到这一点(我现在怀疑是这种情况),那么我对部分解决方案的想法是否正确,它们会像我想的那样工作吗?

*免责声明:这可能不是一个最小的代码示例;我不了解所有部分,所以我不知道哪些是不必要的。

Wil*_*ard 32

更新:请注意,以下答案适用于 RHEL 6。在 RHEL 7 中,大多数 cgroup 由 systemd 管理,不推荐使用 libcgroup。


自从发布这个问题以来,我研究了我上面链接的整个指南,以及大部分cgroups.txt文档和cpusets.txt。我现在对 cgroup 的了解比我预期的要多,所以我将在这里回答我自己的问题。

您可以采用多种方法。我们公司在 Red Hat 的联系人(技术架构师)建议不要全面限制所有流程,而不是采用更具声明性的方法——仅限制我们特别希望限制的流程。根据他关于该主题的陈述,这样做的原因是系统调用可能依赖于用户空间代码(例如 LVM 进程),如果受到限制,可能会降低系统速度——与预期效果相反。所以我最终限制了几个特定命名的进程,而把其他一切都搁置一旁。

另外,我想提一下我发布问题时遗漏的一些cgroup 基本数据


Cgroups依赖于libcgroup被安装。 但是,这是一组用于自动处理 cgroup 配置和进程分配给 cgroup 的工具,非常有用。

我发现 libcgroup 工具也可能具有误导性,因为 libcgroup 包建立在它自己的一组抽象和关于您使用 cgroup 的假设之上,这与 cgroup 的实际内核级实现略有不同。(我可以举一些例子,但这需要一些工作;如果你有兴趣,请发表评论。)

因此,使用工具libcgroup之前(如/etc/cgconfig.conf/etc/cgrules.confcgexeccgcreatecgclassify,等等)我高度建议得到非常熟悉的/cgroup虚拟文件系统本身,和手动创建的cgroup,cgroup中的层次结构(包括与多个子系统层级连接,其libcgroup悄悄和leakily摘要离开),通过运行将进程重新分配给不同的 cgroup echo $the_pid > /cgroup/some_cgroup_hierarchy/a_cgroup_within_that_hierarchy/tasks,以及在幕后执行的其他看似神奇的任务libcgroup


另一个基本的概念,我缺少的是,如果/cgroup虚拟文件系统在所有安装在系统上(或者更准确地说,如果有该cgroup子系统又名“控制器”被安装在所有的),那么每一个你的整个系统的过程一个群。 没有“某些进程在 cgroup 中而有些不在”这样的事情。

对于给定的层次结构,有所谓的cgroup,它拥有附属子系统的所有系统资源。例如具有cpuset和连接blkio子系统的cgroup层次结构,将有一个根本的cgroup其将拥有所有系统上的CPU和系统上的所有blkio,并能分享这些资源的一部分孩子的cgroup。你不能限制 root cgroup,因为它拥有你系统的所有资源,所以限制它甚至没有意义。


我还缺少一些关于 libcgroup 的其他简单数据:

如果使用/etc/cgconfig.conf,则应确保将chkconfig --list cgconfig显示cgconfig设置为在系统引导时运行。

如果更改/etc/cgconfig.conf,则需要运行service cgconfig restart以加载更改。(并且cgclear在愚弄测试时停止服务或运行的问题非常常见。对于调试,我建议,例如lsof /cgroup/cpuset,如果cpuset是您正在使用的 cgroup 层次结构的名称。)

如果要使用/etc/cgrules.conf,则需要确保“cgroup 规则引擎守护进程” ( cgrulesengd) 正在运行:service cgred startchkconfig cgred on。(并且您应该了解有关此服务的可能但不太可能的竞争条件,如页面底部的Red Hat 资源管理指南第 2.8.1 节中所述。)

如果您想手动绕过并使用虚拟文件系统(我建议首次使用)设置您的 cgroup,您可以这样做,然后cgconfig.conf通过使用cgsnapshot其各种选项创建一个文件来镜像您的设置。


最后,当我写下以下内容时,我遗漏了关键信息:

然而,对此的警告似乎是…… myprocessname 的子进程将被重新分配给受限的 cpu0only cgroup。

我是对的,但有一个我不知道的选项。

cgexec 是启动进程/运行命令并将其分配给 cgroup 的命令。

cgclassify 是将已经运行的进程分配给 cgroup 的命令。

这两者也将阻止cgred( cgrulesengd) 将指定的进程重新分配给基于 的不同 cgroup /etc/cgrules.conf

二者cgexeccgclassify支持--sticky标志,它附加地防止cgred从重新分配进程基于/etc/cgrules.conf


所以,我写的这个问题的答案(虽然不是我最终实现的设置,因为我们上面提到的红帽技术架构师的建议)是:

按照我的问题中的描述制作cpu0onlyanycpucgroup。(确保cgconfig设置为在启动时运行。)

* cpuset cpu0only按照我的问题中的描述制定规则。(并确保cgred设置为在启动时运行。)

开始我想任何进程无限制使用:cgexec -g cpuset:anycpu --sticky myprocessname

这些进程将不受限制,其所有子进程也将不受限制。 系统上的其他所有内容都将被限制为 CPU 0(一旦您重新启动,因为cgred不会将 cgrules 应用于已经运行的进程,除非它们更改了它们的 EUID)。这不是完全可取的,但这是我最初要求的,并且可以使用 cgroups 来完成。

  • 我看到了。但那已经是24小时前了。可能是它的原因很长。好的东西有时会像这样被忽视。不管怎样,很快得到“很多”选票的答案很少是好的答案——如果这么多人已经知道它是有用的,那么信息就不会那么有用。不过,这是好的方面之一。cgroup 真是太神秘了。 (2认同)