userns container falha ao iniciar, como rastrear o motivo?

8

Ao criar um contêiner LXC userns (sem privilégios) no Ubuntu 14.04 com a seguinte linha de comando:

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

e (sem tocar no arquivo de configuração criado) e tentar iniciá-lo com:

lxc-start -n test1 -l DEBUG

falha. O arquivo de log me mostra:

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.

Agora vejo dois erros aqui, o último provavelmente sendo um resultado do primeiro, que é:

lxc_start - failed creating cgroups

No entanto, vejo /sys/fs/cgroup montado:

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

e cgmanager estão instalados:

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

Observação: meu host ainda é padronizado para upstart .

Caso haja alguma dúvida, o suporte do kernel 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

Observação: meu host ainda é padronizado para upstart .

    
por 0xC0000022L 01.01.2015 / 23:11

1 resposta

7

Acontece surpresa surpresa, isso é uma coisa específica do Ubuntu.

A causa

O problema: embora o kernel tenha cgroups ativado (verifique com grep CGROUP /boot/config-$(uname -r) ) e cgmanager esteja em execução, não há nenhum cgroup específico para o meu usuário. Você pode verificar isso com:

$ cat /proc/self/cgroup
11:hugetlb:/
10:perf_event:/
9:blkio:/
8:freezer:/
7:devices:/
6:memory:/
5:cpuacct:/
4:cpu:/
3:name=systemd:/
2:cpuset:/

se o seu UID for dado em cada uma das linhas relevantes, tudo bem, mas se nenhum cgroup tiver sido definido, haverá apenas uma barra após o segundo cólon em cada linha.

Meu problema era específico para iniciar um contêiner sem privilégios. Eu poderia começar contêineres privilegiados bem.

Descobri que meu problema estava intimamente relacionado com este tópico sobre o lxc-users lista de discussão .

Remédio

No Ubuntu 14.04 upstart é o padrão, ao contrário de systemd . Portanto, certos componentes que seriam instalados em uma distro baseada em systemd não são instalados por padrão.

Havia dois pacotes além do cgmanager que eu tinha que instalar para ir além do erro mostrado na minha pergunta: cgroup-bin e libpam-systemd . Francamente, não estou 100% certo de que o primeiro é estritamente necessário, por isso você pode tentar deixar de fora e comentar aqui.

Após a instalação dos pacotes e uma reinicialização, você deverá ver seu UID ( id -u , here 1000) na saída:

$ 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:freezer:/user/1000.user/1.session
7:devices:/user/1000.user/1.session
6:memory:/user/1000.user/1.session
5:cpuacct:/user/1000.user/1.session
4:cpu:/user/1000.user/1.session
3:name=systemd:/user/1000.user/1.session
2:cpuset:/user/1000.user/1.session

Depois disso, o erro ao tentar iniciar o contêiner de convidado se torna (reduzido para brevidade):

lxc-start 1420160065.383 INFO     lxc_cgroup - cgroup driver cgmanager initing for test1
lxc-start 1420160065.419 ERROR    lxc_start - failed to create the configured network
lxc-start 1420160065.446 ERROR    lxc_start - failed to spawn 'test1'
lxc-start 1420160065.451 ERROR    lxc_start_ui - The container failed to start.

Ainda não há sucesso, mas estamos um passo mais perto.

O encadeamento lxc-users vinculado acima aponta para /etc/systemd/logind.conf sem mencionar três controladores: net_cls , net_prio e debug . Para mim, apenas o último estava faltando. Após a alteração, você terá que fazer o login novamente, já que as alterações entrarão em vigor após a criação da sua sessão de login.

Esta postagem de blog de um dos autores do LXC dá o próximo passo:

Your user, while it can create new user namespaces in which it’ll be uid 0 and will have some of root’s privileges against resources tied to that namespace will obviously not be granted any extra privilege on the host.

One such thing is creating new network devices on the host or changing bridge configuration. To workaround that, we wrote a tool called “lxc-user-nic” which is the only SETUID binary part of LXC 1.0 and which performs one simple task. It parses a configuration file and based on its content will create network devices for the user and bridge them. To prevent abuse, you can restrict the number of devices a user can request and to what bridge they may be added.

An example is my own /etc/lxc/lxc-usernet file:

stgraber veth lxcbr0 10

This declares that the user “stgraber” is allowed up to 10 veth type devices to be created and added to the bridge called lxcbr0.

Between what’s offered by the user namespace in the kernel and that setuid tool, we’ve got all that’s needed to run most distributions unprivileged.

Se seu usuário tiver sudo de direitos e você estiver usando o Bash, use:

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

e verifique se o tipo ( veth ) corresponde ao da configuração do contêiner e se a ponte ( lxcbr0 ) está configurada e ativa.

E agora temos outro conjunto de erros:

lxc-start 1420192192.775 INFO     lxc_start - Cloning a new user namespace
lxc-start 1420192192.775 INFO     lxc_cgroup - cgroup driver cgmanager initing for test1
lxc-start 1420192192.923 NOTICE   lxc_start - switching to gid/uid 0 in new user namespace
lxc-start 1420192192.923 ERROR    lxc_start - Permission denied - could not access /home/user.  Please grant it 'x' access, or add an ACL for the container root.
lxc-start 1420192192.923 ERROR    lxc_sync - invalid sequence number 1. expected 2
lxc-start 1420192192.954 ERROR    lxc_start - failed to spawn 'test1'
lxc-start 1420192192.959 ERROR    lxc_start_ui - The container failed to start.

Brilhante, isso pode ser corrigido. Outro lxc-users thread dos mesmos protagonistas do primeiro segmento abre o caminho maneira.

Por enquanto, um teste rápido sudo chmod -R o+X $HOME terá que ser feito, mas as ACLs também são uma opção viável. YMMV.

    
por 02.01.2015 / 11:12