备注

使用cgroup命名空间需要使用CONFIG_CGROUPS选项配置的内核。

cgroup命名空间提供的虚拟化有多种用途:

*
它可以防止信息泄漏,否则容器外部的cgroup目录路径对于容器中的进程将是可见的。例如,此类泄漏可能向容器化的应用程序揭示有关容器框架的信息。
*
它简化了诸如容器迁移之类的任务。 cgroup命名空间提供的虚拟化允许将容器与祖先cgroup的路径名知识区分开。如果没有这种隔离,则在迁移容器时,需要在目标系统上复制完整的cgroup路径名(显示在/ proc / self / cgroups中)。这些路径名也必须是唯一的,以免与目标系统上的其他路径名冲突。
*
It allows better confinement of containerized processes, because it is possible to mount the container's cgroup filesystems such that the container processes can't gain access to ancestor cgroup directories. Consider, for example, the following scenario:
*
我们有一个cgroup目录/ cg / 1,由用户ID 9000拥有。
*
我们有一个进程X,也由用户ID 9000拥有,该进程在cgroup / cg / 1/2下进行了命名空间(即X通过CLONE_NEWCGROUP通过clone(2)或unshare(2)放置在新的cgroup命名空间中)。旗)。
在没有cgroup名称空间的情况下,因为cgroup目录/ cg / 1由UID 9000拥有(并且可写),并且进程X也由用户ID 9000拥有,所以进程X将能够修改cgroups文件的内容(即,更改cgroup设置),不仅要在/ cg / 1/2中,还要在祖先cgroup目录/ cg / 1中。 cgroup目录/ cg / 1/2下的命名空间X与对cgroup文件系统进行适当的安装操作(如上所示)相结合,阻止了它修改/ cg / 1中的文件,因为它甚至无法看到该目录的内容(或进一步删除的cgroup祖先目录)。结合正确执行分层限制,这可以防止进程X逃避祖先cgroup施加的限制。

另外参见

unshare(1),clone(2),setns(2),unshare(2),proc(5),cgroups(7),凭据(7),名称空间(7),user_namespaces(7)

CGROUP_NAMESPACES - Linux手册页

Linux程序员手册 第7部分
更新日期: 2019-08-02

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

说明

有关名称空间的概述,请参见namespaces(7)。

Cgroup名称空间可虚拟化进程的cgroup(请参阅cgroups(7))视图,如通过/ proc / [pid] / cgroup和/ proc / [pid] / mountinfo看到的那样。

每个cgroup命名空间都有自己的一组cgroup根目录。这些根目录是/ proc / [pid] / cgroup文件中相应记录中显示的相对位置的基点。当进程使用带有CLONE_NEWCGROUP标志的clone(2)或unshare(2)创建新的cgroup命名空间时,其当前cgroups目录将成为新命名空间的cgroup根目录。 (这适用于cgroups版本1层次结构和cgroups版本2统一层次结构。)

从/ proc / [pid] / cgroup读取"目标"进程的cgroup成员资格时,每条记录的第三字段中显示的路径名将相对于相应cgroup层次结构的读取进程的根目录。如果目标进程的cgroup目录位于读取进程的cgroup命名空间的根目录之外,则路径名将显示cgroup层次结构中每个祖先级别的../条目。

以下Shell会话演示了创建新的cgroup命名空间的效果。

首先,(作为超级用户)在初始cgroup命名空间的shell中,我们在冰箱层次结构中创建一个子cgroup,并在该cgroup中放置一个过程,我们将在下面的演示中使用该过程:

# mkdir -p /sys/fs/cgroup/freezer/sub2
# sleep 10000 &     # Create a process that lives for a while
[1] 20124
# echo 20124 > /sys/fs/cgroup/freezer/sub2/cgroup.procs

然后,我们在冰箱层次结构中创建另一个子cgroup,并将外壳放入该cgroup中:

# mkdir -p /sys/fs/cgroup/freezer/sub
# echo $$                      # Show PID of this shell
30655
# echo 30655 > /sys/fs/cgroup/freezer/sub/cgroup.procs
# cat /proc/self/cgroup | grep freezer
7:freezer:/sub

接下来,我们使用unshare(1)创建一个在新cgroup中运行新shell的进程并安装名称空间:

# PS1="sh2# " unshare -Cm bash

然后,从unshare(1)开始的新Shell中,我们分别检查新Shell的/ proc / [pid] / cgroup文件,该文件位于初始cgroup名称空间(init,带有PID 1)中,并且同级cgroup(sub2)中的进程:

sh2# cat /proc/self/cgroup | grep freezer
7:freezer:/
sh2# cat /proc/1/cgroup | grep freezer
7:freezer:/..
sh2# cat /proc/20124/cgroup | grep freezer
7:freezer:/../sub2

从第一个命令的输出中,我们看到新外壳(与初始外壳在同一个cgroup中)的冷冻机cgroup成员身份相对于冷冻机cgroup根目录定义,该目录在新cgroup命名空间为创建。 (绝对而言,新外壳程序位于/ sub freezer cgroup中,并且新cgroup名称空间中的freezer cgroup层次结构的根目录也是/ sub。因此,新外壳程序的cgroup成员身份显示为aq / aq。)

但是,当我们查看/ proc / self / mountinfo时,会看到以下异常:

sh2# cat /proc/self/mountinfo | grep freezer
155 145 0:32 /.. /sys/fs/cgroup/freezer ...

这行的第四个字段(/ ..)应该显示cgroup文件系统中的目录,该目录构成了此挂载的根目录。由于根据cgroup名称空间的定义,该进程的当前freezer cgroup目录成为其root freezer cgroup目录,因此在此字段中应该看到aq / aq。这里的问题是,我们看到了对应于初始cgroup命名空间的cgroup文件系统的装载条目(其cgroup文件系统确实根于sub的父目录)。要解决此问题,我们必须从新的外壳中重新安装冷冻机cgroup文件系统(即,从新cgroup命名空间中的进程执行安装),然后我们将看到预期的结果:

sh2# mount --make-rslave /     # Don't propagate mount events
                               # to other namespaces
sh2# umount /sys/fs/cgroup/freezer
sh2# mount -t cgroup -o freezer freezer /sys/fs/cgroup/freezer
sh2# cat /proc/self/mountinfo | grep freezer
155 145 0:32 / /sys/fs/cgroup/freezer rw,relatime ...

遵循规范

命名空间是特定于Linux的功能。

名称

cgroup_namespaces-Linux cgroup名称空间概述

日期:2019-08-20 18:01:52 来源:oir作者:oir