什么是非特权LXC容器?


20

如果将Linux容器(LXC容器)称为“非特权”是什么意思?

Answers:


20

非特权LXC容器是利用用户名称空间)的容器。即,一种内核功能,它允许将主机上的一系列UID映射到命名空间中,该命名空间中,UID为0的用户可以再次存在。

与我最初对非特权LXC容器的最初看法相反,这并不意味着该容器必须由非特权主机用户拥有。那只是一种可能性。

相关的是:

  1. 为主机用户(usermod [-v|-w|--add-sub-uids|--add-sub-gids])定义了一系列下级UID和GID
  2. ...并且此范围已映射到容器配置(lxc.id_map = ...)中

甚至root也可以拥有未特权的容器,因为主机上容器进程的有效UID最终将在映射定义的范围内。

但是,因为root您必须先定义下级ID。通过创建与用户不同adduserroot不会有一系列默认定义下属的ID。

还请记住,您可以随意使用所有范围,因此您可以拥有3个具有以下配置行的容器(仅显示UID映射):

  1. lxc.id_map = u 0 100000 100000
  2. lxc.id_map = u 0 200000 100000
  3. lxc.id_map = u 0 300000 100000

假设它root拥有100000到400000之间的从属UID。我发现的所有文档都建议每个容器使用65536个从属ID,不过有些使用100000使其更易于阅读。

换句话说:您不必为每个容器分配相同的范围。

拥有超过40亿(〜2^32)可能的下级ID,这意味着您可以很轻松地将下级范围处理给主机用户。

由root拥有和运行的非特权容器

再擦一遍。无特权的LXC来宾不需要由主机上的无特权用户运行。

使用从属UID / GID映射配置容器,如下所示:

lxc.id_map = u 0 100000 100000
lxc.id_map = g 0 100000 100000

root主机上的用户拥有给定下级ID范围的位置,将使您可以更好地限制来宾。

但是,在这种情况下还有一个重要的附加优势(是的,我已经证实它可以工作):您可以在系统启动时自动启动容器。

通常,当在网络上搜索有关LXC的信息时,系统会告知您无法自动启动没有特权的LXC来宾。但是,默认情况下,只有那些不在系统范围内的容器中的容器才是正确的(通常是/var/lib/lxc)。如果是这样(通常意味着它们是由root创建并由root启动),那就完全不一样了。

lxc.start.auto = 1

一旦将其放入容器配置中,将可以很好地完成这项工作。

正确获取权限和配置

我自己为此付出了一些努力,因此我在这里添加了一个部分。

除了lxc.include通常以名称/usr/share/lxc/config/$distro.common.conf$distro发行版的名称在其中)所包括的配置片段之外,您还应该检查/usr/share/lxc/config/$distro.userns.conf系统上是否还存在一个,并将其也包括在内。例如:

lxc.include = /usr/share/lxc/config/ubuntu.common.conf
lxc.include = /usr/share/lxc/config/ubuntu.userns.conf

此外,添加下级ID映射:

lxc.id_map = u 0 100000 65535
lxc.id_map = g 0 100000 65535

这意味着主机UID 100000是root 内部的LXC客人的用户名称空间。

现在,请确保权限正确。如果将来宾的姓名存储在环境变量中,则$lxcguest可以运行以下命令:

# Directory for the container
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest
chmod ug=rwX,o=rX $(lxc-config lxc.lxcpath)/$lxcguest
# Container config
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest/config
chmod u=rw,go=r $(lxc-config lxc.lxcpath)/$lxcguest/config
# Container rootfs
chown 100000:100000 $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
chmod u=rwX,go=rX $(lxc-config lxc.lxcpath)/$lxcguest/rootfs

这应该可以让您在首次尝试给出与权限有关的错误之后运行容器。


4
好的答案-但这lxc不是必需的。您可以使用该util-linux工具创建任何类型的名称空间容器unshare。您可以使用util-linux工具输入所述容器nsenter。后一种工具还允许您从没有它的情况下将正在运行的进程添加到已创建的容器中。命名空间支持是在内核中实现的。
mikeserv

4
@mikeserv:您的意思是不需要LXC来使用userns吗?我知道。我也知道Docker现在拥有自己的库,可以利用这些功能。但是,如果没有LXC提供的功能的帮助,您将如何对整个系统进行容器化?为什么要这么做?我的意思是只包含一个应用程序,并与之结合使用chroot会有所帮助,但是LXC组合了各种名称空间(UTS,安装等)以容器化整个系统。
0xC0000022L15年

2
好吧...就像我说的那样,unshare已经对任何/所有各种名称空间都做到了这一点,甚至可以/proc通过一个cli开关为您提供单独的私有安装。如果您的单个应用程序init和你的chrootinitramfs,你得到以秒为单位的整体容器。
mikeserv

0

为了跟踪0xC0000022L的解决方案,该解决方案对我来说效果很好,我编写了一个递增 uid-gid.pl perl脚本来自动执行必要的所有权更改,以便正确映射LXC容器中的文件。

如果没有它,则使用此建议的设置,在LXC容器本身中,属于LXC容器rootfs中主主机上0 / root的文件将被映射到65534 / nobody。要映射到LXC容器中的0 / root,它们必须在主机上属于100000。

这在这里描述https://yeupou.wordpress.com/2017/06/23/setting-up-lxc-containers-with-mapped-giduid/并且可以在gitlab https://gitlab.com上直接获取脚本/yeupou/stalag13/blob/master/usr/local/bin/increase-uid-gid.pl

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.