Como iniciar automaticamente contêineres lxc sem privilégios?

9

No Ubuntu 14.04, criei um contêiner sem privilégios que posso iniciar e parar manualmente.

Mas eu gostaria que isso iniciasse e parasse junto com o sistema.

Eu adicionei o seguinte à configuração do contêiner: lxc.start.auto = 1 lxc.start.delay = 5

No entanto, os scripts do sistema não parecem selecionar contêineres não privilegiados.

um tópico relacionado a isso no linuxcontainers.org, mas a solução parece estar restrita ao rootusuário.

Existe uma maneira limpa de fazer isso para um usuário não root (com o consentimento do usuário root)?

HRJ
fonte

Respostas:

3

Eu acho que encontrei uma solução melhor do que as atualmente apresentadas aqui. Em parte porque, até onde eu sei, o cgmanager está morto, em parte porque minha solução não parece uma solução alternativa, mas principalmente porque essa discussão ainda aparece ao procurar uma solução para o problema. Na verdade, é bem simples: use o modo de usuário systemd .

Concedido se você não usar o systemd, esta solução não ajudará. Nesse caso, aconselho que você descubra se o seu sistema init tem alguma maneira de permitir que usuários sem privilégios executem serviços na inicialização e os use como ponto de partida.

Usando o modo de usuário systemd para iniciar automaticamente contêineres lxc não privilegiados

Suponho que você tenha contêineres lxc sem privilégios funcionando corretamente e que funcionem lxc-autostartconforme o usuário do contêiner funciona. Nesse caso, faça o seguinte:

  1. Crie o arquivo ~/.config/systemd/user/lxc-autostart.servicena casa de qualquer usuário que tenha os contêineres lxc:
[Unit]
Description="Lxc-autostart for lxc user"

[Service]
Type=oneshot
ExecStart=/usr/bin/lxc-autostart
ExecStop=/usr/bin/lxc-autostart -s
RemainAfterExit=1

[Install]
WantedBy=default.target
  1. Então, como esse usuário é executado:
systemctl --user enable lxc-autostart

(Observe, a --useropção diz ao systemctl que você o está usando no modo de usuário. Todas as coisas que normalmente faço com systemctl, inicio, parada, status, ativação, etc, funcionam com --user.)

  1. Em seguida, execute o seguinte, onde $userestá o nome do usuário que possui os contêineres lxc:
sudo loginctl enable-linger $user

Isso é necessário para o systemd iniciar uma instância do usuário do systemd $userna inicialização. Caso contrário, ele iniciaria apenas um no momento $userem que efetuar login.

Para obter mais informações, recomendo a página systemd / timer do archlinux wiki e as páginas de manual systemd .

Acessando a instância systemd de um usuário como root

Você pode realmente iniciar / parar / qualquer serviço de sistema do usuário como root, no entanto, isso exige que você defina a XDG_RUNTIME_DIRvariável de ambiente. Suponha que $user seja o usuário cuja instância você deseja acessar e $uidseja uid, é assim que você iniciaria o lxc-autostart.service definido acima:

sudo -u $user XDG_RUNTIME_DIR=/run/user/$uid systemctl --user start lxc-autostart

Você pode até usar systemd-runpara executar comandos arbitrários como esse usuário de uma maneira que não quebre o lxc. Estou usando os seguintes comandos para parar / iniciar meus contêineres antes / depois do backup, onde $nameestá o nome do contêiner lxc que está sendo copiado:

sudo -u $user XDG_RUNTIME_DIR=/run/user/$uid systemd-run --user --wait lxc-stop -n $name
sudo -u $user XDG_RUNTIME_DIR=/run/user/$uid systemd-run --user --scope lxc-start -n $name

(Observe que sem --waitsystemd-run não bloqueia até que o contêiner seja parado.)

Wieke
fonte
7

Eu recomendo usar o @rebootalias útil no cron do Ubuntu para executar lxc-autostart.

Como usuário que possui o contêiner não privilegiado, execute crontab -ee adicione a seguinte linha:

@reboot lxc-autostart

codificado
fonte
Isso parece ótimo. No entanto, não parece haver uma maneira de executar um comando no desligamento (via cron). Alguma ideia?
HRJ 30/01
Não conheço maneiras simples de executar um trabalho no desligamento. Você provavelmente teria que, como root, adicionar um trabalho inicial para encerrar os contêineres de cada usuário que os possui. Você pode procurar /etc/init/lxc.confpor ponteiros. É o trabalho inicial que inicia os contêineres privilegiados. Não deve ser muito difícil copiá-lo e modificá-lo para encerrar contêineres não privilegiados também.
codificado em
1
Ocorre-me que, como cada processo no contêiner é visível a partir do host, o contêiner provavelmente não precisa de nada de especial para desligá-lo, cada processo deve receber o sinal TERM do host. Provavelmente, você não precisa fazer nada de especial no desligamento. Se você deseja executar alguns scripts ou outras coisas no desligamento, isso é diferente, mas a maioria dos processos deve ter a chance de desligar normalmente.
codificado
A abordagem crontab funciona? No Ubuntu 14.04, recebo o erro "chamada para cgmanager_move_pid_sync falhou: solicitação inválida" que ocorre porque o PAM, ou seja, libpam-systemd não está envolvido no processo de alteração do usuário. Você pode ver /proc/self/cgroupque ele contém seqüências como em /user/0.user/1.sessionvez de/user/1000.user/1.session
Daniel Alder
3

Caso alguém se depare com essas perguntas e respostas, como resposta à inicialização automática de contêineres LXC sem privilégios (eu certamente volto aqui), aqui está uma solução que funciona bem e que eu segui para que funcionasse no meu servidor:

http://blog.lifebloodnetworks.com/?p=2118 de Nicholas J Ingrassellino.

Em poucas palavras, envolve a criação de dois scripts e eles trabalham juntos na inicialização para permitir que o LXC inicie os contêineres sem privilégios de cada usuário listado, sem precisar efetivamente fazer login na conta do usuário; em outras palavras, executar o comando como o usuário com toda a magia do CGroups intacta. De acordo com as melhores práticas do SO, citarei aqui os ossos, mas vale a pena ler o artigo original.

Permitir que nossa conta de usuário use a ponte…

echo "$USER veth lxcbr0 1024" | sudo tee -a /etc/lxc/lxc-usernet

Criar script inicial ... Em /etc/init/lxc-unprivileged.confadição ...

description "LXC Unprivileged Containers"
author "Mike Bernson <[email protected]>"

start on started lxc

script
    USERS="[user]"

    for u in $USERS; do
        cgm create all lxc$u
        cgm chown all lxc$u $(id -u $u) $(id -g $u)
        lxc-autostart -L -P /home/$u/.local/share/lxc | while read line;
        do
            set -- $line
            /usr/local/bin/startunprivlxc lxc$u $u $1
            sleep $2
        done
    done
end script

Certifique-se de substituir [usuário] por sua conta de usuário.

Crie o script de início do contêiner ... Em /usr/local/bin/startunprivlxc add ...

#!/bin/sh

cgm movepid all $1 $$
sudo -iH -u $2 -- lxc-start -n $3 -d

... e torná-lo executável ...

sudo chmod +x /usr/local/bin/startunprivlxc

Gostaria apenas de enfatizar que ele parece funcionar com segurança, corretamente e não requer a raiz do SSH nas outras contas de usuário.

Também há mais sobre o assunto (tocando em dicas relacionadas) aqui: https://gist.github.com/julianlam/4e2bd91d8dedee21ca6f, que pode ser útil para entender por que é assim.

Kevin Teljeur
fonte
2

Escrevi um pequeno script para solucionar o problema, basta seguir as instruções comentadas.

Thiago de Arruda
fonte
0

DESCULPE: respondeu muito cedo. Não funcionou, embora lxc-ls mostre "AUTOSTART" como "YES".

Aqui está um link com informações muito mais úteis, e talvez alguém possa usá-las: http://www.geeklee.co.uk/unprivileged-privileged-containers-ubuntu-14-04-lxc/

Cheguei nesta página porque tive o mesmo problema. Depois de ler este tópico, percebi que o lxc-create não pode gravar no diretório "/ var / lib / lxc /" usual se não for executado com o sudo.

Eu olhei em volta e localizei os rootfs para meu contêiner sem privilégios em "~ / .local / share / lxc" e coloquei as duas linhas da pergunta na configuração nesse diretório.

Eu olhei para o modelo que usei "lxc-download" para obter uma pista, mas acho que esse caminho foi passado quando "lxc-download" é ​​chamado. Não observei como o sistema procura contêineres sem privilégios durante a inicialização.

lxc n00b
fonte
0

Estou executando cada contêiner não privilegiado com um mesmo usuário nomeado para melhor isolamento e é assim que eu faço:

#!/bin/bash

LXC_CONTAINERS="container1 container2"

for LXC_CONTAINER in $LXC_CONTAINERS; do
 su - $LXC_CONTAINER -c "lxc-start -n $LXC_CONTAINER --logfile /home/$LXC_CONTAINER/.local/share/lxc/lxc-$LXC_CONTAINER.log --logpriority DEBUG"
done
sam
fonte
-1

Supondo (que é a mãe de todas as maneiras de estragar tudo), você está efetuando login como o usuário que "possui" o contêiner lxc sem privilégios, o seguinte comando deve abordar o que você está procurando ...

$ echo "lxc-start -n LXC-CONTAINER-NAME -d" >> .bashrc

Isso simplesmente executará o comando acima quando você efetuar login via bash. Isso também pressupõe que o bash é o shell de logon. Substitua o nome: LXC-CONTAINER-NAMEpelo nome do seu contêiner LXC que você deseja iniciar.

user249005
fonte
-1

Eu usei uma abordagem diferente e está funcionando

1º Adicione as seguintes entradas no arquivo de configuração do contêiner

CONFIGURAÇÃO DE INÍCIO AUTOMÁTICO

lxc.start.auto = 1 lxc.start.delay = 5

2º Criar uma relação de confiança entre o usuário do contêiner e ele próprio no mesmo servidor

userlxc @ GEST-4: ~ $ ssh-keygen -t rsa Gerando pares de chaves rsa públicas / privadas. Digite o arquivo no qual salvar a chave (/home/userlxc/.ssh/id_rsa): Digite a senha (vazia para nenhuma senha): Digite a mesma senha novamente: sua identificação foi salva em /home/userlxc/.ssh/id_rsa. Sua chave pública foi salva em /home/userlxc/.ssh/id_rsa.pub. A impressão digital da chave é: c9: b4: e1: f3: bf: a3: 25: cc: f8: bc: be: b6: 80: 39: 59: 98 userlxc @ GEST-AMENCIA-4 A imagem randomart da chave é: + - [RSA 2048] ---- + | | | | | o | | * + | | ES | = * | | = o =. | | . +. +. | | oO = oo | + ----------------- +

userlxc @ GEST-4: ~ $ cat .ssh / id_rsa.pub >> .ssh / allowed_keys userlxc @ GEST-4: ~ $ ls -lrt .ssh / allowed_keys -rw-rw-r-- 1 userlxc userlxc 404 Nov 19 17:23 .ssh / allowed_keys

Verifique a conexão ssh, você deve poder usá-la sem a senha userlxc @ GEST-4: ~ $ ssh userlxc @ localhost "lxc-ls --fancy"

NOME ESTADO IPV4 IPV6 AUTOSTART

EXTLXCCONT01 PARADO - - SIM
UBUSER1404USERCONT01-test PARADO - - NÃO
UBUSER1404USERLXCCONT01 PARADO - - NÃO

3º Criar uma entrada crontab no proprietário do contêiner

@reboot ssh userlxc @ localhost "lxc-autostart"

user323185
fonte