有一个来自 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)
我的问题是:我怎样才能做相反的事情?
换句话说,如何将除一组特定的白名单进程及其子进程之外的所有进程分配给受限制的 …
我想仅关闭一个进程的交换。对于其他进程,交换应该像往常一样工作。
我如何用 cgroups 实现这个?
我正在做一个实现分布式模拟的项目:在多个节点上执行任意代码,然后收集和聚合结果。
每个节点都是 Ubuntu Linux 虚拟机的一个实例,并运行一个主进程,负责将要执行的代码转发到多个工作进程(每个内核 1 个)。
这个问题是关于如何确保每个工作人员都在沙盒环境中运行,而不需要为每个工作人员使用虚拟机实例。对工人的确切要求是:
不应强加其他限制:worker 应该能够加载动态库(从只读文件夹)、生成新线程或进程、调用系统函数、ecc ecc 但限制必须由生成/加载的实体继承和应该以总和的方式应用(例如,我们不能让一个工作线程产生两个线程,每个线程使用 800MB,这样的工作线程的内存限制为 1GB)。
不言而喻,工人应该没有办法提高自己的权利。
我花了大量时间审查可用的替代方案(SELinux、AppArmor、cgroups、ulimit、Linux 命名空间、LXC、Docker 等)以获得满足我的要求的最简单的解决方案,但我在该领域的经验有限。
目前的理解:LXC 和 Docker 对我的用例来说有点偏重,并不完全安全1。AppArmor 由于更容易配置而优于 SELinux,将其用于 fs 和 net 限制;cgroups 优于 ulimit(在单个进程上运行),将其用于 mem 和 cpu 限制。
这是实现我的目标的最简单方法吗?我可以只使用 AppArmor 或 cgroups 吗?我的模型中是否存在明显的安全漏洞?指导方针应该是“允许工人自己倒下,但不能做其他事情”。
我想尝试 cgroup v2 但不确定它是否安装在我的 linux 机器上
>> uname -r
4.14.66-041466-generic
Run Code Online (Sandbox Code Playgroud)
由于 cgroup v2 在 4.12.0-rc5 中可用,我认为它应该在我使用的内核版本中可用。
https://www.infradead.org/~mchehab/kernel_docs/unsorted/cgroup-v2.html
但是,我的系统似乎没有 cgroup v2,因为其文档中提到的内存接口文件在我的系统上不可用。
https://www.kernel.org/doc/Documentation/cgroup-v2.txt
好像我还有 cgroup v1。
/sys/fs/cgroup/memory# ls
cgroup.clone_children memory.kmem.failcnt memory.kmem.tcp.usage_in_bytes memory.memsw.usage_in_bytes memory.swappiness
cgroup.event_control memory.kmem.limit_in_bytes memory.kmem.usage_in_bytes memory.move_charge_at_immigrate memory.usage_in_bytes
cgroup.procs memory.kmem.max_usage_in_bytes memory.limit_in_bytes memory.numa_stat memory.use_hierarchy
cgroup.sane_behavior memory.kmem.slabinfo memory.max_usage_in_bytes memory.oom_control notify_on_release
docker memory.kmem.tcp.failcnt memory.memsw.failcnt memory.pressure_level release_agent
memory.failcnt memory.kmem.tcp.limit_in_bytes memory.memsw.limit_in_bytes memory.soft_limit_in_bytes tasks
memory.force_empty memory.kmem.tcp.max_usage_in_bytes memory.memsw.max_usage_in_bytes memory.stat
Run Code Online (Sandbox Code Playgroud)
后续问题 感谢 Brian 的帮助。请让我知道我是否应该创建一个新问题,但我认为如果我在这里问我的问题可能对其他人有帮助。
1)我无法按照文档中的命令添加 cgroup 控制器
>> echo "+cpu +memory -io" > cgroup.subtree_control
Run Code Online (Sandbox Code Playgroud)
但是,我得到了“回声:写错误:无效的参数”。我是否缺少此步骤的先决条件?
2) 我运行了一个 docker 容器,但 docker …
我有一个 systemd 服务(一个 CI 运行程序),它往往会使系统陷入 CPU 密集型作业的泥潭。我刚刚发现平均负载超过 100,我想停止这种胡说八道。
系统上的其他任何东西都没有任何限制,所以交易是我希望其他一切都像现在一样继续运行,但是:
... 对系统上的其他所有东西都起到次要作用。事实上,即使系统上没有其他东西需要剩余 10% 的 CPU 周期,我也希望它们具有 90% 的绝对上限,但如果有任何其他要求 CPU 时间,我希望它们尽可能多他们要第一个。
配置它的最佳方法是什么?我在 EC2 上运行 Arch Linux 并且有可用的 cgroups(包括 cgmanager),但从未使用过它们。
我lxc在Arch Linux. 以下是基本系统信息:
[chb@conventiont ~]$ uname -a
Linux conventiont 3.17.4-Chb #1 SMP PREEMPT Fri Nov 28 12:39:54 UTC 2014 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
这是一个自定义/编译内核,具有user namespace enabled:
[chb@conventiont ~]$ lxc-checkconfig
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
Network namespace: enabled
Multiple /dev/pts instances: enabled
--- Control groups ---
Cgroup: enabled
Cgroup clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: …Run Code Online (Sandbox Code Playgroud) 在我们的集群中,我们限制了我们的进程资源,例如内存 ( memory.limit_in_bytes)。
我认为,这最终也是通过 Linux 内核中的 OOM 杀手来处理的(通过阅读源代码看起来是这样)。
有没有办法在我的进程被杀死之前获得信号?(就像SGE 的-notify选项一样,它将在进程终止qsubSIGUSR1之前发送。)
我在/dev/mem_notify 这里读到,但我没有 - 现在还有别的东西吗?我也读过这似乎有些相关。
我希望能够至少转储一个小的堆栈跟踪和其他一些有用的调试信息 - 但也许我什至可以通过释放一些内存来恢复。
我目前使用的一种解决方法是这个小脚本,它经常检查我是否接近 (95%) 限制,如果是,它会向进程发送一个SIGUSR1. 在 Bash 中,我在后台 ( cgroup-mem-limit-watcher.py &) 中启动此脚本,以便它监视同一 cgroup 中的其他 proc,并在父 Bash 进程终止时自动退出。
我正在尝试在两个不同的操作系统(Ubuntu 和 CentOS)上使用控制组。我想问的问题很少。
我正在尝试使用该cgcreate命令创建一个控制组,看起来它需要对机器进行 root 访问。到目前为止,我看到的所有示例都没有说明需要成为 root 用户才能创建或修改控制组。
真的有必要成为root用户吗?最终目标是编写一个 C++ 应用程序,该应用程序创建和管理控制组以使用 libcgroup API 控制资源。但是 C++ 应用程序不会由任何 root 用户运行。它可以是任何普通用户。
我使用 KVM 来管理我的虚拟机。我正在尝试限制为 VM 提供的资源。我可以使用 libvirt/cgroups 限制为 VM 分配的 CPU 和内存。现在我想通过应用一些权重来控制为每个 VM 分配的磁盘时间。我查看了 cgroups 中的 blkio 控件。由于 VM 只是一个 Linux 进程,我将能够使用 cgroups,但我不确定它是否也适用于异步 IO。如果没有,有人可以提出一个好的替代解决方案吗?
给定 podman 安装在 linux 系统和一个名为 baz.service 的 systemd 单元上:
# /etc/systemd/system/baz.service
[Service]
ExecStart=/usr/bin/podman run --rm --tty --name baz alpine sh -c 'while true; do date; sleep 1; done'
ExecStop=/usr/bin/podman stop baz
Run Code Online (Sandbox Code Playgroud)
然后 baz.service 启动:
# systemctl daemon-reload
# systemctl start baz.service
Run Code Online (Sandbox Code Playgroud)
然后当我检查单元的状态时,我在 /system.slice/baz.service cgroup中看不到shorsleep进程
# systemctl status baz
? baz.service
Loaded: loaded (/etc/systemd/system/baz.service; static; vendor preset: enabl
Active: active (running) since Sat 2019-08-10 05:50:18 UTC; 14s ago
Main PID: 16910 (podman)
Tasks: 9
Memory: 7.3M
CPU: …Run Code Online (Sandbox Code Playgroud)