MaDoVi - Le wiki

Machines - Données - Virtualisation

Outils pour utilisateurs

Outils du site


archives:vm:lxc_app_v2

Virtualisation LXC sur le VHS

A défaut de pouvoir contrôler complètement − en tous les cas sans risque − les logiciels et outils du NAS VHS;
à défaut en particulier de pouvoir ajouter ou mettre à jour, toujours sans risque pour le fonctionnement prévu du serveur, les programmes qui ne sont pas présents sur le NAS ou sont obsolètes et qui nous intéressent;
on se donne pour objectif ici de faire du VHS un «serveur d'applications», en s'appuyant sur les Containers LXC.

… Merci aux copains du forum, qui m'ont permis … d' «enquêter» … ;-)


Avis tout personnel: Ça vaut franchement le coût de s'investir sur ces manipulations avec LXC ! En particulier, çà vaut le coût sur les modèles de NAS dont le processeur ne supporte pas les instructions de virtualisation (pas de VM).
Ne vous laissez pas rebuter par la longueur du texte ci-dessous et les aspects qui paraissent peut-être parfois un chouia techniques, voire «velus»…


L'idée qu'on garde en tête le long de ce «tuto» est de ne pas toucher − tant que faire se peut − à la configuration native du serveur VHS, y compris en matière de réseau et de règles sur le pare-feu.

En dehors du fait qu'elles seront perdues à chaque installation ou mise à jour du firmware, de telles modifications pourraient induire des comportements indésirables et/ou introduire des failles de sécurité (pas assez calé pour en juger) …

Les opérations proposées ici sont réalisées sur un VHS avec firmware en version de 6.1.3.

L'ensemble du code utilisé est emballé et à disposition dans ce tuto, mais tout à la fin quand même, faut tout lire d'abord 1)

NB: N'espérez pas mettre en œuvre dans le contexte présenté ici des applications pour Windows ou MacOS …. Les outils utilisés s'appuient sur le noyau système du VHS et seules des applications GNU/Linux peuvent être envisagées ! (quoique - avec Wine pour Windows ?)

Suggestion: Vous faire les dents dans une VM sur le NAS (pour ceusse qui peuvent) – VM Ubuntu serveur prédéfinie (idem VHS) + installation LXC – est probablement une bonne idée 8-)


1. Contexte

Les cas sont rares (voire inexistant) de programmes disponibles pour une distribution GNU/Linux et pas sur une autre. Lorsque c'est le cas, on peut en principe s'en sortir à partir des codes sources et en recompilant… ce n'est pas toujours facile ! Dans ce cas, l'installation sur la distribution dont on dispose est au minimum … «problématique».
Par ailleurs, indépendamment des distributions, certaines applications pourraient avoir du mal à cohabiter, par exemple avec des versions différentes d'une même bibliothèque (cf. ce post écrit par Epy sur le forum).

Sur notre NAS il n'est bien entendu pas question de prendre de tels risques, celui de faire cohabiter comme celui de compiler …8-O À moins d'être joueur et/ou d'avoir du temps…

L'idéal reste donc d'isoler les applications en les faisant s'exécuter chacune dans leur propre environnement (y compris la distribution), dédié et indépendant de l'application d'à côté, et surtout de la machine hôte – le VHS en l’occurrence ici – sur laquelle elles tournent avec des fonctionnalités éventuellement incompatibles. Pour faire cela, on a au moins trois options:

  • Les machines virtuelles;
  • Les containers Docker;
  • Les containers Linux (LXC) auxquels on s'intéresse ici.

  • Docker parait bien convenir pour des applications (même s'il est quand même orienté vers les développeurs en intégrant des outils de build et de déploiement). Il est très à la mode à l'heure de ces lignes; par conséquent il existe une foultitude d'aides, de tutoriels, d'images Docker disponibles sur la toile. Mais il n'est pas installé sur le VHS… donc risque !
  • Les Machines Virtuelles sont bien sûr possibles: elles existent pour les serveurs dont le processeur supporte les instructions nécessaires (donc pas tous). Ces VM émulent complètement une machine − matériel et OS − et elles consomment ainsi pas mal de ressources.
  • Enfin, les LXC (Linux Containers), semblent un bon compromis entre Docker (qui en hérite dans ses principes d'isolation) et les VM. LXC est moins lourd que ces dernières, car il partage d'avantage de ressources de son hôte, en particulier le noyau Linux. Du fait même de ce partage, les containers LXC sont nécessairement du Linux, contrairement aux VM (machine Windows hébergée sur un hôte Linux par exemple).


Le gros avantage, c'est que LXC est nativement installé sur le VHS ! Et que donc même les serveurs sans support des VM peuvent le faire tourner … c'est vrai puisque LXC est utilisé dans le processus d'installation des serveurs − dixit le support Ve-Hotech !!

La version LXC installée est la 1.0.7 donnée par la commande suivante en ssh:

admin@sesame:~$ dpkg-query -l | grep lxc
ii liblxc1       1.0.7-0ubuntu0.1 amd64 Linux Containers userspace tools (library)
ii lxc           1.0.7-0ubuntu0.1 amd64 Linux Containers userspace tools
ii lxc-templates 1.0.7-0ubuntu0.1 amd64 Linux Containers userspace tools (templates)
ii python3-lxc   1.0.7-0ubuntu0.1 amd64 Linux Containers userspace tools (Python 3.x bindings)
admin@sesame:~$ 

Sachant qu'a priori, la dernière version stable semble être la 1.0.10 pour la distribution Ubuntu Trusty du VHS…

Z'ont vu loin chez Ve-Hotech, même si apparemment ils ne sont pas allés au bout… et/ou n'ont pas communiqué…

On propose ici de faire s'exécuter des applications dans des containers LXC sur le VHS…
Et donc, par le principe même du fonctionnement, sans risque pour lui !


2. Objectifs

Faisons un peu de …heu … «d'architecture», applicative et réseau… pffff m( !

Les services qu'on veut proposer et positionner dans des containers LXC pourront être de toutes natures; on peut peut-être les classer en trois «catégories» ou «types» :?: :

  1. des applications serveur pilotées en lignes de commandes: un serveur de base de données, un serveur VPN, des scripts de sauvegarde… par exemple;
  2. des services en mode web qui ne sont pas déployables simplement sur le VHS − à cause notamment de contraintes diverses sur le NAS: versions PHP ou MySQL insuffisantes, configuration Apache incompatible, etc…
  3. ou bien encore des applications plus lourdes, en mode bureau avec IHM graphique.

La façon d'atteindre ces services «containérisés» sur le VHS est :

  • soit «locale» à partir d'une connexion ssh sur le NAS et la console du container (c'est évidement un peu limité :-O ): ce moyen est plutôt destiné à l'administration des containers.
  • soit distante depuis un client connecté au réseau et raccordé au NAS: ordinateur, tablette, mobile… Là, c'est effectivement pour l'usage réel des services.

Il va falloir exploiter une structure et des protocoles réseaux pour atteindre chacun de ces containers et les services qu'ils hébergent, et les «exposer» sur le LAN.

Mais on n'est pas obligé d'exposer tous les containers – mieux vaut même en exposer le moins possible ! Par exemple, la structure du réseau dans le cadre des containers LXC pourrait correspondre au schéma suivant:

  • Les services exposés le sont «publiquement» sur le réseau LAN - et donc au-delà possiblement
  • Les services isolés ne sont visibles que sur leur sous-réseau LXC
  • Les services exposés et isolés se «connaissent» entre eux via le sous-réseau des containers LXC
  • Par exemples:
    • le service #1 fait tourner Guacamole et expose le seul port 8080 (c'est du Tomcat) vis à vis des navigateurs web sur le LAN; en revanche il accède aux services #2 et #5, via le bridge, sur les ports VNC ou RDP que ces services ouvrent.
    • Pareil pour le service #3 (Ngnix / Php) qui expose HTTP / HTTPS (80 et 443) sur le LAN et peut accéder au service #4, container MariaDB qui n'expose que le port 3306 sur le sous-réseau en 10.0.3.x des containers LXC…

On va tenter ici de se doter d'outils de génération et de configuration d'un «réseau de containers LXC», afin d'en rendre la définition et l'usage les plus souples possibles dans le cadre de notre NAS… (vaste programme, et sans doute jamais vraiment fini …)

On va se limiter à quelques exemples dans le cadre de ce wiki, à titre de cas pratiques:

  • un container de catégorie #1 lxc-term: C'est une VM en mode serveur / console; on y installera MariaDB en particulier;
  • un container de type #2 lxc-web: Serveur HTTP Ngnix / Php avec des sites: Adminer, Nextcloud, … (qui vont exploiter lxc-term/MariaDB);
  • un container de type #3 lxc-gui: Un container “bureau” pour héberger des applications graphiques (JDownloader, MySQL-Workbench, …);

… et on aura alors − a priori − balayé et illustré pas mal de cas d'usage …


3. Considérations préalables

Avant de commencer la mise en œuvre de nos containers, ci-dessous quelques points d'attention et de configuration.

Un script est proposé au § Outillage, qui va permettre de configurer le NAS en intégrant ces éléments.


3.1. A propos ... de la sécurité

Il existe deux types de containers: les «privilégiés» et les «non-privilégiés». C'est un peu velu pour moi… mais en gros, dans un container «privilégié», un pirate qui s'y introduirait pourrait avoir accès à une ressource de l'hôte via des processus système du container et pourrait ainsi potentiellement échapper au container et passer pour root sur l'hôte…

Il est possible depuis la version 1.0 de LXC, de faire s'exécuter un container complètement en tant qu'un utilisateur banalisé (et non plus par le compte root de l'hôte) grâce à la gestion des espaces de noms utilisateurs. Dans un tel container, dit «non-privilégié», les droits d'un éventuel pirate seraient au maximum ceux de l'utilisateur, il resterait ainsi «confiné» dans le container.
Dans la mesure où il peut y avoir de tout et n'importe quoi comme application dans les containers, le mode «non-privilégiés» est naturellement à … privilégier !

FIXME Néanmoins j'arrive pô à faire démarrer un container «non-privilégié», même dans une VM où j'ai complètement la main… FIXME

Par conséquent, dans les manipulations proposées ici, on ne réalise pour l'instant que des containers «privilégiés», exécutés avec des droits root donc…

Et en l'état, la mise en garde s'impose donc selon la formule consacrée:

Attention les manipulations proposées ici seront réalisées, si vous vous lancez, à vos «risques et périls».

Le risque − bien relatif quand même − parait plus grand pour vos données si votre NAS est en DMZ. :!:

En même temps, j'l'aurais quand même faite cette mise en garde, même avec des containers «non-privilégiés» opérationnels ;-)


3.2. ... Des répertoires...

LXC manipule et «vit» dans des répertoires localisés par défaut sur la partition système du NAS qui ne dispose pas d'un espace important et qui est écrasée et réinitialisée à la mise à jour ou la réinstallation du système (voire même au reboot pour certain éléments de configuration). Au moins deux de ces dossiers sont concernés, qu'il va falloir faire pointer vers une zone de stockage plus appropriée sur le NAS.

En synthèse, le mode opératoire est le suivant:

  • Un container exploite le noyau Linux de son hôte; il s'appuie quand même sur une distribution GNU/Linux lorsqu'on le construit. On peut avoir une distribution Debian, Ubuntu, Arche-Linux, etc… dans une de ses versions / variantes compatibles avec le noyau de l'hôte. Le choix de la distribution est fait lors de la création du container, en indiquant le modèle ou template utilisé (ici choix d'une Debian):
      sudo lxc-create -n MonContainer -t debian

    Le modèle est en fait un script shell exécuté;

  • Le container est créé dans un répertoire, et son image de base qui a servi à sa construction est mise dans un cache, en prévision d'un autre container créé sur la même image; l'utilisation du cache (qui a une «durée de vie») permettra d'éviter de reconstruire depuis zéro et de télécharger inutilement les composants.

Les répertoires utilisés souvent par LXC et où il stocke ses fichiers sont, hélas, tous localisés par défaut sur la partition système – limitée en taille, donc:

  • /var/lib/lxc: emplacement des containers
  • /var/lib/lxcsnap: emplacement des instantanés (snapshots)
  • /var/cache/lxc: emplacement du cache des images de containers
  • /usr/share/lxc/templates: emplacement des modèles de containers (template)

Pour … plus tard, et pour information (mais ces chemins-là ne devraient pas poser de souci, le $HOME des comptes du VHS étant définis selon: /mnt/data/data/users/<compte>):

  • $HOME/.local/share/lxc: emplacement des containers «non-privilégiés»
  • $HOME/.local/share/lxcsnap: emplacement des instantanés «non-privilégiés» (unprivileged snapshots)
  • $HOME/.cache/lxc: emplacement du cache des images «non-privilégiés»

Il faut donc qu'on se définisse, pour les containers privilégiés, un emplacement dédié sur le serveur pour accueillir tout çà (sous /mnt/data/…/admin/… par exemple).

☛ Script dans § 4. Outillage


3.3. ... Des templates ...

Les templates (localisés dans /usr/share/lxc/templates/ donc) définissent la configuration et les paquets installés par défaut de la distribution choisie. Ces templates ont été installés sur le NAS avec l'installation du produit LXC (donc, ça date…). Mais il existe un template download qui propose des images de systèmes téléchargées depuis un serveur linuxcontainer sur le web, a priori plus «fraîches» et actualisées et le choix parait plus riche.

Dans nos manipulations ici, on propose aussi bien de l'ubuntu que du debian en templates locaux et download, selon les cas:

  • Le template lxc-ubuntu est … «une grosse vache» ;-) avec un certain nombre de paquets dont on n'a pas forcément besoin (serveur ssh par exemple, pas toujours utile)
  • Le template lxc-debian est plus léger… voire creux !
  • Le template lx-download semble être un compromis

⇒ Il faudrait pointer exactement les contenus de chacun…

En revanche, les scripts des modèles utilisent les répertoires par défaut. On va donc devoir revoir les contenus de ces trois modèles et modifier les chemins pour les faire pointer sur les disques au lieu de la partition système (un RAID md0 dédié en réalité).

Si vous souhaitez utiliser d'autres modèles qu'un de ces trois-là, modifiez-les, sous peine de saturer la zone système !

☛ Script dans § 4. Outillage


3.4. ... Et du réseau

3.4.1. Configuration

Les containers LXC sont donc prévus pour fonctionner avec – aussi – une «isolation réseau» (en plus de celle des processus): il existe un pont qui définit un sous-réseau dédié aux containers (en 10.0.3.* sur le VHS, nommé lxcbr0). Un dispositif serveur DNS/DHCP (avec dnsmasq) est fourni avec LXC, permettant d'attribuer noms et adresses IP aux containers sur ce sous-réseau.

A l'instar d'un routeur ou d'une box, lorsqu'un container est démarré, une adresse lui est attribuée dynamiquement par ce serveur dnsmasq. Et comme un routeur également, on peut fixer l'adresse de façon systématique. D'autre part, on peut donner un nom a chaque container, pour pouvoir l'adresser de cette façon plutôt que par une adresse IP qu'on mémorise moins bien… enfin, pour ce qui me concerne !

Pour répondre au schéma présenté plus haut, on propose une configuration de ce dispositif afin de l'adapter au VHS et à nos besoins.

Le fichier de configuration est là: /etc/defaut/lxc-net. Deux lignes sont à dé-commenter/adapter:

  • La première consiste à donner un chemin vers un fichier de configuration des noms et adresses des containers: #LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf. On propose un contenu pour ce fichier (c'est facultatif, çà fonctionne sans en laissant la ligne en commentaire).
  • La seconde permet d'activer le domaine «lxc»: #LXC_DOMAIN=“lxc”

Lorsque vous touchez à cette configuration, un arrêt / relance du service est nécessaire pour la prendre en compte :

sudo stop lxc-net 
sudo start lxc-net 

FIXME Mon problème actuel est de démarrer cela au boot du VHS. En effet, d'après ce que je comprends: Si je passe les commandes ci-dessous après le démarrage du serveur, je n'ai pas de route définie sur le bridge lxcbr0 dédié aux containers:

  • je regarde si mon bridge lxcbr0 est défini (c'est le cas):
    NAS
    admin@wsesame:~$ brctl show
    bridge name	bridge id		STP enabled	interfaces
    br0		8000.00e0666e2175	no		bond0
    lxcbr0		8000.000000000000	no		
    virbr0		8000.000000000000	yes		
    admin@sesame:~$ 
  • Je regarde si ce pont entre dans la définition d'une route (ce n'est pas le cas):
    NAS
    admin@sesame:~$ sudo route -n
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         192.168.1.1     0.0.0.0         UG    100    0        0 br0
    192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 br0
    192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0
    admin@sesame:~$ 
  • S'il n'y a pas de route, les containers ne «sortent» pas et restent confinés: pas de ping, pas de apt-get update, etc…
  • En revanche, après l'activation de lxc-net, il me créé bien une route et les containers ont accès au net:
    NAS
    admin@sesame:~$ sudo stop lxc-net
    lxc-net stop/waiting
    admin@sesame:~$ sudo start lxc-net
    lxc-net start/running
    admin@sesame:~$ sudo route -n
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         192.168.1.1     0.0.0.0         UG    100    0        0 br0
    10.0.3.0        0.0.0.0         255.255.255.0   U     0      0        0 lxcbr0
    192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 br0
    192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0
    admin@sesame:~$ 

J'en déduis que la phase d'init. des processus au boot (et les définitions réseau) font qu'il manque quelque chose qui empêche de démarrer correctement la partie LXC. La solution ? : Ben lancer les commandes stop/start lxc-net systématiquement après un redémarrage. Moi, çà m'embête pas plus que çà (je redémarre rarement le serveur), mais faut que je trouve à régler ça… Un expert réseau / init., dont le processus est «maison» sur le VHS ?

On a cependant un bridge en 192.168.122. qui, lui, est bien là au démarrage… A exploiter ? FIXME


☛ Script dans § 4. Outillage


3.4.2. Exposition

les règles iptables du VHS prévoient bien par défaut l'utilisation du pont réseau LXC :

NAS
admin@sesame:~$ sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE
-A POSTROUTING -s 10.0.3.0/24 ! -d 10.0.3.0/24 -j MASQUERADE
admin@sesame:~$ 

La dernière ligne autorise le «POSTROUTING» sur l'ensemble des adresses LXC: des «machines» avec des adresses en 10.0.3.x peuvent sortir sur le réseau. Ceci permet la création des containers et l'installation d'applications téléchargées via Internet à partir de ces containers.

Il faut que l'hôte autorise l' ip_forward et c'est le cas:

NAS
admin@sesame:~$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
admin@sesame:~$ 

En revanche, rien sur le «PREROUTING»: les façons de router les flux à destination des containers n'existent pas (ce qui est bien normal: çà ne s'invente pas, çà ne peut pas être prédéfini :-) ).

FIXME Le problème ici n'est pas tant de définir ces règles, que de les … conserver: elles ne résistent pas au reboot ! … Ou alors, j'ai raté un truc … FIXME

Donc on va s’outiller pour le faire (☛ Script dans § 4. Outillage) à l'aide des commandes suivantes: la valeur de <portHost> est évidemment un port libre sur le NAS…

Ouvrir l'accès:

sudo iptables -t nat -**A** PREROUTING -p tcp -i **<interface>** --dport **<portHost>** -j DNAT --to-destination **<@IP:Port Destination>**

Exemple pour ssh dans un container:

sudo iptables -t nat -A PREROUTING -p tcp -i br0 --dport 65022 -j DNAT --to-destination 10.0.3.11:22

Ceci fait, un accès ssh depuis n'importe qu'il poste du LAN sera ouvert via la commande suivante (ou son équivalent PuTTy depuis un poste sous Windows):

$ ssh <usr>@<nom du VHS ou son @IP> -p 65022

Fermer l'accès: Remplacer A (Append) par D (Delete)
Exemple:

sudo iptables -t nat -D PREROUTING -p tcp -i br0 --dport 65022 -j DNAT --to-destination 10.0.3.11:22

Remarque: On a une autre option, mais qui fait perdre tout son intérêt à l'isolation réseau du container. On peut en effet choisir de «court-circuiter» le sous-réseau LXC : on «raccroche» les containers à l'interface réseau du VHS (br0 au lieu de lxcbr0) en modifiant le fichier de configuration du container. Et du coup, comme pour les machines virtuelles du NAS ou n'importe quelle machine sur le réseau local, le container va chercher son adresse sur la box / le routeur… Les containers sont alors des machines comme les autres, atteignables et exposées comme les autres. Du fait que les containers sont sur le NAS – composant sensible s'il en est – et qu'en plus ils fonctionnent (pour l'instant) en mode «privilégié», ce n'est sans doute pas pertinent d'ouvrir comme çà sur le réseau. Et «en même temps»… ça ne semble pas pire qu'une VM !


4. Outillage

Ci-dessous, on propose un ensemble de scripts (shell ou python) qui vont nous permettre:

  1. de configurer le VHS afin de faciliter la création et l'exécution des containers sans risque de remplir prématurément l'espace système
  2. de créer des containers sur telle ou telle distribution, avec des packages prédéfinis selon ce que l'on veut en faire
  3. de gérer les containers: les lancer, les arrêter, les exposer ou non sur le réseau…

4.1. Configurations

On a vu plus haut dans les «considérations préalables» 3 thèmes : les espaces de stockage des containers, les modèles ou template et le cache des images LXC, et enfin la configuration du réseau des containers.

Thème #1: Dans un premier temps, il faut remplacer la destination par défaut des containers et les localiser sur l'espace de stockage du NAS. Deux options, qui ne s'excluent pas mutuellement :

  1. utiliser systématiquement dans les commandes lxc-xxx le paramètre -P <chemin sur le NAS>
  2. définir le chemin une fois pour toutes en créant un fichier /etc/lxc/lxc.conf avec:
    lxc.lxcpath=<chemin sur le NAS>. Le problème de cette option: elle est perdue à la mise à jour du firmware…

Thème #2: A la création d'un container, les scripts des templates consultent le chemin du cache des images LXC. Si l'image à créer existe déjà, elle est exploitée, sinon l'image est téléchargée et y est stockée (en gros et pour faire court). Le chemin de cache est codé «en dur» dans les scripts des templates; il faut donc aussi modifier les templates et utiliser un répertoire de cache dans la zone de stockage du NAS.

Thème #3: La configuration du serveur dnsmasq pour gérer le réseau de containers est assez simple: activation du domaine lxc et, pour la partie DHCP qui reste optionnelle, donner des adresses «fixes» – i.e. attribuées dynamiquement, mais toujours les mêmes – aux machines LXC. Les plages d'adresses indiquées dans le script ci-dessous sont juste un choix … Mais là encore, la config. est définie dans la zone système, elle sera perdue à la mise à jour (ou la réinstallation) du firmware.

4.1.1. Définition

Le script ci-dessous propose de couvrir ces trois thèmes; il y ajoute la définition des variables d'environnement utiles (fichier .profile). Vous pouvez bien sûr l'adapter à vos propres choix…

Par ailleurs, suite aux constats de pertes liées à une réinstallation ou à une mise à jour, ce script peut simplement être rejouer pour «retrouver vos petits»…

Selon votre version de l'os VHT ou l'organisation de votre espace de stockage (JBOD par exemple), il est possible que le montage de cet espace sur les disques ne permette pas l'exécution de scripts (monté en mode noexec). Si c'est le cas, voir ce post sur le forum, qui permet de faire un montage avec possibilité d'exécution … Çà parle de plex, mais çà marche ici aussi !

Vous pouvez retrouver ce script shell de configuration en annexe.

lxc_set-env.sh
#!/bin/bash
# --------------------------------------------------------------------------- #
# --------------------------------------------------------------------------- #
# Script de configuration d'un environnement "container LXC" sur le VHS       #
# --------------------------------------------------------------------------- #
# L'outil lxc est installé par défaut sur le VHS - à partir de la v 6.0.0 au  #
# moins du firmware. Un certain nombre de répertoire par défaut sont modifiés #
# afin de ne pas solliciter la clé système: fragilité et espace "faibles" sur #
# cette clé usb interne...                                                    #
# Script à lancer en 'root' avec sudo.                                        #
# --------------------------------------------------------------------------- #
# Date        Vers  Commentaires                                              #
# --------------------------------------------------------------------------- #
# 2017.03.24  1.0   Version initiale                                          #
# 2017.04.01  1.1   Modif template 'lxc-ubuntu' & 'lxc-debian'                #
# 2017.04.02  1.2   Template 'lxc-download' + Rep tmp (était sur la clé..)    #
# 2017.08.25  1.3   Un environnement / répertoire unique sous admin/prive     #
# 2018.01.04  1.4   Il restait un dossier temporaire sur la clé (ajout #110)  #
# --------------------------------------------------------------------------- #
# --------------------------------------------------------------------------- #
readonly VERSION='1.4'
readonly RAZ="\e[m"
readonly BLEUFONCE="\033[1;34m"
readonly VERT="\033[0;32m"
readonly ROUGE="\033[1;31m"
readonly DateMaJ=$(date +'%Y-%m-%d - %H:%M:%S')
 
# on doit être 'root'
if [ "$(id -u)" != "0" ]; then
  echo -e "Vous devez avoir des privilèges ${ROUGE}root${RAZ} pour exécuter ce script."
  echo -e "Ainsi, lancez le script avec: ${VERT}sudo $0 ${RAZ}"
  exit 1
fi
 
# --------------------------------------------------------------------------- #
# Définitions des répertoires 
# --------------------------------------------------------------------------- #
# - Sur le VHS, on utilise le compte 'admin' dont le $HOME vaut '/mnt/data/data/users/admin'.
# - Adaptez les chemins à ce que vous voulez faire si vous avez besoin d'en changer.
# Arborescence proposée par défaut:
#  $HOME/prive/envlxc           => Dossier de base.
#  $HOME/prive/envlxc/lxc       => Dossiers des containers définis:
#     . Un répertoire par container créé avec la commande lxc-creat 
#     . avec le fichier de config. et le systeme de fichier rootfs du container.
#  $HOME/prive/envlxc/lxcsnap   => Dossiers des instantanés (snapshot) des containers: 
#     . un répertoire numéroté par instantané de container. Créé direct par la commande lxc-snapshot
#  $HOME/prive/envlxc/cache     => Dossier du cache, un répertoire (ou une arborescence...) par 'image'.
#  $HOME/prive/envlxc/templates => Dossier des modèle de container (contenu adapté au VHS).
#  $HOME/prive/envlxc/tools     => Dossier avec un ensemble de scripts de gestion des containers
#  $HOME/prive/envlxc/tmp       => Dossier temporaire pour travailler... 
# --------------------------------------------------------------------------- #
readonly LXCBase="$HOME/prive/envlxc"
readonly LXCPath="$LXCBase/lxc"
readonly LXCCache="$LXCBase/cache"
readonly LXCTemplates="$LXCBase/templates"
readonly LXCTools="$LXCBase/tools"
readonly LXCTemp="$LXCBase/tmp"
 
# --------------------------------------------------------------------------- #
# Création des différents dossiers, s'ils n'existent pas
# --------------------------------------------------------------------------- #
if [ ! -e "$LXCBase" ] ; then 
	mkdir -p $LXCBase 
fi
if [ ! -e "$LXCPath" ] ; then 
	mkdir -p $LXCPath 
fi
if [ ! -e "$LXCCache" ] ; then 
	mkdir -p $LXCCache 
fi
if [ ! -e "$LXCTemplates" ] ; then 
	mkdir -p $LXCTemplates 
fi
if [ ! -e "$LXCTools" ] ; then 
	mkdir -p $LXCTools 
fi
if [ ! -e "$LXCTemp" ] ; then 
	mkdir -p $LXCTemp 
fi
 
# --------------------------------------------------------------------------- #
# Fixer la configuration du chemin des containers
# --------------------------------------------------------------------------- #
cat > /etc/lxc/lxc.conf <<FINISH
# $DateMaJ - Fixer le chemin des containers LXC sur l espace du NAS
lxc.lxcpath=$LXCPath
FINISH
 
# --------------------------------------------------------------------------- #
# On copie les modèles/template existant par défaut dans le répertoire cible
# --------------------------------------------------------------------------- #
cp -p /usr/share/lxc/templates/* $LXCTemplates/
 
# On donne les droits qui vont bien sur l'arborescence complète
chmod +x -R $LXCBase
# on laisse l'utilisateur admin manipuler les outils...
#chown admin:users $LXCTools
chown admin:users $LXCTools
 
# --------------------------------------------------------------------------- #
# On modifie 3 modèles/template dans leurs chemins "en dur" du cache + rep tmp
# --------------------------------------------------------------------------- #
# Modif du template ubuntu:   chgt du chemin du cache
sed -i "s|cache=\"\$LOCALSTATEDIR/cache/lxc/\$release\"|cache=\"${LXCCache}/\$release\"|g" $LXCTemplates/lxc-ubuntu
# Modif du template debian:   chgt du chemin du cache
sed -i "s|cache=\"\$LOCALSTATEDIR/cache/lxc/debian\"|cache=\"${LXCCache}/debian\"|g" $LXCTemplates/lxc-debian
# Modif du template download: chgt du chemin du cache et répertoire temporaire
sed -i "s|LXC_CACHE_BASE=\"\$LOCALSTATEDIR/cache/lxc/\"|LXC_CACHE_BASE=\"${LXCCache}/\"|g" $LXCTemplates/lxc-download
sed -i "s|DOWNLOAD_TEMP=/tmp/lxc-download.|DOWNLOAD_TEMP=${LXCTemp}/lxc-download.|g" $LXCTemplates/lxc-download
sed -i "s|DOWNLOAD_TEMP=\$(mktemp -d)|DOWNLOAD_TEMP=\$(mktemp -d --tmpdir=${LXCTemp})|g" $LXCTemplates/lxc-download
# Modif du template xxxxxxxx: chgt du chemin du cache
# à vous de jouer ...
 
# --------------------------------------------------------------------------- #
# Config réseau du "serveur dnsmasq" dédié aux containers LXC
# --------------------------------------------------------------------------- #
# On garde l'original...
cp /etc/default/lxc-net /etc/default/lxc-net.original
# Autoriser les container à se reconnaitre entre eux par leur petit nom...
sed -i "s|^#LXC_DOMAIN=\"lxc\"|LXC_DOMAIN=\"lxc\"|g" /etc/default/lxc-net
# Activier le fichier de config dns ...
sed -i "s|^#LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf|LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf|g" /etc/default/lxc-net
# ... et le créer/définir
cat > /etc/lxc/dnsmasq.conf <<FINISH
# $DateMaJ - Fixer les adresses des containers LXC - CECI N EST QU UNE CONVENTION ...
server=/lxc/10.0.3.1
 
# cid 11 -> 100: containers term
dhcp-host=lxc-term01,10.0.3.11
dhcp-host=lxc-term02,10.0.3.12
dhcp-host=lxc-term03,10.0.3.13
 
# cid 101 -> 200: containers web
dhcp-host=lxc-web01,10.0.3.101
dhcp-host=lxc-web02,10.0.3.102
dhcp-host=lxc-web03,10.0.3.103
 
# cide 201 -> 253; containers gui
dhcp-host=lxc-gui01,10.0.3.201
dhcp-host=lxc-gui02,10.0.3.202
dhcp-host=lxc-gui03,10.0.3.203
 
FINISH
 
# prise en compte par arrêt/relance du service réseau lxc
stop lxc-net 
start lxc-net 
 
# --------------------------------------------------------------------------- #
# On créé les variables d'environnement associées au compte courant...
# Simple confort pour les commandes 'lxc-xxx', ou le tools dans le path
# Vous pouvez virer ...!
# --------------------------------------------------------------------------- #
cat >> $HOME/.profile <<FINISH
# $DateMaJ - Ajout chemins LXC et templates
export LXCBase=${LXCBase}
export LXCPath=${LXCPath}
export LXCTemplates=${LXCTemplates}
export LXCCache=${LXCCache}
export LXCTools=${LXCTools}
export LXCTemp=${LXCTemp}
 
FINISH
 
echo -e "logout/login nécessaire pour prise en compte..."
exit

4.1.2. Mode opératoire

  • Copier ce script sur le VHS, dans un dossier à votre convenance
  • Le rendre exécutable avec chmod +x lxc_set-env.sh
  • L'exécuter via sudo ./lxc_set-env.sh

4.1.2. Vérification

Pour s'assurer que çà fonctionne:

  • Vérifier que le chemin des containers est bien pris en compte – i.e. qu'ils n'iront pas dans la zone système – en passant la commande suivante (doit donner un résultat, le fichier existe, son contenu est défini):
    sudo cat /etc/lxc/lxc.conf
  • Créer un container:
    sudo lxc-create -n lxc-web02 -t $LXCTemplates/lxc-download -- -d ubuntu -r trusty -a amd64
  • Vérifier que rien n'est ajouté dans la zone système dans les répertoires «standards» avec les commandes:
    • sudo ls /var/lib/lxc/
    • sudo ls /var/cache/lxc
  • Vérifier au contraire que vous avez quelque chose dans les dossiers dédiés:
    • ls $LXCPath
    • ls $LXCCache
  • Lancer le container et vérifier qu'il a l'adresse configurée (10.0.3.102 ici pour un container nommé lxc-web02):
    • sudo lxc-start -n lxc-web02 -d
    • sudo lxc-ls -f
      NAME       STATE    IPV4        IPV6  AUTOSTART  
      -----------------------------------------------
      lxc-web02  RUNNING  10.0.3.102  -     NO         
    • Si vous n'avez pas cette adresse en 10.0.3.102, vous pouvez tenter:
      • un arrêt du container via sudo lxc-stop -n lxc-web02
      • un arrêt/relance de lxc-net via sudo stop lxc-net puis sudo start lxc-net sur le VHS,
      • une relance du container et vérifier…
        • sudo lxc-start -n lxc-web02 -d
        • sudo lxc-ls -f
  • Quand tout est bon, vous pouvez arrêter et supprimer ce container de test (il est là juste pour vérifier son adresse, on fera un autre du même nom plus tard):
    • sudo lxc-stop -n lxc-web02
    • sudo lxc-destroy -n lxc-web02

Si les premières vérifications échouent – les containers sont stockés dans la zone réduite du système – il ne faut pas aller plus loin et d'abord régler le problème …

Si vous êtes arrivés ici avec succès, le reste n'est que … «bavardage» =).
En effet, avec la doc. sous le bras, vous pouvez maintenant sans risque créer vos différents containers: ce sont des VM de base – certes un peu dépouillées, mais c'est le but – que vous pouvez enrichir comme n'importe quel système GNU/Linux en y installant ce que vous voulez.

Passer à la suite, c'est juste pour illustrer, faire des T.P. et peut-être donner quelques idées… ? et pour moi m'exercer aux Scripts Bash et Python…;-)


4.2. Outils de création

L'environnement LXC dont dispose notre NAS VHS se suffit à lui-même: il «vient» avec un ensemble d'outils nécessaires et suffisants pour manipuler les containers (cf. les pages man).

Néanmoins, ce à quoi on destine un container va conditionner son contenu et souvent, le contenu initial à la construction sera le même entre deux containers de même nature.

D'où l'intérêt de faire des constructions génériques, et si on reprend les trois catégories évoquées plus haut:

  • des éléments seront communs à tous les types de containers: un compte, avec privilèges (sudo), un choix de langue, de fuseau horaire, etc…
  • pour les containers de type lxc-term: un serveur ssh, des outils réseau, …
  • les types lxc-web hébergeront un serveur web, du php, …
  • les containers de la catégorie lxc-gui contiendront un système graphique, un serveur VNC…

On propose ici un script qui permet de constituer rapidement des containers pré-configurés et dédiés selon ces trois catégories (+une vide, c'est à dire sans rien ajouter au modèle choisi).

  • On fabrique çà en Python (le langage Python est disponible sur le VHS dans ses versions 2.7.6 et 3.4.0);
  • On utilise l'outil whiptail – via une bibliothèque – qui permet une interface un peu plus ergonomique et conviviale que la simple console;
  • On se limite aux distributions debian et ubuntu, on ne s'occupe pas des autres (passekeu je connais pas…) Attention à adapter les templates pour ceux qui veulent s'y aventurer !;
  • On crée les containers en installant les paquets définis selon le type de container;
  • On adapte des petits trucs… genre changer les système d'init. - virer systemd … (cf. Annexes A.2);
  • j'ai pas tiré dans tous les coins, sûrement des bugs On se réserve le droit de l'améliorer :-x … ;
  • 1ière évolution envisagée: paramètres de lancement (un par question: le principe d'un script étant de pouvoir être lancé par un autre, sans intervention…);
  • Autre évolution: gestion des packages pré-installés un peu plus évoluée…

Le fichier s'appelle lxc_define.py; il est disponible dans le paquet des sources en annexe; il est destiné au répertoire $LXCTools défini par le script de configuration joué juste avant…

Depuis une console ssh sur le NAS:

  • Si sa propriété «exécutable» s'est perdue en chemin, faire :
    chmod u+x $LXCTools/lxc_define.py
  • Lancer avec:
    sudo -E $LXCTools/lxc_define.py
  • Les écrans me semblent explicites et le code est commenté…
  • … et remarques, suggestions, corrections et améliorations attendues !

Remarque: si le fond violet/fuchsia utilisé – c'est la faute à ubuntu, couleur par défaut – vous pique les yeux, tapez:

sudo ln -sf /etc/newt/palette.original  /etc/alternatives/newt-palette

Pour y revenir (mais la modif. ne tient pas non plus le reset apparemment):

sudo ln -sf /etc/newt/palette.ubuntu  /etc/alternatives/newt-palette

4.3. Outil d'exploitation

Cet outil propose, parmi les containers définis, de pouvoir les lancer/stopper, lister les ports ouverts et les exposer sur un port correspondant sur l'hôte, ou au contraire de stopper l'exposition si elle est déjà définie…

En fait, le mieux est sera de l'utiliser: plus rapide – et sans doute plus clair – que d'expliquer ce qu'il fait ^_^.
(Projet à l'étude au §6: faire un site web sur le VHS qui ferait la même chose. Mais faut du temps…)

  • Travaux en cours …
  • On fait çà en python
  • On exploite les API… python donc, fournies avec LXC

4.4. Remarques

Pensez à désactiver l'indexation sur le dossier $LXCBase que vous avez défini …
… sinon, le FileTrackingSystem (FTS pour les intimes), é bé l'a pas fini de ramer à indexer la foultitude de fichiers système du premier container venu !

Ce serait bien de prendre les dernières versions des logiciels (MySQL, PHP, etc…); ce serait bien de faire çà aussi pour la distribution: Ubuntu Xenial par exemple depuis le template download. Mais il faut tenir compte des contraintes sur le NAS et son noyau Linux (c'est lui qui tourne dans les containers) et de son système.

Il faut en effet préciser un point important: les dernières versions des distributions – notamment ubuntu xenial ou debian stretch – utilisent l’outil systemd. Or, LXC sur Ubuntu Trusty (système du NAS en v6.x) ne supporte pas cela dans les containers. Il existe une solution apparemment : il faut installer lxcfs sur le NAS … donc on laisse tomber (cf. https://newspaint.wordpress.com/2016/04/25/adding-an-ubuntu-16-04-xenial-lxc-container-to-ubuntu-14-04-trusty/)

Apparente solution de contournement en Annexes – A vérifier néanmoins à l'usage, mais ça m'a l'air de fonctionner et le script de définition des containers lxc_define intègre cette annexe pour les distributions debian (à partir de jessie) et ubuntu (à partir de xenial) qui sont en systemd et qu'on change…


5. Travaux pratiques ... donc

Les réalisations proposées dans les § suivants sont purement illustratives, pour montrer un peu ce qu'on peut faire avec cette techno. sur nos serveurs VHS.

Pour situer les choses − et accessoirement faire un point d'avancement des travaux décrits….:-P − un petit schéma: C'est une «vue logique» bien sûr … Tout est bien physiquement sur le NAS.

«Clickodrôme» intégré ci-dessous pour les détails et le mode opératoire …Les codes sont en annexes
Config. Web01 Term01
Tools Web02 Gui01


C'est une remarque pertinente sur le forum: à partir du moment où un container est défini, ce qui vous y mettez «à l'intérieur dedans» et les opérations pour le faire sont les mêmes que pour une machine GNU/Linux standard: vous savez le faire ou bien vous trouvez tout ce qu'il faut sur la toile pour vous y aider.

On propose néanmoins des créations/définitions via des scripts écrits en Python.

Cela a des avantages et des inconvénients…

  • Avantage pour les définitions: c'est plus simple à jouer que de se tartiner une foultitude ce copier/coller de commandes…
  • Avantage pour la réalisation: c'est plus simple à faire (je m'ai gouré, je change le code, je rejoue tout)
  • Avantage pour la conservation: les scripts sont des «recettes», on peut les rejouer en cas de pépin sur le NAS, ou les jouer ailleurs.
  • Avantage pour l'explication: dans ce tuto, on explique rien, en colle un fichier script … :-x :-P (commenté, quand même !)
  • Inconvénient pour faire autre chose que ces exemples: il faut comprendre !
  • Inconvénient pour comprendre: il faut se farcir le code…j'ose espérer qu'il demeure lisible

Voyons… Les avantages gagnent … et hop !! Un tuto ne couvrira jamais tous les cas de figure de toutes façons !

On se propose donc d'utiliser l'outil lxc_define défini plus haut pour créer chaque container, puis de scripter son contenu et y déposer ce à quoi on le destine.

L'ensemble des travaux pratiques suppose de les suivre à la lettre

Pour tenter de guider et minimiser les manip. à réaliser, les installations et configurations sont «automatisées» (le mot est bien trop fort quand même :-) via des scripts à jouer sur le VHS.

Néanmoins, il vous faut respecter les étapes et les choix pour que l'ensemble fonctionne. En effet, la combinatoire entre les façons de faire selon les versions des distributions, des paquets, des outils différents dans les containers, est bien trop grande pour les écrire et pouvoir toutes les valider…

Simplement pour dire que si vous choisissez l'ensemble des options proposées, cela devrait fonctionner… (sauf si j'meuhhh suis planté ici). Pour des cas différents, le code est sans doute à étudier/adapter à votre cible: inspirez-vous des scripts et / ou discutons-en sur le forum… çà pourrait être sympa ;-)

Les paragraphes suivants portent chacun sur un container et sont structurés de façon identique:

  1. Création du container: lister les données utilisées/renseignées lors de la définition via lxc_define;
  2. Proposer un (ou plusieurs) script – commentés – d'installation du contenu applicatif du container
  3. Décrire le mode opératoire de mise en œuvre
  4. Proposer le résultat attendu/obtenu

:!: NB: Tous les scripts proposés sont destinés au répertoire $LXCTools. Déposez-les-y (c'est français çà ?) via Filezilla par exemple. Si leur propriété d'exécution se perd en chemin lors de la copie sur les NAS, passez la commande suivante depuis une connexion ssh sur celui-ci et en remplaçant <script.sh/.py> par le nom du fichier concerné:

NAS
admin@sesame:~$ chmod +x $LXCTools/<script.sh/.py>


Bon, on doit être trop pas mal …. Allons-y, jouons un peu …:-P


5.1. Serveurs MariaDB et SSH - «lxc-term01»

 MariaDB est un fork de MySQL – qu'on ne présente plus celui-là. MySQL est désormais porté par la société Oracle et prend une orientation commerciale qui déplaît à un certain nombre de partisans et d'utilisateurs du «monde du libre». D'où ce choix …;-)

 OpenSSH (OpenBSD Secure Shell) «est un ensemble d'outils informatiques libres permettant des communications sécurisées sur un réseau informatique en utilisant le protocole SSH.» Lui non plus, on ne le présente plus…

Création du container - Données des formulaires sudo -E $LXCTools/lxc_define.sh:

Formulaire / Écran Choix / Alimentation
Nom du container lxc-term01
Distribution/release debian wheezy (7.x)
Modèle 2- Term
Liste des paquets Pas de changement: nano wget apt-utils debconf-utils openssh-server
Compte/Privilège <xxxx> / <OUI>
Démarre avec l'hôte OUI a priori, mais c'est vous qui voyez…
Synthèse Vérifier les informations et confirmer

La construction démarre et sollicite votre intervention pour:

  • Choix du fuseau horaire: Europe / Paris pour les métropolitains
  • Choix des 'locales' du container: Je prends fr_FR.UTF8

Les travaux sont terminés quand l’outil vous rend la main avec l'écran suivant:

...
Setting up sudo (1.8.5p2-1+nmu3+deb7u4) ...
************************************
 ==> Création du compte...
************************************
Adding user `cram28' to group `sudo' ...
Adding user cram28 to group sudo
Done.
************************************
NAME        STATE    IPV4       IPV6  AUTOSTART  
-----------------------------------------------
lxc-term01  RUNNING  10.0.3.11  -     NO         
____________________________________

Traitement terminé
************************************
admin@sesame:~$ 

Script - Le script fourni dans le package en fin de tuto s'appelle lxc_set-mariadb.py. Mêmes remarques que plus haut pour ce script-là aussi: Le rendre exécutable, commenté, pas tout testé, observations et suggestions bienvenues…

Mode opératoire - Données des formulaires sudo -E $LXCTools/lxc_set-mariadb.py:

Formulaire / Écran Choix / Alimentation
Nom du container lxc-term01
Options MariaDB Tout cocher: Mot de passe root - accès réseau - création compte
Saisies Doubles saisies des mots de passe, définition du compte
Synthèse Vérifier les informations et confirmer

Si tout va bien, l'installation se termine sur l'écran suivant:

...
[ ok ] Stopping MariaDB database server: mysqld.
[ ok ] Starting MariaDB database server: mysqld.
Setting up libdbd-mysql-perl (4.021-1+deb7u3) ...
Setting up libhtml-template-perl (2.91-1) ...
Setting up libterm-readkey-perl (2.30-4+b2) ...
Setting up mariadb-server (10.2.9+maria~wheezy) ...
************************************
 ==> Sécurisation de l'installation ...
************************************
************************************
 ==> Création compte ...
************************************
************************************
 ==> Ouverture réseau ...
************************************
[ ok ] Stopping MariaDB database server: mysqld.
[ ok ] Starting MariaDB database server: mysqld.

 ==> Script dans le container terminé...
************************************
NAME        STATE    IPV4       IPV6  AUTOSTART  
-----------------------------------------------
lxc-term01  RUNNING  10.0.3.11  -     NO         
____________________________________

Traitement ./lxc_set-mariadb.sh terminé
************************************
admin@sesame:~$ 

Résultats pour MariaDB

  • Dans le container: “Attachez-vous” au container (il tourne déjà, le mot de passe demandé est celui du compte admin du VHS - lié à la commande sudo):
    NAS
    admin@sesame:~$ sudo lxc-attach -n lxc-term01
    [sudo] password for admin: 

    Connectez-vous au moteur de base de données avec le compte “root” défini à l'installation de MariaDB et son mot de passe:

    lxc-term01
    root@lxc-term01:/# mysql -u root -p
    Enter password: 
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MariaDB connection id is 50
    Server version: 10.2.9-MariaDB-10.2.9+maria~wheezy-log mariadb.org binary distribution
     
    Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
     
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
     
    MariaDB [(none)]> 

    On passe une requête pour voir:

    lxc-term01
    MariaDB [(none)]> use mysql;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
     
    Database changed
    MariaDB [mysql]> select Host, User, Password from user;
    +-----------+------------------+-------------------------------------------+
    | Host      | User             | Password                                  |
    +-----------+------------------+-------------------------------------------+
    | localhost | root             | *C4794A209AF2D6A116BFD0145CEF24FC7197828D |
    | 127.0.0.1 | root             | *C4794A209AF2D6A116BFD0145CEF24FC7197828D |
    | ::1       | root             | *C4794A209AF2D6A116BFD0145CEF24FC7197828D |
    | localhost | debian-sys-maint | *E8E547CCC1D2082BB5AC6F8A0F5BC83E9C62DD41 |
    | %         | cram28           | *74DA7469E1AE40D81FF8D78C982F87DD49F25474 |
    +-----------+------------------+-------------------------------------------+
    5 rows in set (0.00 sec)
     
    MariaDB [mysql]> 

    On quitte MariaDB, puis le container:

    lxc-term01
    MariaDB [mysql]> quit
    Bye
    root@lxc-term01:/# exit
    exit
    admin@sesame:~$ 
  • Depuis le NAS (notez la différence des informations: ici le client est bien MySQL Oracle du VHS et pas MariaDB du container): On se connecte avec le compte qu'on a défini à l'installation de MariaDB et on fait la même manip (NB Pour des raisons de sécurité, et comme vous pouvez le voir par la colonne Host de la requête précédente, le compte root n'est pas autorisé via le réseau…):
    NAS
    admin@sesame:~$ mysql -h 10.0.3.11 -u cram28 -p 
    Enter password: 
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 51
    Server version: 5.5.5-10.2.9-MariaDB-10.2.9+maria~wheezy-log mariadb.org binary distribution
     
    Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
     
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
     
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
     
    mysql> use mysql;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
     
    Database changed
    mysql> select Host, User, Password from user;
    +-----------+------------------+-------------------------------------------+
    | Host      | User             | Password                                  |
    +-----------+------------------+-------------------------------------------+
    | localhost | root             | *C4794A209AF2D6A116BFD0145CEF24FC7197828D |
    | 127.0.0.1 | root             | *C4794A209AF2D6A116BFD0145CEF24FC7197828D |
    | ::1       | root             | *C4794A209AF2D6A116BFD0145CEF24FC7197828D |
    | localhost | debian-sys-maint | *E8E547CCC1D2082BB5AC6F8A0F5BC83E9C62DD41 |
    | %         | cram28           | *74DA7469E1AE40D81FF8D78C982F87DD49F25474 |
    +-----------+------------------+-------------------------------------------+
    5 rows in set (0.00 sec)
     
    mysql> quit
    Bye
    admin@sesame:~$ 

Résultats pour l'accès via SSH: On va accéder au container en ssh depuis le réseau; pour ce faire, on va «NATé» un port dédié et libre sur le NAS afin d'atteindre le container depuis un poste sur le réseau local (avec Putty depuis Windows par exemple).

  • Sur le NAS, on NATe le port 65022 (par exemple !) et on envoie le flux qui arrivera sur ce port du NAS vers le port standard 22 du serveur ssh du container (pas sûr que ce soit limpide cette phrase):
    NAS
    admin@sesame:~$ sudo iptables -t nat -A PREROUTING -p tcp -i br0 --dport 65022 -j DNAT --to-destination 10.0.3.11:22
  • On se connecte en ssh depuis un poste du réseau local (via Putty pour les clients Windows) en indiquant l'utilisateur défini à la création du container, l'@IP ou le nom réseau du NAS, et surtout en précisant notre port NATé (sinon on se retrouvera sur le NAS et pas dans le container…):
    Client
    cram28@paprika:~$ ssh cram28@sesame -p 65022
    The authenticity of host '[sesame]:65022 ([192.168.1.2]:65022)' can't be established.
    ECDSA key fingerprint is SHA256:Sar4qNrhfdx+Fwe0A9xSGIjblwPwu1EMoXpPP7tGK8c.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '[sesame]:65022,[192.168.1.2]:65022' (ECDSA) to the list of known hosts.
    cram28@sesame's password: 
    Linux lxc-term01 3.16.0-31-generic #41~14.04.1-Ubuntu SMP Wed Feb 11 19:30:13 UTC 2015 x86_64
     
    The programs included with the Debian GNU/Linux system are free software;
    the exact distribution terms for each program are described in the
    individual files in /usr/share/doc/*/copyright.
     
    Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
    permitted by applicable law.
     
    cram28@lxc-term01:~$ 
  • On passe une commande dans le container (par exemple pour afficher la distribution ici) et on sort:
    lxc-term01
    cram28@lxc-term01:~$ lsb_release -a
    No LSB modules are available.
    Distributor ID:	Debian
    Description:	Debian GNU/Linux 7.11 (wheezy)
    Release:	7.11
    Codename:	wheezy
     
    cram28@lxc-term01:~$ logout
    Connection to sesame closed.
    cram28@paprika:~$ 

Bon, tutto va bene8-)


5.2. Serveur web et sites - «lxc-web01»

On propose ici un container destiné à accueillir un serveur web et quelques sites.

5.2.1. Serveur web

On va le «motoriser» avec le serveur http couplé au langage . Pour la partie SGBD, on va bien sûr utiliser le container MariaDB précédent, mais on pourra tout aussi bien faire un lien avec le serveur MySQL du VHS (à condition d'en ouvrir les accès via le réseau - cf. Le VHS - Un Serveur MySQL…).

Pour installer la toute dernière version de php (la 7.2), sur Debian Wheezy il faut compiler le code source, sur Debian Jessie il y a un dépôt dédié, de même que pour les «vieilles» distributions Ubuntu … Pareil encore, la version du moteur nginx présent dans les dépôts de Trusty ne correspond pas à la dernière…

Bref, il faut donc prendre une version de distribution récente dans notre petit outil, avec l'option “type web” pour pouvoir bénéficier des versions récentes et présentes sur les dépôts «officiels» de ces outils: par exemple nginx 1.10 et php 7.0 sur debian Stretch (v9.0) à l'heure de ces lignes (c'est toujours plus récent que sur le NAS… )

Création du container - Données des formulaires sudo -E $LXCTools/lxc_define.sh:

Formulaire / Écran Choix / Alimentation
Nom du container lxc-web01
Distribution/release ubuntu xenial (16.04)
Modèle 3 - Web
Liste des paquets Pas de changement: nano wget ca-certificates nginx mariadb-client php php-fpm php-cli php-json php-curl php-imap php-gd php-mysql php-xml php-zip php-intl php-mcrypt php-imagick php-mbstring php-apcu
Compte/Privilège <xxxx> / <OUI>
Démarre avec l'hôte A vous de voir…
Synthèse Vérifier les informations et confirmer

La construction démarre et sollicite votre intervention pour:

  • Choix des 'locales' du container: Je prends fr_FR.UTF8
  • Choix du fuseau horaire: Europe / Paris pour les métropolitains

Les travaux sont terminés quand l’outil vous rend la main avec l'écran suivant:

...
Paramétrage de debconf-utils (1.5.51ubuntu2) ...
************************************
 ==> Création du compte...
************************************
Ajout de l'utilisateur « cram28 » au groupe « sudo »...
Adding user cram28 to group sudo
Fait.
************************************
NAME        STATE    IPV4        IPV6  AUTOSTART  
------------------------------------------------
lxc-term01  STOPPED  -           -     NO         
lxc-web01   RUNNING  10.0.3.101  -     NO         
____________________________________

Traitement terminé
************************************
admin@sesame:~$ 

Remarque: L'outil de création des containers applique l'annexe 2 et remplace systemd par sysvinit si vous choisissez une distribution «récente» … ubtunu à partir de xenial, debian depuis jessie.

Résultats : Pour vérifier le bon fonctionnement de notre serveur web, on va utiliser la commande curl (déjà installée sur le VHS) avec l'adresse du container en paramètre:

  • Avec l'option -I, cette commande va retournée des informations sur le serveur:
    NAS
    admin@sesame:~$ curl -I 10.0.3.101
    HTTP/1.1 200 OK
    Server: nginx/1.10.3 (Ubuntu)
    Date: Sat, 24 Feb 2018 10:30:43 GMT
    Content-Type: text/html
    Content-Length: 612
    Last-Modified: Sat, 17 Feb 2018 10:47:43 GMT
    Connection: keep-alive
    ETag: "5a88084f-264"
    Accept-Ranges: bytes
  • Sans option, la commande affiche la page HTML par défaut
    NAS
    admin@sesame:~$ curl 10.0.3.101
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
     
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
     
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
  • On va afficher cette page par défaut dans un navigateur depuis un poste client. Pour ce faire et sur le NAS toujours, on NATe le port 65080 (par exemple) et on envoie ce flux sur le port standard 80 du serveur http nginx du container:
    NAS
    admin@sesame:~$ sudo iptables -t nat -A PREROUTING -p tcp -i br0 --dport 65080 -j DNAT --to-destination 10.0.3.101:80
  • On se connecte avec un navigateur web depuis un poste du réseau local : dans la barre des adresses, l'URL correspond à l'adresse ip ou au nom du NAS, en précisant bien le port NATé:
    http://<@IP ou non du VHS>:<port exposé>

On a un serveur web opérationnel et accessible sur le LAN8-)

On va ajouter des sites/services dans les paragraphes ci-dessous. Comme ces services sont destinés plutôt à un usage LAN («en intranet», sans l'ouvrir à l'extérieur), la sécurité et les bonnes pratiques en la matière ne sont pas considérées ici: par exemple, tous les sites sont configurés dans un même fichier, utilisation de l'index, pas de ssl etc…

Si vous voulez ouvrir sur l'extérieur et Internet, faudra sûrement revisiter tout çà :!:


5.2.2. Ajout du site «Adminer»

On va mettre l'outil Adminer – plus 2/3 bricoles ici – à disposition dans notre container lxc-web01 (celui-ci est donc un pré-requis pour le faire). Objectifs: pour un outil simplissime, efficace et léger, pour accéder au moteur SGBD MariaDB dans son container lxc-term01 défini plus haut.

Pour cela, on utilise un script qui nous évitera de faire le boulot à la main…

Script en annexe. Mêmes remarques que plus haut pour ce script-là aussi: Commenté, sûrement pas tout testé, observations et suggestions bienvenues…

Mode opératoire - Données des formulaires sudo -E $LXCTools/lxc_set-adminer.py, pour installer Adminer:

Formulaire / Écran Choix / Alimentation
Container cible lxc-web01
Options Moi, je coche tout évidemment ;-)
Synthèse Vérifier les informations et confirmer

Le script affiche ses traitements et se termine avec la liste des containers.

...
************************************
NAME        STATE    IPV4       IPV6  AUTOSTART  
-----------------------------------------------
lxc-term01  RUNNING  10.0.3.11  -     NO
lxc-web01   RUNNING  10.0.3.101 -     NO           
____________________________________

Traitement ./lxc_set-adminer.py terminé
************************************
admin@sesame:~$ 

Résultats pour Adminer

  • «Comme d'hab.» maintenant – mais c'est fait déjà à l'étape précédente de création du container lxc-web01 – il faut exposer le service sur le LAN en ouvrant un port dédié sur le VHS. Pour mémoire si ce n'est pas déjà fait à l'étape précédente (et en attendant l'outil qui va bien), la commande d'exposition pourrait ainsi être la suivante:
    NAS
    $ sudo iptables -t nat -A PREROUTING -p tcp -i br0 --dport 65080 -j DNAT --to-destination 10.0.3.101:80

    Pour stopper l'exposition (D comme delete remplace A comme append):

    NAS
    $ sudo iptables -t nat -D PREROUTING -p tcp -i br0 --dport 65080 -j DNAT --to-destination 10.0.3.101:80

  • Les paramètres:
    • La liste déroulante «Système» est valorisée avec «MySQL» pour accéder à des moteurs MySQL comme MariaDB.
    • Le «Serveur» est votre … serveur SGBD, identifié par nom réseau ou adresse IP sur la LAN. Il faut noter qu'on peut mettre ici le nom du container MariaDB lxc-term01 directement, mais seulement parce que le service web lxc-web01 et le service base de données lxc-term01 sont des containers sur le même sous-réseau en 10.0.3.x via le bridge. Si vous faîtes des containers sur un autre hôte que le VHS, ils ne seront pas visibles sur le LAN et il faudra, pour les atteindre, en exposer un port depuis leur hôte comme on le fait ici. On exploitera alors la forme en <nom ou @IP>:<port> qu'autorise en saisie cette zone «Serveur».
    • «Utilisateur» et «Mot de passe» sont ceux définis lors de la création du container lxc-term01 si vous souhaitez atteindre ce serveur
    • Le nom de la «base de données» est optionnelle.

  • Si vous avez ouvert l'accès réseau au moteur de bases de données MySQL natif sur le VHS (cf. le tuto sur ce wiki), vous pourrez utiliser ce même outil Adminer en lieu et place, sans les contraintes connues de l'outil PhpMyAdmin proposé dans le portail du NAS (NAS qui s'appelle ici sesame, prenez le nom ou l'@IP pour le votre):

Je vous laisse trouver les «2/3 bricoles» à la racine du serveur…


5.2.3. Ajout du site «NextCloud»

Définition reprise de ce tuto (qui m'a bien servi):

«Nextcloud est un fork du célèbre ownCloud, solution vous permettant de créer votre propre cloud auto-hébergé et ainsi de stocker et synchroniser vos fichiers, vos contacts, votre agenda et vos contenus multimédias directement sur votre serveur. Vous pourrez alors accéder à toutes ces informations directement depuis votre navigateur web ou votre mobile via une application dédiée.»





5.3. Containers «bureau» - «lxc-gui01»





5.4. Un unique... «pour les dominer tous» - «lxc-web02»


L'outil Guacamole pourrait bien être idéal pour servir d'intermédiaire de présentation de nos services sur un client «banalisé»: depuis un simple navigateur, il permet notamment d'afficher des bureaux distants.

Guacamole est positionné comme suit:

Ainsi, nos services en containers LXC sont exposés sur le réseau dans un protocole (VNC, RDP, SSH etc…) et sont «restitués» dans un navigateur en HTML 5 sur les clients via Guacamole: … simple !


6. Un site... «pour les contrôler tous»

Idée: Les mêmes manip. & opérations avec un site «intranet» Apache/PHP/(Python ?) sur le NAS …
Y a du boulot et je suis une bille….

Inspiration: lxc-webpanel. C'est … vieux !


A. Annexes pour des ... «détails»

A.0. Le code complet

Les fichiers ci-joints proposent l'ensemble du code bash .sh ou python .py présenté ici.

  • Le 1ier fichier lxc_set-env.sh doit être obligatoirement exécuté. Il définit – entre autres choses – une arborescence pour LXC. Vous le copiez où vous voulez sur le serveur (par exemple dans privé/scripts de l'utilisateur admin.
  • L'ensemble des autres scripts est destiné au dossier $LXCTools crée par la configuration précédente.
  • Si la propriété «exécutable» d'un script est perdue en chemin: chmod +x <script>
  • Il existe un bout de code whiptailPy.py poussé avec l'outil de création des containers. Il est utilisé par tous les scripts python et doit donc être présent dans $LXCTools.
Domaine Script / Commande Périmètre
Config.lxc_set-env.zip
sudo ./lxc_set-env.sh
bash_shell2.jpegParamétrage de l'environnement LXC sur le VHS.
Outilslxc_define.zip
sudo -E $LXCTools/lxc_define.py
Outil de création de containers par “typologie”
Toolsen cours …Outil de gestion des containers (facilitateur)
Term01lxc_set-mariadb.zip
sudo -E $LXCTools/lxc_set-mariadb.py
Container term: ajout MariaDB, SSH
Web01lxc_set-adminer.zip
sudo -E $LXCTools/lxc_set-adminer.py
Container web: Ajout Adminer (outil BDD)
Web01en cours …Container web: Ajout…(outil ..)
Web02en cours …Container web: Serveur Guacamole (Accès bureaux)
Gui01en cours …Container gui: Pour applications de bureau (env. graphiques)

A.1. LXC dans une VM: «bac à sable»

Pour mettre au point des scripts et des définitions de containers, pour vérifier qu'ils fonctionnent comme attendu, on peut se rapprocher de l'environnement de l'hôte VHS des containers, mais dans une machine virtuelle.


A.2. Quelles distributions compatibles ?

Le VHS tourne sous Ubuntu serveur 14.04 «Trustry» avec un noyau linux 3.16:

Terminal VHS
admin@sesame:~$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 14.04.2 LTS
Release:	14.04
Codename:	trusty
 
admin@sesame:~$ uname -a
Linux sesame 3.16.0-31-generic #41~14.04.1-Ubuntu SMP Wed Feb 11 19:30:13 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
admin@sesame:~$ 

Qu'est-ce qui m’empêche de faire un container avec une… «Xenial» (16.04) ? :?: 8-o

Ne rêvons pas tout de même: la version du noyau Linux restera celle du VHS …

Sur ce cas précis en l’occurrence, le problème vient des systèmes d'init. des processus, de systemd utilisé sur «Xenial», tandis que pour notre hôte VHS, il s'agit de l'«ancien système» sysvinit upstart-sysv
Et il semble bien qu'il y ait des incompatibilités! En effet: «LXC on Trusty does not support systemd in containers.» (je sais plus où j'ai lu çà…:-/)

Voyons:

Terminal VHS
admin@sesame:~$ sudo lxc-create -n lxc-xenial \
                                -t $LXCTemplate/lxc-download \ 
                                -- -d ubuntu -r xenial -a amd64
 
admin@sesame:~$ sudo lxc-start -n lxc-xenial -d

Jusque là tout va bien mais pas dedans … Pas d'adresse et rien ne tourne:

Terminal VHS/LXC
admin@sesame:~$ sudo lxc-ls -f 
NAME              STATE    IPV4  IPV6  AUTOSTART  
------------------------------------------------
lxc-xenial        RUNNING  -     -     NO         
 
admin@sesame:~$ sudo lxc-attach -n lxc-xenial 
 
root@lxc-xenial:/# top
 
top - 21:14:38 up  1:04,  0 users,  load average: 0.03, 0.08, 0.08
Tasks:   3 total,   1 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.3 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  2048388 total,   439896 free,   329864 used,  1278628 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  1526444 avail Mem 
 
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    1 root      20   0   36536   2136   1696 S   0.0  0.1   0:00.00 systemd
    9 root      20   0   21156   3384   2900 S   0.0  0.2   0:00.00 bash   
   13 root      20   0   39580   3152   2696 R   0.0  0.2   0:00.00 top    
 
root@lxc-xenial:/# service --status-all
 [ - ]  bootmisc.sh
 [ - ]  checkfs.sh
 [ - ]  checkroot-bootclean.sh
 [ - ]  checkroot.sh
 [ - ]  console-setup
 [ - ]  cron
 [ - ]  hostname.sh
 [ ? ]  hwclock.sh
 [ - ]  keyboard-setup
 [ - ]  killprocs
 [ ? ]  kmod
 [ - ]  mountall-bootclean.sh
 [ - ]  mountall.sh
 [ - ]  mountdevsubfs.sh
 [ - ]  mountkernfs.sh
 [ - ]  mountnfs-bootclean.sh
 [ - ]  mountnfs.sh
 [ ? ]  networking
 [ ? ]  ondemand
 [ - ]  procps
 [ - ]  rc.local
 [ + ]  resolvconf
 [ - ]  rsyslog
 [ - ]  sendsigs
 [ + ]  udev
 [ - ]  umountfs
 [ - ]  umountnfs.sh
 [ - ]  umountroot
 [ - ]  urandom
root@lxc-xenial:/# 

La solution consiste à revenir à sysvinit sur le container «Xenial» avec la série de commandes suivante:

Terminal LXC
### Pour activer l'accès internet
root@lxc-xenial:/# service networking start
root@lxc-xenial:/# service resolvconf start
 
root@lxc-xenial:/# apt-get install upstart upstart-sysv
root@lxc-xenial:/# apt-get remove --purge --auto-remove systemd
 
 
# il faudra aussi réinstaller openssh-sftp-server
root@lxc-xenial:/# apt-get remove --purge openssh-sftp-server
root@lxc-xenial:/# apt-get install openssh-sftp-server
 
root@lxc-xenial:/# exit

On sort, on arrête …:

Terminal VHS
admin@sesame:~$ sudo lxc-stop -n lxc-xenial 

… il va mettre plus d'une minute à s'éteindre: l'est bancal…

Et on relance, et là, c'est mieux !:

Terminal VHS/LXC
admin@sesame:~$ sudo lxc-start -n lxc-xenial -d
 
admin@sesame:~$ sudo lxc-ls -f 
NAME              STATE    IPV4        IPV6  AUTOSTART  
------------------------------------------------------
lxc-xenial        RUNNING  10.0.3.213  -     NO         
 
admin@sesame:~$ sudo lxc-attach -n lxc-xenial 
 
root@lxc-xenial:/# top
top - 23:58:38 up  3:48,  0 users,  load average: 0.11, 0.09, 0.07
Tasks:  17 total,   1 running,  16 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.2 sy,  0.0 ni, 97.7 id,  1.8 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  2048388 total,   222428 free,   343712 used,  1482248 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  1506768 avail Mem 
 
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND         
    1 root      20   0   43404   4124   3128 S   0.0  0.2   0:00.06 init            
  128 root      20   0   29948    268     12 S   0.0  0.0   0:00.00 upstart-udev-br 
  135 root      20   0   41588   3120   2728 S   0.0  0.2   0:00.00 systemd-udevd  
  136 message+  20   0   42768   2660   2292 S   0.0  0.1   0:00.00 dbus-daemon    
  143 syslog    20   0  256396   2760   2352 S   0.0  0.1   0:00.00 rsyslogd       
  154 root      20   0   30016   1756   1288 S   0.0  0.1   0:00.00 upstart-socket-
  157 root      20   0   29900    364     12 S   0.0  0.0   0:00.00 upstart-file-br
  289 root      20   0   16120    856      0 S   0.0  0.0   0:00.00 dhclient
  372 root      20   0   12844   1800   1660 S   0.0  0.1   0:00.00 getty
  375 root      20   0   12844   1820   1684 S   0.0  0.1   0:00.00 getty
  376 root      20   0   12844   1896   1752 S   0.0  0.1   0:00.00 getty
  379 root      20   0   26068   2348   2120 S   0.0  0.1   0:00.00 cron 
  384 root      20   0   65520   5500   4800 S   0.0  0.3   0:00.00 sshd 
  435 root      20   0   12844   1784   1644 S   0.0  0.1   0:00.00 getty
  436 root      20   0   12844   1720   1580 S   0.0  0.1   0:00.00 getty
  440 root      20   0   21156   3276   2796 S   0.0  0.2   0:00.00 bash
  445 root      20   0   39580   3296   2828 R   0.0  0.2   0:00.00 top              
 
root@lxc-xenial:/# service --status-all
 [ + ]  bootmisc.sh
 [ + ]  checkfs.sh
 [ + ]  checkroot-bootclean.sh
 [ + ]  checkroot.sh
 [ + ]  console-setup
 [ + ]  cron
 [ + ]  dbus
 [ + ]  hostname.sh
 [ + ]  hwclock.sh
 [ - ]  keyboard-setup
 [ - ]  killprocs
 [ + ]  kmod
 [ + ]  mountall-bootclean.sh
 [ + ]  mountall.sh
 [ + ]  mountdevsubfs.sh
 [ + ]  mountkernfs.sh
 [ + ]  mountnfs-bootclean.sh
 [ + ]  mountnfs.sh
 [ + ]  networking
 [ ? ]  ondemand
 [ ? ]  plymouth
 [ ? ]  plymouth-log
 [ + ]  procps
 [ - ]  rc.local
 [ + ]  resolvconf
 [ + ]  rsyslog
 [ - ]  sendsigs
 [ + ]  ssh
 [ + ]  udev
 [ - ]  umountfs
 [ - ]  umountnfs.sh
 [ - ]  umountroot
 [ - ]  urandom
root@lxc-xenial:/# 
 
root@lxc-xenial:/# netstat -tlnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      384/sshd        
tcp6       0      0 :::22                   :::*                    LISTEN      384/sshd        
root@lxc-xenial:/#

Même problème constaté avec debian, qui embarque systemd depuis la distribution jessie (pas de problème avec Wheezy). La manip est similaire (cf. le script de création de lxc-web02 pour Guacamole):

Terminal
...
echo -e " ==> Remplacer systemd par sysvinit..."
chroot $rootfs apt-get -y install apt-utils debconf-utils
chroot $rootfs apt-get -y install systemd-sysv sysvinit-core sysvinit-utils --force-yes
chroot $rootfs apt-get -y remove --purge systemd
...

Cela semble fonctionner correctement… En cas de problème on devrait néanmoins pouvoir utiliser les distributions directement compatibles (Ubuntu Trusty, Debian Wheezy,…) !


A.3. Limiter la consommation des containers

Il est possible de limiter l’utilisation de tout et n’importe quoi concernant les conteneurs, et ça peut se faire via fichier de config: lxc.cgroup.<cgroup-name> = <value>

Pour limiter la consommation des conteneurs :

  • mémoire: lxc.cgroup.memory.limit_in_bytes = 256M
  • swap: lxc.cgroup.memory.memsw.limit_in_bytes = 1G
  • pour assigner des cœurs CPU: lxc.cgroup.cpuset.cpus = 0-1,3
  • pour donner plus ou moins de CPU (chacun a 1024 de base) il s’agit de lxc.cgroup.cpu.shares = 512, et ici on donne deux fois moins de CPU à ce conteneur qu’aux autres.

Autre source:
Par ailleurs, il est recommandé de limiter l’usage mémoire des LXC avec par exemple, dans le fichier config de ceux-ci :

  • lxc.cgroup.memory.soft_limit_in_bytes = 256M
  • lxc.cgroup.memory.limit_in_bytes = 1G
  • lxc.cgroup.memory.memsw.limit_in_bytes = 2G
  • lxc.cgroup.memory.swappiness = 0

Cela appliquera une limite réelle de 1G de RAM + 1G de swap, mais le container essaiera de ne pas swaper et même de ne pas dépasser 256M de RAM.


A.4. Un baratin pour les futurs unprivileged

Unprivileged LXC containers are the ones making use of user namespaces (userns). I.e. of a kernel feature that allows to map a range of UIDs on the host into a namespace inside of which a user with UID 0 can exist again.

Contrary to my initial perception of unprivileged LXC containers for a while, this does not mean that the container has to be owned by an unprivileged host user. That is only one possibility.

Relevant is:

  that a range of subordinate UIDs and GIDs is defined for the host user (usermod [-v|-w|--add-sub-uids|--add-sub-gids])
  ... and that this range is mapped in the container configuration (lxc.id_map = ...)

So even root can own unprivileged containers, since the effective UIDs of container processes on the host will end up inside the range defined by the mapping.

However, for root you have to define the subordinate IDs first. Unlike users created via adduser, root will not have a range of subordinate IDs defined by default.

Also keep in mind that the full range you give is at your disposal, so you could have 3 containers with the following configuration lines (only UID mapping shown):

  lxc.id_map = u 0 100000 100000
  lxc.id_map = u 0 200000 100000
  lxc.id_map = u 0 300000 100000

assuming that root owns the subordinate UIDs between 100000 and 400000. All documentation I found suggests to use 65536 subordinate IDs per container, some use 100000 to make it more human-readbable, though.

In other words: You don't have to assign the same range to each container.

With over 4 billion (~ 2^32) possible subordinate IDs that means you can be generous when dealing the subordinate ranges to your host users. Unprivileged container owned and run by root

To rub that in again. An unprivileged LXC guest does not require to be run by an unprivileged user on the host.

Configuring your container with a subordinate UID/GID mapping like this:

lxc.id_map = u 0 100000 100000
lxc.id_map = g 0 100000 100000

where the user root on the host owns that given subordinate ID range, will allow you to confine guests even better.

However, there is one important additional advantage in such a scenario (and yes, I have verified that it works): you can auto-start your container at system startup.

Usually when scouring the web for information about LXC you will be told that it is not possible to autostart an unprivileged LXC guest. However, that is only true by default for those containers which are not in the system-wide storage for containers (usually something like /var/lib/lxc). If they are (which usually means they were created by root and are started by root), it's a whole different story.

lxc.start.auto = 1

will do the job quite nicely, once you put it into your container config. Getting permissions and configuration right

I struggled with this myself a bit, so I'm adding a section here.

In addition to the configuration snippet included via lxc.include which usually goes by the name /usr/share/lxc/config/$distro.common.conf (where $distro is the name of a distro), you should check if there is also a /usr/share/lxc/config/$distro.userns.conf on your system and include that as well. E.g.:

lxc.include = /usr/share/lxc/config/ubuntu.common.conf
lxc.include = /usr/share/lxc/config/ubuntu.userns.conf

Furthermore add the subordinate ID mappings:

lxc.id_map = u 0 100000 65535
lxc.id_map = g 0 100000 65535

which means that the host UID 100000 is root inside the user namespace of the LXC guest.

Now make sure that the permissions are correct. If the name of your guest would be stored in the environment variable $lxcguest you'd run the following:

# Directory for the container
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest
chmod ug=rwX,o=rX $(lxc-config lxc.lxcpath)/$lxcguest
# Container config
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest/config
chmod u=rw,go=r $(lxc-config lxc.lxcpath)/$lxcguest/config
# Container rootfs
chown 100000:100000 $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
chmod u=rwX,go=rX $(lxc-config lxc.lxcpath)/$lxcguest/rootfs

This should allow you to run the container after your first attempt may have given some permission-related errors.


1)
…Pas de triche !! ^_^
archives/vm/lxc_app_v2.txt · Dernière modification: 04/10/2019 21:13 de Cram28