userns容器无法启动,如何跟踪原因?


8

在Ubuntu 14.04上使用以下命令行创建userns(非特权)LXC容器时:

lxc-create -n test1 -t download -- -d $(lsb_release -si|tr 'A-Z' 'a-z') -r $(lsb_release -sc) -a $(dpkg --print-architecture)

和(不触摸创建的配置文件),然后尝试使用以下命令启动它:

lxc-start -n test1 -l DEBUG

它失败。日志文件显示了我:

lxc-start 1420149317.700 INFO     lxc_start_ui - using rcfile /home/user/.local/share/lxc/test1/config
lxc-start 1420149317.700 INFO     lxc_utils - XDG_RUNTIME_DIR isn't set in the environment.
lxc-start 1420149317.701 INFO     lxc_confile - read uid map: type u nsid 0 hostid 100000 range 65536
lxc-start 1420149317.701 INFO     lxc_confile - read uid map: type g nsid 0 hostid 100000 range 65536
lxc-start 1420149317.701 WARN     lxc_log - lxc_log_init called with log already initialized
lxc-start 1420149317.701 INFO     lxc_lsm - LSM security driver AppArmor
lxc-start 1420149317.701 INFO     lxc_utils - XDG_RUNTIME_DIR isn't set in the environment.
lxc-start 1420149317.702 DEBUG    lxc_conf - allocated pty '/dev/pts/2' (5/6)
lxc-start 1420149317.702 DEBUG    lxc_conf - allocated pty '/dev/pts/7' (7/8)
lxc-start 1420149317.702 DEBUG    lxc_conf - allocated pty '/dev/pts/8' (9/10)
lxc-start 1420149317.702 DEBUG    lxc_conf - allocated pty '/dev/pts/10' (11/12)
lxc-start 1420149317.702 INFO     lxc_conf - tty's configured
lxc-start 1420149317.702 DEBUG    lxc_start - sigchild handler set
lxc-start 1420149317.702 DEBUG    lxc_console - opening /dev/tty for console peer
lxc-start 1420149317.702 DEBUG    lxc_console - using '/dev/tty' as console
lxc-start 1420149317.702 DEBUG    lxc_console - 14946 got SIGWINCH fd 17
lxc-start 1420149317.702 DEBUG    lxc_console - set winsz dstfd:14 cols:118 rows:61
lxc-start 1420149317.905 INFO     lxc_start - 'test1' is initialized
lxc-start 1420149317.906 DEBUG    lxc_start - Not dropping cap_sys_boot or watching utmp
lxc-start 1420149317.906 INFO     lxc_start - Cloning a new user namespace
lxc-start 1420149317.906 INFO     lxc_cgroup - cgroup driver cgmanager initing for test1
lxc-start 1420149317.907 ERROR    lxc_cgmanager - call to cgmanager_create_sync failed: invalid request
lxc-start 1420149317.907 ERROR    lxc_cgmanager - Failed to create hugetlb:test1
lxc-start 1420149317.907 ERROR    lxc_cgmanager - Error creating cgroup hugetlb:test1
lxc-start 1420149317.907 INFO     lxc_cgmanager - cgroup removal attempt: hugetlb:test1 did not exist
lxc-start 1420149317.908 INFO     lxc_cgmanager - cgroup removal attempt: perf_event:test1 did not exist
lxc-start 1420149317.908 INFO     lxc_cgmanager - cgroup removal attempt: blkio:test1 did not exist
lxc-start 1420149317.908 INFO     lxc_cgmanager - cgroup removal attempt: freezer:test1 did not exist
lxc-start 1420149317.909 INFO     lxc_cgmanager - cgroup removal attempt: devices:test1 did not exist
lxc-start 1420149317.909 INFO     lxc_cgmanager - cgroup removal attempt: memory:test1 did not exist
lxc-start 1420149317.909 INFO     lxc_cgmanager - cgroup removal attempt: cpuacct:test1 did not exist
lxc-start 1420149317.909 INFO     lxc_cgmanager - cgroup removal attempt: cpu:test1 did not exist
lxc-start 1420149317.910 INFO     lxc_cgmanager - cgroup removal attempt: cpuset:test1 did not exist
lxc-start 1420149317.910 INFO     lxc_cgmanager - cgroup removal attempt: name=systemd:test1 did not exist
lxc-start 1420149317.910 ERROR    lxc_start - failed creating cgroups
lxc-start 1420149317.910 INFO     lxc_utils - XDG_RUNTIME_DIR isn't set in the environment.
lxc-start 1420149317.910 ERROR    lxc_start - failed to spawn 'test1'
lxc-start 1420149317.910 INFO     lxc_utils - XDG_RUNTIME_DIR isn't set in the environment.
lxc-start 1420149317.910 INFO     lxc_utils - XDG_RUNTIME_DIR isn't set in the environment.
lxc-start 1420149317.910 ERROR    lxc_start_ui - The container failed to start.
lxc-start 1420149317.910 ERROR    lxc_start_ui - Additional information can be obtained by setting the --logfile and --logpriority options.

现在我在这里看到两个错误,后者可能是前者的结果,即:

lxc_start-创建cgroups失败

但是,我看到/sys/fs/cgroup安装了:

$ mount|grep cgr
none on /sys/fs/cgroup type tmpfs (rw)

cgmanager安装:

$ dpkg -l|awk '$1 ~ /^ii$/ && /cgmanager/ {print $2 " " $3 " " $4}'
cgmanager 0.24-0ubuntu7 amd64
libcgmanager0:amd64 0.24-0ubuntu7 amd64

注意:我的主机默认仍为upstart

如有疑问,内核支持cgroups

$ grep CGROUP /boot/config-$(uname -r)
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_NET_CLS_CGROUP=m
CONFIG_NETPRIO_CGROUP=m

注意:我的主机默认仍为upstart

Answers:


7

事实证明,这是Ubuntu特有的事情。


原因

问题:尽管内核已cgroups启用(使用进行检查grep CGROUP /boot/config-$(uname -r))并cgmanager正在运行,但是没有特定于我的用户的cgroup。您可以使用以下方法进行检查:

$ cat / proc / self / cgroup
11:hugetlb:/
10:perf_event:/
9:blkio:/
8:冰柜:/
7:设备:/
6:内存:/
5:cpuacct:/
4:cpu:/
3:名称=系统化的:/
2:cpuset:/

如果在每个相关行中都给出了您的UID,那么就可以了,但是,如果没有定义cgroup,则在每行的第二个冒号之后只会有一个斜杠。

我的问题特定于启动未特权的容器。我可以启动特权容器。

原来,我的问题与邮件列表中的该主题lxc-users密切相关。

补救

在Ubuntu 14.04上upstart是默认设置,而不是systemd。因此systemd,默认情况下不会安装将在基于发行版上安装的某些组件。

有另外两个包来cgmanager,我曾为了安装以获得超出我的问题所示的错误:cgroup-binlibpam-systemd。坦率地说,我不是100%肯定必须严格使用前者,因此您可以尝试将其省略并在此处评论。

在安装软件包并重新引导之后,您应该id -u在输出中看到您的UID(此处为1000):

$ cat / proc / self / cgroup
11:hugetlb:/user/1000.user/1.session
10:perf_event:/user/1000.user/1.session
9:blkio:/user/1000.user/1.session
8:冰柜:/user/1000.user/1.session
7:设备:/user/1000.user/1.session
6:内存:/user/1000.user/1.session
5:cpuacct:/user/1000.user/1.session
4:cpu:/用户/1000.user/1.session
3:名称= systemd:/user/1000.user/1.session
2:cpuset:/user/1000.user/1.session

此后,尝试启动来宾容器时出现错误(为简洁起见,将其修剪):

lxc-start 1420160065.383信息lxc_cgroup-用于test1的cgroup驱动程序cgmanager初始化
lxc-start 1420160065.419错误lxc_start-无法创建配置的网络
lxc-start 1420160065.446错误lxc_start-无法生成'test1'
lxc-start 1420160065.451错误lxc_start_ui-容器无法启动。

因此,仍然没有成功,但是我们离目标只有一步之遥。

上述连接lxc-users线指向/etc/systemd/logind.conf不提三个控制器:net_clsnet_priodebug。对我来说,只有最后一个失踪了。更改之后,您将不得不重新登录,因为更改将在创建登录会话后生效。

LXC的一位作者的这篇博客文章给出了下一步:

尽管您的用户可以创建新的用户命名空间,但该用户命名空间将为uid 0,并且具有与该命名空间相关的资源的root特权,因此显然不会在主机上授予任何其他特权。

一种这样的事情是在主机上创建新的网络设备或更改网桥配置。为了解决该问题,我们编写了一个名为“ lxc-user-nic”的工具,它是LXC 1.0的唯一SETUID二进制部分,并且执行一项简单的任务。它解析配置文件,并根据其内容为用户创建网络设备并桥接它们。为了防止滥用,您可以限制用户可以请求的设备数量以及可以添加的网桥。

一个示例是我自己的/ etc / lxc / lxc-usernet文件:

stgraber veth lxcbr0 10

这声明允许用户“ stgraber”最多创建10个veth类型的设备并将其添加到称为lxcbr0的网桥。

在内核中用户命名空间提供的功能和该setuid工具之间,我们已经获得了运行大多数无特权发行版所需的一切。

如果您的用户拥有sudo权限并且您正在使用Bash,请使用以下命令:

echo "$(whoami) veth lxcbr0 10"|sudo tee -a /etc/lxc/lxc-usernet

并确保类型(veth)与容器配置中的类型匹配,并且桥接(lxcbr0)已配置且处于启动状态。

现在我们得到了另一组错误:

lxc-start 1420192192.775信息lxc_start-克隆新的用户名称空间
lxc-start 1420192192.775信息lxc_cgroup-用于test1的cgroup驱动程序cgmanager初始化
lxc-start 1420192192.923注意lxc_start-在新用户名称空间中切换到gid / uid 0
lxc-start 1420192192.923错误lxc_start-权限被拒绝-无法访问/ home / user。请授予它“ x”访问权限,或为容器根目录添加ACL。
lxc-start 1420192192.923错误lxc_sync-无效的序列号1.预期2
lxc-start 1420192192.954错误lxc_start-无法生成'test1'
lxc-start 1420192192.959错误lxc_start_ui-容器无法启动。

辉煌,可以解决。与第一个线索相同的主角提供了另一个lxc-users线索

目前,必须进行快速测试sudo chmod -R o+X $HOME,但是ACL在这里也是可行的选择。YMMV。


如果我想以另一个用户身份运行userns LXC容器,它仍然会失败。创作工作(警告:)WARN: could not reopen tty: Permission denied。但是启动sudo -H -i -u database lxc-start -n mysql -d失败就像您的问题一样。同样的错误。但是,您的修复程序不适用于sudo。如果我这样做了,sudo -H -i -u database cat /proc/self/cgroup我得到的输出与我作为主叫用户运行的输出完全相同。所以很显然,当尝试使用sudo启动容器时,它将尝试作为其他用户写入我的cgroup中,这会失败... :-(有什么见识?
Huygens
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.