¿Cómo iniciar automáticamente contenedores lxc sin privilegios?

9

En Ubuntu 14.04, he creado un contenedor sin privilegios que puedo iniciar y detener manualmente.

Pero me gustaría que esto comience y se detenga junto con el sistema.

He agregado lo siguiente a la configuración del contenedor: lxc.start.auto = 1 lxc.start.delay = 5

Sin embargo, las secuencias de comandos del sistema no parecen elegir contenedores sin privilegios.

Hay un hilo relacionado con esto en linuxcontainers.org, pero la solución parece estar restringida al rootusuario.

¿Hay una manera limpia de hacer esto para un usuario no root (con el consentimiento del usuario root)?

HRJ
fuente

Respuestas:

3

Creo que he encontrado una mejor solución que las que se presentan actualmente aquí. En parte porque, por lo que puedo decir, cgmanager está muerto, en parte porque mi solución no parece una solución alternativa, sino principalmente porque esta discusión todavía aparece cuando busco una solución al problema. En realidad es bastante simple: use el modo de usuario systemd .

Por supuesto, si no usa systemd, esta solución no va a ayudar. En ese caso, le aconsejaría que averigüe si su sistema init tiene alguna forma de permitir que usuarios sin privilegios ejecuten servicios en el arranque y los usen como punto de partida.

Uso del modo de usuario systemd para iniciar automáticamente contenedores lxc sin privilegios

Supongo que tiene contenedores lxc sin privilegios que funcionan correctamente y que se ejecutan a lxc-autostartmedida que funciona el usuario del contenedor. Si es así, haga lo siguiente:

  1. Cree el archivo ~/.config/systemd/user/lxc-autostart.serviceen el hogar de cualquier usuario que tenga los contenedores 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. Luego, mientras ese usuario ejecuta:
systemctl --user enable lxc-autostart

(Tenga en cuenta que la --useropción le dice a systemctl que lo está usando en modo de usuario. Todas las cosas que normalmente hago con systemctl, start, stop, statuc, enable, etc., funcionan con --user).

  1. Luego ejecute lo siguiente, donde $userestá el nombre del usuario que tiene los contenedores lxc:
sudo loginctl enable-linger $user

Esto es necesario para que systemd inicie una instancia de usuario systemd $useren el arranque. De lo contrario, solo comenzaría uno en el momento $useren que inicie sesión.

Para obtener más información, recomiendo la página archlinux wiki systemd / timer y las páginas man de systemd .

Acceder a la instancia de systemd de un usuario como root

En realidad, puede iniciar / detener / cualquier servicio systemd de un usuario como root, sin embargo, esto requiere que configure la XDG_RUNTIME_DIRvariable de entorno. Supongamos que $user es el usuario a cuya instancia desea acceder y $uides uid, así es como iniciaría el servicio lxc-autostart.service definido anteriormente:

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

Incluso puede usar systemd-runpara ejecutar comandos arbitrarios como ese usuario de una manera que no rompa lxc. Estoy usando los siguientes comandos para detener / iniciar mis contenedores antes / después de la copia de seguridad, donde $nameestá el nombre del contenedor lxc que se está respaldando:

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

(Tenga en cuenta que sin --waitsystemd-run no se bloquea hasta que se detiene el contenedor).

Wieke
fuente
7

Recomiendo usar el práctico @rebootalias en el cron de Ubuntu para ejecutar lxc-autostart.

Como usuario propietario del contenedor sin privilegios, ejecute crontab -ey agregue la siguiente línea:

@reboot lxc-autostart

codificado
fuente
Esto suena genial Sin embargo, no parece haber una manera de ejecutar un comando en el apagado (a través de cron). ¿Algunas ideas?
HRJ
No conozco ninguna forma simple de ejecutar un trabajo en el cierre. Probablemente, como root, deba agregar un trabajo inicial para cerrar los contenedores de cada usuario que los posea. Podrías buscar /etc/init/lxc.confpunteros. Es el trabajo inicial que inicia los contenedores privilegiados. No debería ser demasiado difícil copiarlo y modificarlo para cerrar también contenedores no privilegiados.
codificado el
1
Se me ocurre que, dado que cada proceso en el contenedor es visible desde el host, el contenedor probablemente no necesita nada especial para apagarlo, cada proceso debe recibir la señal TERM del host. Lo más probable es que no necesite hacer nada especial en el apagado. Si desea ejecutar algunos scripts u otras cosas similares en el apagado, eso es diferente, pero la mayoría de los procesos deberían tener la oportunidad de apagarse normalmente.
codificado el
¿Funciona el enfoque crontab? En Ubuntu 14.04, recibo el error "call to cgmanager_move_pid_sync: solicitud no válida" que ocurre porque PAM, es decir, libpam-systemd no está involucrado en el proceso de cambio del usuario. Puedes ver /proc/self/cgroupque contiene secuencias como en /user/0.user/1.sessionlugar de/user/1000.user/1.session
Daniel Alder
3

En caso de que alguien se tropiece con estas preguntas y respuestas para obtener la respuesta al inicio automático de contenedores LXC no privilegiados (ciertamente reviso mucho aquí), aquí hay una solución que funciona bien y que seguí para que funcione en mi servidor:

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

En pocas palabras, implica la creación de dos scripts, y funcionan juntos al inicio para permitir que LXC inicie los contenedores sin privilegios de cada usuario listado sin tener que iniciar sesión en la cuenta de usuario; en otras palabras, ejecutar el comando como el usuario con toda la magia de CGroups intacta. De acuerdo con las mejores prácticas de SO, citaré los detalles aquí, pero vale la pena leer su artículo original.

Permita que nuestra cuenta de usuario use el puente ...

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

Crear secuencia de comandos Upstart ... En /etc/init/lxc-unprivileged.confagregar ...

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

Asegúrese de reemplazar [usuario] con su cuenta de usuario.

Cree el script de inicio del contenedor ... Además, /usr/local/bin/startunprivlxc agregue ...

#!/bin/sh

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

... y hacerlo ejecutable ...

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

Solo me gustaría enfatizar que parece funcionar de manera segura, correcta y no requiere la raíz para SSH en las otras cuentas de usuario.

También hay más sobre el tema (tocando temas relacionados) aquí: https://gist.github.com/julianlam/4e2bd91d8dedee21ca6f que puede ser útil para comprender por qué es así.

Kevin Teljeur
fuente
2

He escrito un pequeño script para solucionar el problema, solo siga las instrucciones comentadas.

Thiago de Arruda
fuente
0

LO SIENTO: respondí demasiado pronto. No funcionó aunque lxc-ls muestra "AUTOSTART" como "YES".

Aquí hay un enlace con mucha más información útil, y tal vez alguien pueda usarlo: http://www.geeklee.co.uk/unprivileged-privileged-containers-ubuntu-14-04-lxc/

Llegué a esta página porque tenía el mismo problema. Después de leer este hilo, me di cuenta de que lxc-create no puede escribir en el directorio habitual "/ var / lib / lxc /" si no se ejecuta con sudo.

Miré a mi alrededor y localicé los rootfs para mi contenedor no privilegiado en "~ / .local / share / lxc", y puse las dos líneas en la pregunta en config en ese directorio.

Miré la plantilla que usé, "lxc-download" para obtener una pista, pero creo que esa ruta se pasó cuando se invoca "lxc-download". No he visto cómo el sistema busca contenedores sin privilegios durante el arranque.

lxc n00b
fuente
0

Estoy ejecutando cada contenedor no privilegiado con un mismo usuario nombrado para un mejor aislamiento y así es como lo hago:

#!/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
fuente
-1

Suponiendo (que son la madre de todas las formas de arruinar las cosas), está iniciando sesión como el usuario que "posee" el contenedor lxc sin privilegios, luego el siguiente comando debe abordar lo que está buscando ...

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

Esto simplemente ejecutará el comando anterior cuando inicie sesión a través de bash. Esto también supone que bash es el shell de inicio de sesión. Reemplace el nombre: LXC-CONTAINER-NAMEcon el nombre de su contenedor LXC que le gustaría comenzar.

user249005
fuente
-1

He utilizado un enfoque diferente y está funcionando.

1º Agregar las siguientes entradas en el archivo de configuración del contenedor

CONFIGURACIÓN DE INICIO AUTOMÁTICO

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

2º Crear una relación de confianza entre el usuario del contenedor y él mismo en el mismo servidor

userlxc @ GEST-4: ~ $ ssh-keygen -t rsa Generando pares de claves rsa públicas / privadas. Ingrese el archivo en el que guardará la clave (/home/userlxc/.ssh/id_rsa): ingrese la frase de contraseña (vacía para que no haya frase de contraseña): ingrese la misma frase de contraseña nuevamente: su identificación se ha guardado en /home/userlxc/.ssh/id_rsa. Su clave pública se ha guardado en /home/userlxc/.ssh/id_rsa.pub. La huella digital de la clave es: c9: b4: e1: f3: bf: a3: 25: cc: f8: bc: be: b6: 80: 39: 59: 98 userlxc @ GEST-AMENCIA-4 La imagen del randomart de la clave es: + - [RSA 2048] ---- + | El | El | El | El | o | El | * + | El | ES | El | = * | El | = o =. El | El | . +. +. El | El | oO = oo | + ----------------- +

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

Compruebe la conexión ssh, debe poder usarla sin contraseña userlxc @ GEST-4: ~ $ ssh userlxc @ localhost "lxc-ls --fancy"

NOMBRE ESTADO IPV4 IPV6 AUTOSTART

EXTLXCCONT01 STOPPED - - YES
UBUSER1404USERCONT01-test STOPPED - - NO
UBUSER1404USERLXCCONT01 STOPPED - - NO

3º Crear una entrada crontab en el propietario del contenedor

@reboot ssh userlxc @ localhost "lxc-autostart"

usuario323185
fuente