O contêiner userns falha ao iniciar, como rastrear o motivo?

8

Ao criar um contêiner LXC de usuários (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 depois tentar iniciá-lo com:

lxc-start -n test1 -l DEBUG

Falha. O arquivo de log mostra-me:

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 resultado do primeiro, que é:

lxc_start - falha ao criar cgroups

No entanto, vejo /sys/fs/cgroupmontado:

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

e cgmanagerestá instalado:

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

Nota: Meu host ainda é o padrão upstart.

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

Nota: Meu host ainda é o padrão upstart.

0xC0000022L
fonte

Respostas:

7

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


A causa

O problema: embora o kernel tenha cgroupsativado (verifique com grep CGROUP /boot/config-$(uname -r)) e cgmanageresteja em execução, não há um 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: congelador: /
7: dispositivos: /
6: memória: /
5: cpuacct: /
4: CPU: /
3: nome = systemd: /
2: cpuset: /

se o seu UID for fornecido em cada uma das linhas relevantes, tudo bem, mas se nenhum cgroups tiver sido definido, haverá apenas uma barra após o segundo dois pontos em cada linha.

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

Aconteceu que meu problema estava intimamente relacionado a esse tópico na lxc-userslista de discussão .

Remédio

No Ubuntu 14.04 upstarté o padrão, por oposição a systemd. Portanto, certos componentes que seriam instalados em uma systemddistribuição baseada em não são instalados por padrão.

Havia dois pacotes além dos cgmanagerquais eu tinha que instalar para ir além do erro mostrado na minha pergunta: cgroup-bine libpam-systemd. Francamente, não tenho 100% de certeza de que o primeiro seja estritamente necessário, então 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 -uaqui 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: dispositivos: /user/1000.user/1.session
6: memória: /user/1000.user/1.session
5: cpuacct: /user/1000.user/1.session
4: cpu: /user/1000.user/1.session
3: nome = 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 (aparado por questões de brevidade):

lxc-start 1420160065.383 INFO lxc_cgroup - driver do cgroup cgmanager inicial para teste1
lxc-start 1420160065.419 ERRO lxc_start - falha ao criar a rede configurada
lxc-start 1420160065.446 ERRO lxc_start - falha ao gerar 'test1'
lxc-start 1420160065.451 ERRO lxc_start_ui - O contêiner falhou ao iniciar.

Portanto, ainda não obtivemos sucesso, mas estamos um passo mais perto.

Os acima ligados lxc-userspontos de rosca para /etc/systemd/logind.confnão mencionar três controladores: net_cls, net_prioe debug. Para mim, apenas o último estava faltando. Após a alteração, você terá que efetuar login novamente, pois as alterações entram 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:

Seu usuário, embora possa criar novos espaços para nome de usuário nos quais será uid 0 e terá alguns dos privilégios de root em relação aos recursos vinculados a esse espaço para nome, obviamente não terá privilégios extras no host.

Uma coisa é criar novos dispositivos de rede no host ou alterar a configuração da ponte. Para contornar isso, escrevemos uma ferramenta chamada “lxc-user-nic”, que é a única parte binária SETUID do LXC 1.0 e que executa uma tarefa simples. Ele analisa um arquivo de configuração e, com base em seu conteúdo, cria dispositivos de rede para o usuário e os une. Para evitar abusos, você pode restringir o número de dispositivos que um usuário pode solicitar e a qual ponte eles podem ser adicionados.

Um exemplo é o meu próprio arquivo / etc / lxc / lxc-usernet:

stgraber veth lxcbr0 10

Isso declara que o usuário “stgraber” pode criar e adicionar até 10 dispositivos do tipo veth à ponte chamada lxcbr0.

Entre o que é oferecido pelo namespace de usuário no kernel e essa ferramenta setuid, temos tudo o que é necessário para executar a maioria das distribuições sem privilégios.

Se seu usuário tiver sudodireitos e você estiver usando o Bash, use o seguinte:

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

e verifique se o tipo ( veth) corresponde ao tipo na 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 - Clonando um novo espaço para nome de usuário
lxc-start 1420192192.775 INFO lxc_cgroup - driver do cgroup cgmanager inicial para teste1
lxc-start 1420192192.923 AVISO lxc_start - alternando para gid / uid 0 no novo espaço de nome do usuário
lxc-start 1420192192.923 ERRO lxc_start - permissão negada - não foi possível acessar / home / usuário. Conceda acesso 'x' ou adicione uma ACL para a raiz do contêiner.
lxc-start 1420192192.923 ERRO lxc_sync - número de sequência inválido 1. esperado 2
lxc-start 1420192192.954 ERRO lxc_start - falha ao gerar 'test1'
lxc-start 1420192192.959 ERRO lxc_start_ui - O contêiner falhou ao iniciar.

Brilhante, isso pode ser corrigido. Outro lxc-usersfio pelos mesmos protagonistas do primeiro fio abre o caminho.

Por enquanto, sudo chmod -R o+X $HOMEserá necessário um teste rápido , mas as ACLs também são uma opção viável. YMMV.

0xC0000022L
fonte
Ainda estou preso pelo fato de que, se eu quiser executar o contêiner LXC de usuários como outro usuário, ele falhará. A criação funciona (com um aviso:) WARN: could not reopen tty: Permission denied. Mas iniciar sudo -H -i -u database lxc-start -n mysql -dfalha como em sua pergunta. Mesmos erros. No entanto, sua correção não funciona sudo. Se eu sudo -H -i -u database cat /proc/self/cgroupobtiver exatamente a mesma saída como se eu a executasse como meu usuário de chamada. Então, obviamente, ao tentar iniciar o recipiente usando sudo, ele vai tentar que o outro usuário para escrever no meu cgroup que falha ... :-( Qualquer insight?
Huygens