Comment démarrer automatiquement des conteneurs lxc non privilégiés?

9

Sur Ubuntu 14.04, j'ai créé un conteneur non privilégié que je peux démarrer et arrêter manuellement.

Mais je voudrais que cela démarre et s'arrête avec le système.

J'ai ajouté ce qui suit à la configuration du conteneur: lxc.start.auto = 1 lxc.start.delay = 5

Cependant, les scripts système ne semblent pas choisir de conteneurs non privilégiés.

Il existe un thread lié à cela sur linuxcontainers.org, mais la solution semble être limitée à l' rootutilisateur.

Existe-t-il un moyen propre de le faire pour un utilisateur non root (avec le consentement de l'utilisateur root)?

HRJ
la source

Réponses:

3

Je pense avoir trouvé une meilleure solution que celles actuellement présentées ici. En partie parce que pour autant que je sache, cgmanager est mort, en partie parce que ma solution ne ressemble pas à une solution de contournement hacky, mais surtout parce que cette discussion apparaît toujours lors de la recherche d'une solution au problème. C'est assez simple en fait: utilisez le mode utilisateur systemd .

Accordé si vous n'utilisez pas systemd, cette solution ne va pas vous aider. Dans ce cas, je vous conseillerais de déterminer si votre système init a un moyen d'autoriser les utilisateurs non autorisés à exécuter des services au démarrage et à l'utiliser comme point de départ.

Utilisation du mode utilisateur systemd pour démarrer automatiquement les conteneurs lxc non privilégiés

Je suppose que vous avez des conteneurs lxc non privilégiés qui fonctionnent correctement et que cela fonctionne lxc-autostartcomme l'utilisateur du conteneur fonctionne. Si oui, procédez comme suit:

  1. Créez le fichier ~/.config/systemd/user/lxc-autostart.servicedans la maison de tout utilisateur disposant des conteneurs 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. Alors que cet utilisateur s'exécute:
systemctl --user enable lxc-autostart

(Remarque, l' --useroption indique à systemctl que vous l'utilisez en mode utilisateur. Toutes les choses que je fais normalement avec systemctl, démarrer, arrêter, statuc, activer, etc., fonctionnent avec --user.)

  1. Exécutez ensuite ce qui suit, où $userest le nom de l'utilisateur qui possède les conteneurs lxc:
sudo loginctl enable-linger $user

Ceci est nécessaire pour que systemd démarre une instance d'utilisateur systemd $userau démarrage. Sinon, il n'en démarrerait qu'un au moment de la $userconnexion.

Pour plus d'informations, je recommanderais la page systemlin / timer archlinux wiki et les pages de manuel systemd .

Accès à l'instance systemd d'un utilisateur en tant que root

Vous pouvez réellement démarrer / arrêter / quel que soit le service systemd d'un utilisateur en tant que root, mais cela vous oblige à définir la XDG_RUNTIME_DIRvariable d'environnement. Supposons que $user c'est l'utilisateur dont vous souhaitez accéder à l'instance et $uidson uid, alors voici comment démarrer le lxc-autostart.service défini ci-dessus:

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

Vous pouvez même utiliser systemd-runpour exécuter des commandes arbitraires en tant que cet utilisateur d'une manière qui ne casse pas lxc. J'utilise les commandes suivantes pour arrêter / démarrer mes conteneurs avant / après la sauvegarde, où $nameest le nom du conteneur lxc en cours de sauvegarde:

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

(Notez que sans --waitsystemd-run ne bloque pas tant que le conteneur n'est pas arrêté.)

Wieke
la source
7

Je recommanderais d'utiliser l' @rebootalias pratique dans le cron d' Ubuntu pour fonctionner lxc-autostart.

En tant qu'utilisateur propriétaire du conteneur non privilégié, exécutez crontab -eet ajoutez la ligne suivante:

@reboot lxc-autostart

encodé
la source
Cela sonne bien. Cependant, il ne semble pas y avoir de moyen d'exécuter une commande à l'arrêt (via cron). Des idées?
HRJ
Je ne connais aucun moyen simple d'exécuter un travail à l'arrêt. Vous devrez probablement, en tant que root, ajouter un travail parvenu aux conteneurs d'arrêt pour chaque utilisateur qui en est propriétaire. Vous pouvez rechercher /etc/init/lxc.confdes pointeurs. C'est le travail parvenu qui démarre les conteneurs privilégiés. Il ne devrait pas être trop difficile de le copier et de le modifier pour arrêter également les conteneurs non privilégiés.
codé le
1
Il me semble que, puisque chaque processus dans le conteneur est visible depuis l'hôte, le conteneur n'a probablement pas besoin de quelque chose de spécial pour l'arrêter, chaque processus devrait recevoir le signal TERM de l'hôte. Il y a de fortes chances que vous n'ayez rien à faire de spécial lors de l'arrêt. Si vous souhaitez exécuter certains scripts ou d'autres choses de ce type à l'arrêt, c'est différent, mais la plupart des processus devraient avoir une chance de s'arrêter normalement.
codé le
L'approche crontab fonctionne-t-elle? Sur Ubuntu 14.04, j'obtiens l'erreur "Appel à cgmanager_move_pid_sync a échoué: demande non valide" qui se produit parce que PAM, à savoir libpam-systemd, n'est pas impliqué dans le processus de changement d'utilisateur. Vous pouvez voir /proc/self/cgroupqu'il contient des séquences comme /user/0.user/1.sessionau lieu de/user/1000.user/1.session
Daniel Alder
3

Au cas où quelqu'un tomberait sur ces questions / réponses pour la réponse au démarrage automatique des conteneurs LXC non privilégiés (je reviens certainement beaucoup ici), voici une solution qui fonctionne bien et que j'ai suivie pour la faire fonctionner sur mon serveur:

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

En résumé, cela implique la création de deux scripts, et ils fonctionnent ensemble au démarrage pour permettre à LXC de démarrer les conteneurs non privilégiés de chaque utilisateur répertorié sans avoir à se connecter réellement au compte utilisateur; en d'autres termes, exécuter la commande en tant qu'utilisateur avec toute la magie des CGroups intacte. Conformément aux meilleures pratiques, je vais en citer les os ici, mais cela vaut la peine de lire son article original.

Autoriser notre compte utilisateur à utiliser le pont…

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

Créer un script Upstart… En /etc/init/lxc-unprivileged.confplus…

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

Assurez-vous de remplacer [utilisateur] par votre compte d'utilisateur.

Créez le script de démarrage du conteneur… En /usr/local/bin/startunprivlxc plus…

#!/bin/sh

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

… Et le rendre exécutable…

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

Je voudrais juste souligner qu'il semble fonctionner correctement et en toute sécurité, et ne nécessite pas la racine pour SSH dans les autres comptes d'utilisateurs.

Il y a aussi plus sur le sujet (en abordant les problèmes liés) ici: https://gist.github.com/julianlam/4e2bd91d8dedee21ca6f qui peut être utile pour comprendre pourquoi c'est ainsi.

Kevin Teljeur
la source
2

J'ai écrit un petit script pour contourner le problème, suivez simplement les instructions commentées.

Thiago de Arruda
la source
0

DÉSOLÉ: répondu trop tôt. Cela n'a pas fonctionné même si lxc-ls affiche "AUTOSTART" comme "YES".

Voici un lien avec des informations beaucoup plus utiles, et peut-être que quelqu'un peut en faire usage: http://www.geeklee.co.uk/unprivileged-privileged-containers-ubuntu-14-04-lxc/

J'ai atterri sur cette page car j'avais le même problème. Après avoir lu ce fil, j'ai réalisé que lxc-create ne peut pas écrire dans le répertoire "/ var / lib / lxc /" habituel s'il n'est pas exécuté avec sudo.

J'ai regardé autour de moi et j'ai trouvé les rootfs de mon conteneur non privilégié dans "~ / .local / share / lxc", et j'ai mis les deux lignes de la question en configuration dans ce répertoire.

J'ai regardé le modèle que j'ai utilisé, "lxc-download" pour un indice, mais je pense que ce chemin a été transmis lorsque "lxc-download" est invoqué. Je n'ai pas examiné comment le système recherche les conteneurs non privilégiés lors du démarrage.

lxc n00b
la source
0

j'exécute chaque conteneur non privilégié avec un même utilisateur nommé pour une meilleure isolation et voici comment je le fais:

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

En supposant (qui sont la mère de toutes les façons de gâcher les choses), vous vous connectez en tant qu'utilisateur qui "possède" le conteneur lxc non privilégié, alors la commande suivante devrait répondre à ce que vous recherchez ...

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

Cela exécutera simplement la commande ci-dessus lorsque vous vous connectez via bash. Cela suppose également que bash est le shell de connexion. Veuillez remplacer le nom: LXC-CONTAINER-NAMEpar le nom de votre conteneur LXC que vous souhaitez démarrer.

user249005
la source
-1

J'ai utilisé une approche différente et ça marche

1º Ajoutez les entrées suivantes dans le fichier de configuration du conteneur

CONFIGURATION AUTO START

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

2º Créer une relation de confiance entre l'utilisateur du conteneur et lui-même sur le même serveur

userlxc @ GEST-4: ~ $ ssh-keygen -t rsa Génération d'une paire de clés rsa publique / privée. Entrez le fichier dans lequel enregistrer la clé (/home/userlxc/.ssh/id_rsa): Entrez la phrase secrète (vide pour aucune phrase secrète): Saisissez à nouveau la même phrase secrète: Votre identification a été enregistrée dans /home/userlxc/.ssh/id_rsa. Votre clé publique a été enregistrée dans /home/userlxc/.ssh/id_rsa.pub. L'empreinte digitale de la clé est: c9: b4: e1: f3: bf: a3: 25: cc: f8: bc: be: b6: 80: 39: 59: 98 userlxc @ GEST-AMENCIA-4 L'image aléatoire de la clé est: + - [RSA 2048] ---- + | | | | | o | | * + | | ES | | = * | | = o =. | | . +. +. | | oO = oo | + ----------------- +

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

Vérifiez la connexion ssh, vous devez pouvoir l'utiliser sans mot de passe userlxc @ GEST-4: ~ $ ssh userlxc @ localhost "lxc-ls --fancy"

ÉTAT DE NOM IPV4 IPV6 AUTOSTART

EXTLXCCONT01 ARRÊTÉ - - OUI
UBUSER1404USERCONT01-test ARRÊTÉ - - NON
UBUSER1404USERLXCCONT01 ARRÊTÉ - - NON

3º Créer une entrée crontab chez le propriétaire du conteneur

@reboot ssh userlxc @ localhost "lxc-autostart"

user323185
la source