如何以非 root 用户身份创建和使用cgroups?
例如,我可以完全作为非 root 用户:
?
我第一次在这里问,但我没有得到完整的答案。我也问过 stackoverflow,但这个问题被关闭为题外话。
有什么方法可以得到cgroup
进程吗?
我所知道的唯一一个包 ( cgroup-bin
),只提供了一些对 cgroup 的操作,并允许更改进程的 cgroup/进程列表,但没有能力了解有关特定进程的 cgroup 的信息。
我正在尝试在容器内使用循环设备来挂载一些图像文件:
> sudo losetup /dev/loop0 test.img
losetup: /dev/loop0: failed to set up loop device: No such file or directory
Run Code Online (Sandbox Code Playgroud)
/dev/loop0
确实不存在,并且
> sudo mknod /dev/loop0 b 7 0
mknod: ‘/dev/loop0’: Operation not permitted
Run Code Online (Sandbox Code Playgroud)
我怎样才能使这项工作?容器是否需要一些它可能没有的 cgroup 权限?
我正在尝试在一组独立的 CPU 上运行多线程基准测试。长话短说,我最初尝试使用isolcpus
和taskset
,但遇到了问题。现在我在玩 cgroups/csets。
我认为“简单”cset shield
用例应该可以很好地工作。我有 4 个内核,所以我想使用内核 1-3 进行基准测试(我还将这些内核配置为处于自适应滴答模式),然后内核 0 可用于其他所有内容。
按照这里的教程,它应该很简单:
$ sudo cset shield -c 1-3
cset: --> shielding modified with:
cset: "system" cpuset of CPUSPEC(0) with 105 tasks running
cset: "user" cpuset of CPUSPEC(1-3) with 0 tasks running
Run Code Online (Sandbox Code Playgroud)
所以现在我们有一个隔离的“盾牌”(用户 cset),核心 0 用于其他一切(系统 cset)。
好的,目前看起来不错。现在让我们来看看htop
。这些进程应该都已迁移到 CPU 0 上:
嗯?一些进程显示为在屏蔽内核上运行。为了排除 htop 存在错误的情况,我还尝试使用taskset
检查显示为在屏蔽中的进程的亲和掩码。
也许那些任务是不可移动的?让我们选择一个显示为在 CPU3 上运行的任意进程(应该在屏蔽中)htop
,看看它是否出现在系统 cgroup 中,根据cset
:
$ cset shield …
Run Code Online (Sandbox Code Playgroud) EDIT2:这个问题在 3.8.0-25-generic #37-Ubuntu SMP 下似乎也存在
编辑:我修改了原标题“为什么用 dd 写入文件会触发 Linux 内存不足管理器”中的问题?为了更好地反映我担心下面描述的一般问题:
我遇到了一个麻烦的场景,当我编写一个大小超过内存限制(设置为 300MB)的文件时,OOM 杀手很难杀死我的 LXC 容器中的进程。当我在实际只有 512 MB RAM 的 Xen 虚拟机(EC2 t1.micro)上运行应用程序时,不会出现该问题,因此文件缓冲似乎存在一些与容器内存限制相关的问题。
作为一个简单的例子,我可以演示 dd 写入的大文件如何导致问题。同样,这个问题困扰着所有应用程序。我正在寻求解决应用程序缓存变得太大的一般问题;我了解如何使“dd”工作。
设想:
我有一个 LXC 容器,其中 memory.limit_in_bytes 设置为 300 MB。
我尝试添加一个 ~500 MB 的文件,如下所示:
dd if=/dev/zero of=test2 bs=100k count=5010
Run Code Online (Sandbox Code Playgroud)
大约 20% 的时间,Linux OOM 管理器被此命令触发并杀死一个进程。不用说,这是非常意外的行为;dd 旨在模拟由在容器内运行的程序写入的实际“有用”文件。
详细信息:虽然文件缓存变大 (260 MB),但 rss 和文件映射似乎仍然很低。以下是 memory.stat 在写入过程中可能是什么样子的示例:
cache 278667264
rss 20971520
mapped_file 24576
pgpgin 138147
pgpgout 64993
swap 0
pgfault 55054
pgmajfault 2
inactive_anon 10637312
active_anon 10342400
inactive_file 278339584
active_file 319488
unevictable …
Run Code Online (Sandbox Code Playgroud) 我将在下面附上最小化的测试用例。但是,它是一个简单的 Dockerfile,具有以下几行:
VOLUME ["/sys/fs/cgroup"]
CMD ["/lib/systemd/systemd"]
Run Code Online (Sandbox Code Playgroud)
它是基于 Debian:buster-slim 的映像,并在容器内运行 systemd。实际上,我曾经像这样运行容器:
$ docker run --name any --tmpfs /run \
--tmpfs /run/lock --tmpfs /tmp \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro -it image_name
Run Code Online (Sandbox Code Playgroud)
在我升级一堆主机 Linux 软件包之前,它曾经运行良好。主机内核/systemd 现在似乎默认 cgroup v2。之前是cgroup。它停止工作。但是,如果我提供内核选项以便主机使用 cgroup,则它会再次运行。
在不提供内核选项的情况下,修复是添加--cgroupns=host
到docker run
除了/sys/fs/cgroup
以读写方式安装(:rw
代替:ro
)之外。
我想避免强迫用户提供内核选项。尽管我远非专家,但强制为 docker 容器使用主机命名空间对我来说并不合适。
我试图理解为什么会发生这种情况,并弄清楚应该做什么。我的目标是在 docker 中运行 systemd,其中主机遵循 cgroup v2。
这是我看到的错误:
$ docker run --name any --tmpfs /run --tmpfs /run/lock --tmpfs /tmp \
-v /sys/fs/cgroup:/sys/fs/cgroup:rw -it image_name
systemd 241 running in system mode. (+PAM +AUDIT …
Run Code Online (Sandbox Code Playgroud) 我有 Debian 7 盒子和小问题:
mkdir /cgroups/test
echo 500 > /cgroups/test/cpu.shares
echo 3167 > /cgroups/test/tasks
bash: echo: write error: No space left on device
Run Code Online (Sandbox Code Playgroud)
我该如何解决?
在 fstab 中:
cgroup /cgroups cgroup defaults 0 0
Run Code Online (Sandbox Code Playgroud)
我已经安装:cgroup-bin、libcgroup1、libpam-cgroup
我有一个容器泄漏内存。或者至少,报告的内存消耗快速增加。如果我跑到顶部,我会得到这个:
top - 16:56:51 up 6 days, 17:25, 0 users, load average: 0.16, 0.27, 0.31
Tasks: 4 total, 1 running, 3 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.3 us, 0.7 sy, 0.0 ni, 98.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 7676380 total, 4089380 used, 3587000 free, 675164 buffers
KiB Swap: 0 total, 0 used, 0 free. 2586496 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 …
Run Code Online (Sandbox Code Playgroud) 问题涉及 Linux cgroups cpu 核算。
我在容器级别注意到了这一点,但它仍然持续到顶层。例如:
# cat /sys/fs/cgroup/cpu/cpuacct.stat /sys/fs/cgroup/cpu/cpuacct.usage
user 34618
system 18038
743932863030
Run Code Online (Sandbox Code Playgroud)
前者的单位是百分之一秒,后者的单位是纳秒,即 346.18、180.38 和 743.932863030
我的问题是:为什么前两者加起来不等于后者?
您可能会想“啊,他们从不同的起源开始”,所以几分钟后以下是相同的指标:
# cat /sys/fs/cgroup/cpu/cpuacct.stat /sys/fs/cgroup/cpu/cpuacct.usage
user 40028
system 22098
818501029494
Run Code Online (Sandbox Code Playgroud)
增量为 54.1、40.6 和 74.57。
为什么 free 命令报告的内存使用量与 cgroup 的内存使用量有很大不同?
$ free -b
total used free shared buff/cache available
Mem: 2096914432 520863744 1112170496 35389440 463880192 1356828672
Swap: 2145382400 0 2145382400
$ cat /sys/fs/cgroup/memory/memory.usage_in_bytes
857239552
Run Code Online (Sandbox Code Playgroud)
cgroups 的文档说 memory.usage_in_bytes 是一个“模糊值”。我猜这只是意味着它报告的估计值接近实际值。即使这是一个估计,我认为也不应该相差这么远。
我在 VirutalBox 虚拟机中运行 Linux Mint 18.2。
cgroup ×10
linux ×7
docker ×2
containers ×1
cpu-usage ×1
debian ×1
kernel ×1
loop-device ×1
lxc ×1
memory ×1
memory-usage ×1
multi-core ×1
oom ×1
process ×1
systemd ×1
ubuntu ×1