Construire son cluster LXD

Magazine
Marque
Linux Pratique
Numéro
141
Mois de parution
janvier 2024
Spécialité(s)


Résumé

LXD (LinuX container Daemon) est un environnement complet comprenant une API, des outils et un service (daemon) permettant de gérer des conteneurs LXC (LinuX Containers) et des machines virtuelles QEMU / KVM sur un cluster de machines Linux. L’atout principal de LXD est sa légèreté en termes d’installation, administration et empreinte sur le système. Dans cet article, nous allons explorer l’installation et l’utilisation d’un cluster LXD.


Body

La virtualisation et la conteneurisation sont deux mécanismes radicalement différents dans leur fonctionnement, mais partageant le même objectif : isoler un ou plusieurs processus. Ces processus isolés, qu’il soient virtualisés ou conteneurisés, peuvent être créés individuellement sur chaque machine les hébergeant ou alors orchestrés sur un cluster de nœuds dédiés à cet usage. L’orchestration consiste à distribuer les machines virtuelles et les conteneurs sur un ensemble de machines en passant uniquement une contrainte de ressources et une image à déployer. Un composant nommé orchestrateur (orchestrator) examine votre contrainte de ressource et essaye de placer vos conteneurs et machines virtuelles en fonction. Dans certaines ressources sur la conteneurisation et la virtualisation, vous pourrez trouver le terme ordonnanceur (scheduler) à la place d’orchestrateur. Le terme ordonnanceur est usuellement réservé au noyau Linux, plus précisément le CFS (Completely Fair Scheduler) chargé de répartir le temps processeur entre les différents cœurs du processeur. On retrouve également ce terme pour parler du service chargé de placer les travaux des utilisateurs sur les clusters HPC (High Performance Computing). Dans cet article, nous parlerons d’orchestrateur pour évoquer LXD et consorts.

1. Introduction

Il existe de nombreuses solutions pour orchestrer des processus isolés sur une infrastructure. Côté logiciels propriétaires, on trouve l’incontournable VMWare. Pour le libre, on trouve Proxmox [1] ou OpenNebula [2,3]. La question qui vient immédiatement à l’esprit concerne le positionnement de LXD dans cet écosystème. Son originalité est de proposer une solution beaucoup plus simple en termes d’architecture, d’installation et d’utilisation que les solutions susnommées. En effet, ces solutions lourdes intègrent, en plus de l’orchestration, le provisionnement des machines hébergeant les conteneurs et les machines virtuelles. Le provisionnement consiste à créer et mettre en place une infrastructure informatique physique ou virtuelle de façon automatique ou manuelle. Ce terme regroupe les différentes étapes nécessaires à la gestion de la mise en place d’un système fonctionnel. Nous noterons que lorsque le provisionnement est mentionné, il sous-entend généralement un déploiement automatique par lot. Les solutions susmentionnées intègrent également le provisionnement des images de machines virtuelles et conteneurs. En plus d’assurer le provisionnement des différents acteurs, les solutions lourdes assurent leur supervision via des agents déployés sur les machines hôtes pour la machine elle-même et ses conteneurs et dans les machines virtuelles. Cette supervision sert notamment à piloter le passage à l’échelle du service sous-tendu par les machines virtuelles et/ou les conteneurs. Enfin, les solutions lourdes intègrent également la virtualisation du réseau d’interconnexion des machines virtuelles et des conteneurs pour réglementer les interactions entre eux ainsi que vers l’extérieur. Pour notre étude de LXD, nous allons déployer un laboratoire très simple en machine virtuelle. Nous allons avoir trois nœuds :

  • Un frontal portant le DNS de notre laboratoire ainsi qu’un serveur DHCP. Cette machine fait également office de routeur vers l’extérieur ;
  • Deux nœuds (node1 et node2) chargés d’accueillir les machines virtuelles et les conteneurs. Ces nœuds embarquent donc LXC pour l’instanciation des conteneurs et KVM pour les machines virtuelles. J’ai activé le « nesting » pour pouvoir imbriquer les machines virtuelles.

Nous nous servirons de ce laboratoire pour présenter la configuration de LXD ainsi que le déroulement de plusieurs scénarios d’instanciation. Nous verrons ce qui se passe concrètement sur les nœuds lorsque les machines virtuelles et les conteneurs sont en exécution. Dans la figure 1 représentant le laboratoire, nous voyons que la machine frontale est bidomiciliée. Elle est à la fois connectée au réseau externe en NAT pour accéder à internet et à un réseau interne nommé intnet. Les machines node1 et node2 sont également connectées à intnet. Le réseau intnet porte le réseau 192.168.45.0/24. Le frontal est en 192.168.45.254 et node1 et node2 sont respectivement en 192.168.45.11 et 192.168.45.12. Le frontal embarque également un serveur DHCP qui sert l’étendue 192.168.45.100 à 192.168.45.200. En conséquence, le frontal fait office de passerelle pour que node1 et node2 puissent sortir sur l’extérieur.

lab.drawio-s

Fig. 1 : Laboratoire de test.

2. Les briques de base

Pour préparer l’installation de LXD sur notre cluster de test, il faut présenter deux briques : LXC et KVM / QEMU. LXC est utilisé pour gérer les conteneurs, alors que KVM / QEMU s’occupera de l’instanciation des machines virtuelles. Ces deux briques vont s’appuyer sur un réseau très simple. Sur chaque nœud, nous créerons un pont sur l’interface portant le réseau 192.168.45.0/24 afin d’y attacher nos machines virtuelles et conteneurs. Nous commencerons donc par créer les ponts sur node1 et node2. Ensuite, nous présenterons LXC et enfin nous présenterons KVM / QEMU.

2.1 Création des ponts

Un pont est une extension de domaine de diffusion (broadcast) Ethernet (niveau 2 du modèle OSI). Un pont peut être physique. Par exemple, lorsque vous tirez un câble entre deux commutateurs, vous agrégez les deux domaines de diffusion Ethernet de chacun des commutateurs en un seul. En conséquence, comme ces deux commutateurs sont sur le même domaine de diffusion Ethernet grâce au câble d’interconnexion, le trafic ARP passe de l’un à l’autre. Ainsi, les paquets transportés peuvent circuler entre les machines du même réseau IP. Sur un système Linux, nous pouvons créer des ponts virtuels locaux à la machine. En conséquence, les machines virtuelles et les conteneurs attachés au pont pourront communiquer sur le réseau de la machine hôte. Nous verrons la configuration du pont pour node1, il faudra faire la même chose sur node2. Commençons par installer les paquets gérant les ponts sous Linux :

root@node1:~# apt install bridge-utils

Ensuite, nous allons configurer le pont dans /etc/network/interfaces :

root@node1:~# cat /etc/network/interfaces
source /etc/network/interfaces.d/*
 
auto lo
iface lo inet loopback
 
auto enp0s3
iface enp0s3 inet manual
 
auto br0
iface br0 inet static
        bridge_ports enp0s3
        bridge_stp off
        bridge_waitport 0
        bridge_fd 0
        address 192.168.45.11/24
        gateway 192.168.45.254

L’interface réelle de la machine est enp0s3, elle est connectée physiquement au réseau intnet. Nous voyons dans la configuration du pont br0 que enp0s3 est membre du pont (bridge_ports enp0s3). En conséquence, les interfaces virtuelles liées au pont verront le trafic de niveau 2 tel que ARP et pourront elles-mêmes y faire transiter des trames. Du fait que ce pont est virtuel, on peut désactiver le Spanning-Tree (bridge_stp off) considérer que toutes les interfaces du pont sont immédiatement disponibles (bridge_waitport 0) et qu’elles peuvent communiquer tout de suite (bridge_fd 0). Enfin, on spécifie l’adresse IP du pont (address 192.168.45.11/24) et sa passerelle par défaut (gateway 192.168.45.254). La configuration est à répéter sur node2.

2.2 Installation de snap

Pour disposer d’une version récente de LXD, nous allons passer par l’installeur snap. La différence avec apt est que snap dispose d’un magasin (snap store) alimenté en direct par les développeurs des applications. Par rapport à apt, le cycle de livraison des applications est plus court. Les paquets apt sont gérés par des mainteneurs, sont testés sur la distribution et surtout liés avec les autres paquets (sous forme de dépendances). Ainsi, les mises à jour via apt (ou avec tout autre gestionnaire de paquets natif de distribution Linux) sont beaucoup plus solides qu’avec des systèmes « cutting edge » comme snap. Ici, nous utilisons snap pour installer une seule et unique application donc la maintenance n’est pas très compliquée. D’autant plus que le système de base est assez simple, car il n’embarque que les utilitaires de base du système, KVM et LXC. En revanche, en cas d’assemblages complexes, le recours massif à snap sur une base conséquente installée avec apt peut mener à des incohérences de configuration. Commençons donc par installer snap sur node1. Le gestionnaire d’applications snap s’incarne sous la forme d’un service snapd s’exécutant en arrière-plan sur la machine. La première chose à installer est le paquet snapd sur notre Debian via apt. Contrairement à ce que le nom laisse supposer, le paquet snapd ne contient pas le daemon snapd. Il contient les script permettant à systemd de démarrer snapd lorsqu’il est présent. L’installation se fait donc en deux temps, d’abord l’installation du paquet snapd et l’enregistrement du chemin des exécutables snap dans le PATH :

root@node1:~# apt install snapd

Effectivement, aucun processus snapd n’est en exécution :

root@node1:~# ps -auxwww | grep snapd
root         643 0.0 0.1   6332 2072 pts/0    S+   12:02   0:00 grep snapd

Une fois cette installation effectuée, il faut ajouter /snap/bin dans le PATH de votre session. Vous pouvez ajouter un export dans votre .bashrc :

root@node1:~# export PATH=$PATH:/snap/binroot@node1:~# echo ‘export PATH=$PATH:/snap/bin’ >> .bashrc

Ensuite, on installe le paquet core via snap. Ce paquet contient les composants essentiels pour le fonctionnement du système de gestion des paquets Snap sur votre système Linux, y compris le démon snapd et les bibliothèques de base nécessaires à l'exécution des applications snap. Installons le paquet core :

root@node1:~# snap install core
2023-10-16T09:12:27+02:00 INFO Waiting for automatic snapd restart...
core 16-2.60.4 from Canonical✓ installed

Cette fois-ci, nous retrouvons bien un processus snapd en exécution sur le système :

root@node1:~# ps -auxwww | grep snapd
root         794 3.5 1.3 1245060 27952 ?       Ssl  12:03   0:00 /usr/lib/snapd/snapd
root         886 0.0 0.1    6332  2092 pts/0    S+  12:03   0:00 grep snapd

Vérifions quand même que nous n’avons pas fait tout ça pour rien. Regardons la version de LXD dans les dépôts apt :

root@node1:~# apt-cache policy lxd
lxd:
  Installed: (none)
  Candidate: 5.0.2-5

Nous sommes en version 5.0.2. Regardons la version proposée par snap :

root@node1:~# snap info lxd
name:     lxd
summary:   LXD - container and VM manager
publisher: Canonical✓
store-url: https://snapcraft.io/lxd
...
channels:
  latest/stable:    5.18-da72b8b 2023-10-11 (25945) 189MB -

C’est la 5.18, l’écart est donc assez considérable. Nous allons maintenant évoquer LXC qui sera présent sur les nœuds participant au cluster LXD.

2.3 La couche LXC

LXC (LinuX Containers) est un moteur de conteneur lancé en 2008 qui s'appuie directement sur les mécanismes disponibles dans le noyau pour isoler des processus. Son architecture est présentée dans la figure 2. LXC fournit à la fois une librairie servant d'interface d'utilisation de ces mécanismes avec le noyau nommée liblxc, mais également des outils de haut niveau pour les utilisateurs / administrateurs qui sont un ensemble de commandes préfixé par lxc-*.La librairie liblxc s'appuie sur des mécanismes de contrôle d'accès mandataires notamment SELinux [4] et AppArmor [5], pour créer des politiques d'isolation des conteneurs. Elle peut également tirer parti de Seccomp pour limiter les appels système. Seccomp s'appuie sur le framework BPF [6], idéal pour l’instrumentation des appels système. Si le conteneur a besoin de privilèges particuliers, liblxc peut s'interfacer avec les capacités. Évidemment, liblxc interagit également avec le couple cgroups [7] / espaces de noms [8,9,10]. Enfin, le système de fichiers du conteneur LXC est isolé grâce à pivot_root() qui est un appel système comparable à chroot() au niveau fonctionnel. La différence majeure est que pivot_root() requiert que la nouvelle racine de notre processus soit sur un système de fichiers différent, ce qui mitige les risques inhérents à chroot() qui se contente de modifier un attribut du descripteur de processus avec un nouveau chemin.Au niveau de l'usage, LXC est assez semblable à une machine virtuelle (attention, nous parlons bien de l'usage, pas des mécanismes sous-jacents). Il n'est pas vraiment utilisé par des développeurs, mais plus par des administrateurs pour créer des conteneurs de systèmes Linux complets beaucoup moins volatiles que les conteneurs type Docker. Vous pourrez retrouver dans [11] un exemple d’instanciation d’un conteneur LXC via LXD en mode standalone (c’est-à-dire sans notion de cluster comme le présent article).

lxc.drawio-s

Fig. 2 : LXC.

2.4 La couche KVM / QEMU

Pour la virtualisation, LXD va s’appuyer sur le couple KVM / QEMU. La figure 3 présente les imbrications entre ces deux composants. Commençons par installer QEMU sur notre machine (le noyau par défaut intègre déjà la couche KVM) :

root@node1:~# apt install --no-install-recommends qemu-system libvirt-clients libvirt-daemon-system

QEMU s’appuie sur KVM pour exploiter le matériel. En effet, QEMU est un hyperviseur de type 2. C'est-à-dire qu’il s’exécute sous la forme d’un processus en espace utilisateur. En effet, si nous listons les programmes en exécution sur le nœud accueillant notre machine virtuelle, nous constaterons que nous avons un processus en cours d’exécution nommé qemu-system-x86_64 qui va la piloter. QEMU va s’appuyer sur la notion de « passthrough » pour optimiser les performances de la machine virtuelle via KVM. Pour bien comprendre ce principe, il faut savoir qu’en plus des hyperviseurs de type 2 déjà mentionnés, il existe des hyperviseurs de type 1 tels que KVM. Un tel hyperviseur dispose d’un accès direct au matériel, ce qui le rend plus performant qu’un type 2, mais nécessite des extensions de virtualisation au niveau processeur (ce qui est quand même majoritairement le cas de nos jours). La présence de KVM sous Linux se manifeste par l’exécution d’un module noyau nommé kvm (kvm.ko) :

root@node1:~# lsmod | grep   kvm
kvm_intel             380928 0
kvm                  1146880 1 kvm_intel

Lorsque ce module est chargé, un périphérique bloc /dev/kvm est créé permettant à QEMU d’adresser directement le matériel réel (et pas celui émulé dans son espace), ce qui améliore les performances. C’est la mécanique par défaut de LXD lorsqu’il doit instancier une machine virtuelle. Il lance un processus qemu-system-x86_64 qui va s’appuyer sur KVM pour optimiser l’accès au matériel.

kvmqemu.drawio

Fig. 3 : Le couple KVM / QEMU.

3. Configuration du cluster LXD

Deux cas de figure conditionnent l’installation de LXD. Le premier cas est l’initialisation du cluster. C’est la configuration à réaliser sur le premier nœud. Le second cas est le recrutement du nœud dans un cluster existant. On doit l’appliquer sur tous les nœuds souhaitant rejoindre le cluster. Ces deux installations nécessitent l’installation du paquet snap lxd. Nous allons commencer par créer le premier nœud du cluster.

3.1 Initialisation du cluster

Nous décidons arbitrairement que le premier nœud sera node1. La première chose à faire est d’installer le paquet snap lxd :

root@node1:~# snap install lxd
lxd 5.18-da72b8b from Canonical✓ installed

L’outil en ligne de commandes pour piloter le cluster se nomme lxd. Pour initialiser la configuration, il faut invoquer le paramètre init. Une fois la commande invoquée, lxd vous posera quelques questions pour configurer le cluster.

root@node1:~# lxd init

La première question est de savoir si vous voulez fonctionner en mode cluster ou standalone (un seul nœud isolé). Ici, contrairement à [11] nous créons un cluster :

Would you like to use LXD clustering? (yes/no) [default=no]: yes

En cas de machine domiciliée sur plusieurs réseaux, lxd propose de choisir l’adresse à laquelle contacter le nœud pour les tâches d’administration. Nous n’avons qu’une seule adresse sur la machine, nous laissons donc le paramètre par défaut.

What IP address or DNS name should be used to reach this server? [default=192.168.45.11]:

La question suivante est de savoir si nous rejoignions un cluster existant. Ici, nous configurons le premier nœud donc non.

Are you joining an existing cluster? (yes/no) [default=no]: no

Il faut ensuite définir le nom de la machine au sein du cluster. Nous laissons le paramètre par défaut.

What member name should be used to identify this server in the cluster? [default=node1]:

Cette question propose de configurer un stockage local pour accueillir les conteneurs et machines virtuelles. Ici nous allons répondre oui et les questions suivantes vont nous permettre de le caractériser.

Do you want to configure a new local storage pool? (yes/no) [default=yes]: yes

Ici, nous devons choisir le mécanisme de stockage. Nous avons le choix entre plusieurs stockages à portée locale : dir, lvm et btrfs. Le pilote dir est le plus simple. Il s’agit de stocker les machines virtuelles et conteneurs à plat sur le système de fichiers existant. Nous allons l’utiliser dans l’article, car c’est le format le plus simple pour aller voir ce que LXD stocke sur le disque. Le pilote LVM [12] permet de passer un VG (Volume Group) à LXD. Chaque conteneur ou machine virtuelle sera stocké sur un LV (Logical Volume). Un système de fichiers à la discrétion de l’utilisateur sera instancié sur le LV. Enfin, btrfs propose de créer un fichier bloc sur le système de fichiers existant (il est impossible de lui passer un périphérique bloc natif). Ce n’est pas très efficient en termes de performances, mais cela permet de profiter des fonctionnalités de btrfs. Nous choisissons donc dir :

Name of the storage backend to use (dir, lvm, btrfs) [default=btrfs]: dir

LXD peut s’interfacer avec un système de fichiers distribué Ceph [13,14]. C’est ce qui est sous-entendu par la possibilité de s’attacher un volume distant.

Do you want to configure a new remote storage pool? (yes/no) [default=no]: no

Concernant le provisionnement, LXD propose de s’attacher à un serveur MaaS (Metal as a Service). MaaS est un système de déploiement automatique de serveurs physiques (le Metal de MaaS) s’appuyant, entre autres, sur DHCP / PXE / Bootp. Ici nous ne le souhaitons pas.

Would you like to connect to a MAAS server? (yes/no) [default=no]: no

Nous passons à la configuration réseau. La première question est de savoir si nous nous attachons à un pont existant pour raccorder les machines virtuelles et conteneurs au réseau. Ici, nous répondons oui, car nous allons utiliser le pont configuré dans la partie 2.1.

Would you like to configure LXD to use an existing bridge or host interface? (yes/no) [default=no]: yes

Nous nommons explicitement le pont à utiliser, ici br0 :

Name of the existing bridge or host interface: br0

Le dernier paramètre à configurer est de savoir si vous voulez que les images utilisées par un conteneur soient mises à jour entre deux instanciations.

Would you like stale cached images to be updated automatically? (yes/no) [default=yes]: yes

Enfin, lxd init propose de faire un dump en YAML de la configuration réalisée :

Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: yes
config:
  core.https_address: 192.168.45.11:8443
networks: []
storage_pools:
- config: {}
  description: ""
  name: local
  driver: dir
profiles:
- config: {}
  description: ""
  devices:
    eth0:
      name: eth0
      nictype: bridged
      parent: br0
      type: nic
    root:
      path: /
      pool: local
      type: disk
  name: default
projects: []
cluster:
  server_name: node1
  enabled: true
  member_config: []
  cluster_address: ""
  cluster_certificate: ""
  server_address: ""
  cluster_password: ""
  cluster_certificate_path: ""
  cluster_token: ""

On y retrouve bien tous les paramètres de configuration renseignés précédemment. Ce fichier vous permet de refaire l’installation en mode non interactif au cas où. Pour préparer le recrutement du second nœud node2, nous allons générer un jeton qu’il va falloir passer lors de son initialisation :

root@node1:~# lxc cluster add node2
Member node2 join token:
eyJzZXJ2ZXJfbmFtZSI6Im5vZGUyIiwiZmluZ2VycHJpbnQiOiIzZTI2MjcwODg1NzE1YjdhMTI2OWE0NzZmZDNkNGY2OWVlMzA5NzkwZjhiYzcxNzUwZjg1ODVjNWZjODU0YzRiIiwiYWRkcmVzc2VzIjpbIjE5Mi4xNjguNDUuMTE6ODQ0MyJdLCJzZWNyZXQiOiJmZjQxMjY2ZmQyZTYxODJiYTJlNjlmMzcyMWVhMmExZjZkOWYwZjVjMGQwNWE4ODE1NzUyMjE5MDY1MGVkNDc5IiwiZXhwaXJlc19hdCI6IjIwMjMtMTAtMTZUMjA6NDA6MzkuMzIzMjQ4MTU5KzAyOjAwIn0=

Passons au second nœud node2.

3.2 Recrutement d’un nœud

Nous allons ajouter un nœud dans notre cluster. À l’instar de la création du nœud initial, nous allons commencer par invoquer un init :

root@node2:~# lxd init

Et configurer le nœud en cluster :

Would you like to use LXD clustering? (yes/no) [default=no]: yes

Nous validons l’IP par défaut détectée par le configurateur de LXD :

What IP address or DNS name should be used to reach this server? [default=192.168.45.12]:

C’est à cette étape que l’installation diffère par rapport à la section précédente. Cette fois-ci, nous indiquons rejoindre un cluster existant :

Are you joining an existing cluster? (yes/no) [default=no]: yes

Et nous renseignons le jeton généré à la fin de la section précédente :

Do you have a join token? (yes/no/[token]) [default=no]: yes
Please provide join token: eyJzZXJ2ZXJfbmFtZSI6Im5vZGUyIiwiZmluZ2VycHJpbnQiOiIzZTI2MjcwODg1NzE1YjdhMTI2OWE0NzZmZDNkNGY2OWVlMzA5NzkwZjhiYzcxNzUwZjg1ODVjNWZjODU0YzRiIiwiYWRkcmVzc2VzIjpbIjE5Mi4xNjguNDUuMTE6ODQ0MyJdLCJzZWNyZXQiOiJmZjQxMjY2ZmQyZTYxODJiYTJlNjlmMzcyMWVhMmExZjZkOWYwZjVjMGQwNWE4ODE1NzUyMjE5MDY1MGVkNDc5IiwiZXhwaXJlc19hdCI6IjIwMjMtMTAtMTZUMjA6NDA6MzkuMzIzMjQ4MTU5KzAyOjAwIn0=

On valide nos choix :

All existing data is lost when joining a cluster, continue? (yes/no) [default=no] yes

On indique que nous utilisons le stockage local :

Choose "source" property for storage pool "local":

Et on fait un dump de la configuration en YAML :

Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: yes
config: {}
networks: []
storage_pools: []
profiles: []
projects: []
cluster:
  server_name: node2
  enabled: true
  member_config:
  - entity: storage-pool
    name: local
    key: source
    value: ""
    description: '"source" property for storage pool "local"'
  cluster_address: 192.168.45.11:8443
  cluster_certificate: |
    -----BEGIN CERTIFICATE-----
    MIIB4jCCAWegAwIBAgIRANoTUUJ84+NNJBBVahcO5W0wCgYIKoZIzj0EAwMwIzEM
    MAoGA1UEChMDTFhEMRMwEQYDVQQDDApyb290QG5vZGUxMB4XDTIzMTAxNjA3NDgw
    NloXDTMzMTAxMzA3NDgwNlowIzEMMAoGA1UEChMDTFhEMRMwEQYDVQQDDApyb290
    QG5vZGUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE/r1Kn0gJ49I0rEx4kGDK+hCo
    2Pz+t6cL1Q1S3dMNqv435lxF1u13j8evGY6qgxoxpBlfbv1Suc+HkevoYNYvwGA/
    dHXhepC8c+ydFpGcFELuNBpC5pp07hM2wLRY2iIyo18wXTAOBgNVHQ8BAf8EBAMC
    BaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAoBgNVHREEITAf
    ggVub2RlMYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATAKBggqhkjOPQQDAwNpADBm
    AjEAoSIGjAdlm0jr39LFjvJiv7x0uTFhH49KW5Gd7987dNXuUrvVDFC0LSwI/yMd
    I35XAjEAuXXk6Y6Ps19cMhNfVHUfRNWPs01KLlaEnEejILdnIyqgpCLVgkxDlube
    A/Mk/mbe
    -----END CERTIFICATE-----
  server_address: 192.168.45.12:8443
  cluster_password: ""
  cluster_certificate_path: ""
  cluster_token: ""

Nous allons maintenant vérifier l’état du cluster. Peu importe le nœud sur lequel on lance les commandes, la configuration est distribuée. Commençons par vérifier l’état du cluster :

root@node1:~# lxc cluster list
+-------+----------------------------+------------------+--------------+----------------+-------------+--------+-------------------+
| NAME  |            URL             |      ROLES       | ARCHITECTURE | FAILURE DOMAIN | DESCRIPTION | STATE  |      MESSAGE      |
+-------+----------------------------+------------------+--------------+----------------+-------------+--------+-------------------+
| node1 | https://192.168.45.11:8443 | database-leader  | x86_64       | default        |             | ONLINE | Fully operational |
|       |                            | database         |              |                |             |        |                   |
+-------+----------------------------+------------------+--------------+----------------+-------------+--------+-------------------+
| node2 | https://192.168.45.12:8443 | database-standby | x86_64       | default        |             | ONLINE | Fully operational |
+-------+----------------------------+------------------+--------------+----------------+-------------+--------+-------------------+

Le stockage :

root@node1:~# lxc storage list
+-------+--------+-------------+---------+---------+
| NAME  | DRIVER | DESCRIPTION | USED BY | STATE   |
+-------+--------+-------------+---------+---------+
| local | dir    |             | 1       | CREATED |
+-------+--------+-------------+---------+---------+

Le réseau :

root@node1:~# lxc network list
+--------+----------+---------+------+------+-------------+---------+-------+
| NAME   |   TYPE   | MANAGED | IPV4 | IPV6 | DESCRIPTION | USED BY | STATE |
+--------+----------+---------+------+------+-------------+---------+-------+
| br0    | bridge   | NO      |      |      |             | 1       |       |
+--------+----------+---------+------+------+-------------+---------+-------+
| enp0s3 | physical | NO      |      |      |             | 0       |       |
+--------+----------+---------+------+------+-------------+---------+-------+

Le cluster est opérationnel, nous pouvons créer nos premiers conteneurs et machines virtuelles.

4. Gestion des conteneurs et machines virtuelles

LXD vient avec un magasin d’images utilisables directement. Pour les lister, il faut utiliser la commande lxc image avec l’argument list. Nous mettons en forme l’affichage avec -c lat pour sélectionner l’alias (nom) de l’image, l’architecture et le type (machine virtuelle ou conteneur).

root@node1:~# lxc image list images: -c lat
+------------------------------------------+--------------+-----------------+
|                  ALIAS                   | ARCHITECTURE |      TYPE       |
+------------------------------------------+--------------+-----------------+
| almalinux/8 (3 more)                     | x86_64       | CONTAINER       |
+------------------------------------------+--------------+-----------------+
| almalinux/8 (3 more)                     | x86_64       | VIRTUAL-MACHINE |
+------------------------------------------+--------------+-----------------+
| almalinux/8/arm64 (1 more)               | aarch64      | CONTAINER       |
+------------------------------------------+--------------+-----------------+
| almalinux/8/cloud (1 more)               | x86_64       | CONTAINER       |
+------------------------------------------+--------------+-----------------+
| almalinux/8/cloud (1 more)               | x86_64       | VIRTUAL-MACHINE |
+------------------------------------------+--------------+-----------------+

Les deux points après images sont importants, car si on ne les spécifie pas, lxc va lister les images locales et non celles du magasin. Lançons notre premier conteneur.

4.1 Lancement de conteneurs

Nous allons exécuter notre premier conteneur de la façon la plus simple possible. Nous commençons avec un conteneur Debian 12 récupéré depuis le magasin répondant au nom de container1.

root@node1:~# lxc launch images:debian/12 container1
Creating container1
Starting container1

Créons un second conteneur nommé container2 (quelle imagination !) :

root@node1:~# lxc launch images:debian/12 container2
Creating container2
Starting container2

Regardons comment se sont répartis nos conteneurs :

root@node1:~# lxc list
+------------+---------+-----------------------+------+-----------+-----------+----------+
|    NAME    | STATE   |         IPV4          | IPV6 |   TYPE    | SNAPSHOTS | LOCATION |
+------------+---------+-----------------------+------+-----------+-----------+----------+
| container1 | RUNNING | 192.168.45.100 (eth0) |      | CONTAINER | 0         | node1    |
+------------+---------+-----------------------+------+-----------+-----------+----------+
| container2 | RUNNING | 192.168.45.101 (eth0) |      | CONTAINER | 0         | node2    |
+------------+---------+-----------------------+------+-----------+-----------+----------+

Ils ont bien été orchestrés sur node1 et node2. On retrouve leur système de fichiers en mode dir dans le répertoire suivant (pour node1) :

root@node1:~# ls /var/snap/lxd/common/lxd/storage-pools/local/containers/container1/rootfs/
bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var

Cependant, un détail est frappant : les conteneurs ont chacun récupéré une adresse IP. En effet, un serveur DHCP est installé sur frontal et sert des adresses IP sur le domaine de diffusion Ethernet correspondant à intnet1. En effet, dans la section 2.1, nous avons vu que chacun des nœuds node1 et node2 embarque un pont intégrant leur interface réseau. À partir de ce moment-là, toutes les interfaces raccordées au pont sont également sur le domaine de diffusion Ethernet de intnet. Nous rappelons que le frontal embarque également un serveur DHCP qui sert l’étendue 192.168.45.100 à 192.168.45.200, ce qui correspond aux adresses récupérées par node1 et node2. Si nous examinons la composition du pont sur node1, nous avons la sortie suivante :

root@node1:~# brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.7e1d03eb3881       no              enp0s3
                                                        veth5204af45

Nous voyons que le pont est composé de l’interface réseau « réelle » du nœud enp0s3 et d’une autre interface veth5204af45 correspondant à l’interface eth0 de container1. Connectons-nous au container1 pour voir si le réseau fonctionne :

root@node1:~# lxc exec container1 -- /bin/bash
root@container1:~# ping www.google.fr
PING www.google.fr (172.217.20.163) 56(84) bytes of data.
64 bytes from par10s49-in-f3.1e100.net (172.217.20.163): icmp_seq=1 ttl=118 time=3.00 ms
64 bytes from par10s49-in-f3.1e100.net (172.217.20.163): icmp_seq=2 ttl=118 time=3.35 ms
64 bytes from waw02s07-in-f3.1e100.net (172.217.20.163): icmp_seq=3 ttl=118 time=3.40 ms

Nous avons réalisé une première instanciation simple de deux conteneurs.

4.2 Gestion des ressources des conteneurs

Pour évaluer la gestion des ressources par nos conteneurs et machines virtuelles, nous allons installer l’utilitaire stress dans chacun d’eux. Installons-le dans container1, il faudra répéter cette installation pour chaque conteneur ou machine virtuelle instrumenté :

root@node1:~# lxc exec container1 -- apt-get -qq -y update
root@node1:~# lxc exec container1 -- apt-get -qq -y install stress
Selecting previously unselected package stress.
(Reading database ... 11255 files and directories currently installed.)
Preparing to unpack .../stress_1.0.7-1_amd64.deb ...
Unpacking stress (1.0.7-1) ...
Setting up stress (1.0.7-1) ...

Reprenons notre conteneur container1. Lançons un stress qui met quatre CPU à 100% :

root@node1:~# lxc exec container1 -- stress -c 4
stress: info: [682] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd

Regardons l’empreinte sur node1 avec un top :

root@node1:~# top
top - 03:14:43 up 6 min, 2 users, load average: 9.09, 4.94, 2.03
Tasks: 150 total, 10 running, 140 sleeping,   0 stopped,   0 zombie
%Cpu(s):100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem :   7931.8 total,   6909.8 free,    541.3 used,    712.3 buff/cache
MiB Swap:   2109.0 total,   2109.0 free,      0.0 used.   7390.5 avail Mem
 
    PID USER      PR  NI    VIRT    RES    SHR S %CPU   %MEM   TIME+   COMMAND
   1897 1000000   20   0    3364    112      0 R 100.0   0.0   3:24.34 stress
   1898 1000000   20   0    3364    112      0 R 100.0   0.0   3:24.35 stress
   1900 1000000   20   0    3364    112      0 R 100.0   0.0   3:24.21 stress
   1896 1000000   20   0    3364    112      0 R 100.0   0.0   3:24.30 stress

Nous avons quatre processus qui prennent chacun 100% d’un CPU. Par défaut, LXD n’impose aucune limite aux ressources consommées par les conteneurs. Changeons la configuration du conteneur container1 pour le restreindre à deux CPU :

root@node1:~# lxc config set container1 limits.cpu 2

Et examinons la sortie du top :

root@node1:~# top
top - 03:25:19 up 0 min, 2 users, load average: 1.78, 0.48, 0.16
Tasks: 163 total,   5 running, 158 sleeping,   0 stopped,   0 zombie
%Cpu(s): 14.4 us, 0.2 sy, 0.0 ni, 85.2 id, 0.0 wa, 0.0 hi, 0.1 si, 0.0 st
MiB Mem :   7931.8 total,   7152.0 free,    521.5 used,    487.1 buff/cache
MiB Swap:   2109.0 total,   2109.0 free,      0.0 used.   7410.3 avail Mem
 
    PID USER      PR  NI    VIRT    RES    SHR S %CPU  %MEM     TIME+ COMMAND
   1303 1000000   20   0    3364    108      0 R 50.5   0.0   0:19.77 stress
   1301 1000000   20   0    3364    108      0 R 49.8   0.0   0:07.95 stress
   1302 1000000   20   0    3364    108      0 R 49.8   0.0   0:07.96 stress
   1304 1000000   20   0    3364    108      0 R 49.8   0.0   0:08.29 stress

Cette fois, les quatre processus utilisent chacun la moitié d’un CPU, soit 2 CPU au total. La limitation des ressources s’opère via les cgroups [15]. On notera qu’on peut limiter la mémoire de la même manière.                                                            

4.3 Lancement de machines virtuelles

Comme nous l’avons évoqué précédemment, il est également possible d’instancier des machines virtuelles. Pour créer des machines virtuelles, il faut d’abord installer les paquets suivants sur les nœuds du cluster LXD afin de disposer du couple KVM / QEMU :

root@node1:~# apt install --no-install-recommends qemu-system libvirt-clients libvirt-daemon-system

Une fois ces paquets installés, nous stoppons et détruisons nos conteneurs :

root@node1:~# lxc stop container1 container2
root@node1:~# lxc delete container1 container2

Puis nous recréons deux machines virtuelles basées sur la même image que les conteneurs précédents :

root@node1:~# lxc launch images:debian/12 vm1 --vm
Creating vm1
Starting vm1
root@node1:~# lxc launch images:debian/12 vm2 --vm
Creating vm2
Starting vm2

Listons le résultat :

root@node1:~# lxc list
+------+---------+-------------------------+------+-----------------+-----------+----------+
| NAME | STATE   |          IPV4           | IPV6 |     TYPE        | SNAPSHOTS | LOCATION |
+------+---------+-------------------------+------+-----------------+-----------+----------+
| vm1  | RUNNING | 192.168.45.102 (enp5s0) |      | VIRTUAL-MACHINE | 0         | node1    |
+------+---------+-------------------------+------+-----------------+-----------+----------+
| vm2  | RUNNING | 192.168.45.103 (enp5s0) |      | VIRTUAL-MACHINE | 0         | node2    |
+------+---------+-------------------------+------+-----------------+-----------+----------+

Cette fois, nous voyons que dans la colonne TYPE il s’agit bien de machines virtuelles et non plus de conteneurs. Listons les processus en exécution sur node1 :

root@node1:~# ps -auxwww | grep qemu
lxd         1030 90.0 4.2 1690564 348696 ?     Sl   08:54   0:32 /snap/lxd/26093/bin/qemu-system-x86_64 -S -name vm1 -uuid 90543526-2a80-4fd8-b1e8-c08b703d0d5e -daemonize -cpu host,hv_passthrough -nographic -serial chardev:console -nodefaults -no-user-config -sandbox on,obsolete=deny,elevateprivileges=allow,spawn=allow,resourcecontrol=deny -readconfig /var/snap/lxd/common/lxd/logs/vm1/qemu.conf -spice unix=on,disable-ticketing=on,addr=/var/snap/lxd/common/lxd/logs/vm1/qemu.spice -pidfile /var/snap/lxd/common/lxd/logs/vm1/qemu.pid -D /var/snap/lxd/common/lxd/logs/vm1/qemu.log -smbios type=2,manufacturer=Canonical Ltd.,product=LXD -runas lxd

J’attire l’attention du lecteur sur l’argument suivant : -cpu host,hv_passthrough qui illustre l’explication donnée dans la section 2.4. C’est ici qu’intervient KVM. QEMU indique à la machine virtuelle d’accéder directement au CPU via KVM et non à une émulation qu’il lui présenterait.

4.4 Gestion des ressources des machines virtuelles

À l’instar des conteneurs, il faut être attentif à l’utilisation des ressources par la machine virtuelle. Lançons deux processus à l'intérieur de notre machine virtuelle qui mettent un cœur à 100% :

root@node1:~# lxc exec vm1 -- stress -c 2
stress: info: [437] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd

Regardons le résultat dans la machine virtuelle avec top :

root@node1:~# lxc exec vm1 -- top
top - 08:20:01 up 1 min, 0 user, load average: 1.65, 0.57, 0.20
Tasks: 96 total,   3 running, 93 sleeping,   0 stopped,   0 zombie
%Cpu(s): 99.4 us, 0.6 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem :    955.9 total,    592.1 free,    247.9 used,    268.6 buff/cache
MiB Swap:     0.0 total,     0.0 free,     0.0 used.    708.0 avail Mem
 
    PID USER     PR  NI    VIRT    RES    SHR S %CPU  %MEM     TIME+ COMMAND
    403 root     20   0    3364    108     0  R 49.7   0.0   0:05.60 stress
    404 root     20   0    3364    108     0  R 49.7   0.0   0:05.59 stress

Nous avons deux processus utilisant chacun environ 50% du processeur. Et effectivement, LXD n’a alloué qu’un seul CPU à notre machine virtuelle :

root@node1:~# lxc exec vm1 -- nproc
1

Sur la machine hôte, nous voyons que le processus utilise environ 100% du CPU, soit un cœur complet :

root@node1:~# top
top - 10:27:01 up 1:34, 1 user, load average: 1.00, 1.00, 0.68
Tasks: 91 total,   1 running, 90 sleeping,   0 stopped,   0 zombie
%Cpu(s):100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem :   7933.2 total,   5229.8 free,   1327.0 used,   2340.4 buff/cache
MiB Swap:   2109.0 total,   2109.0 free,     0.0 used.   6606.2 avail Mem
 
    PID USER     PR   NI    VIRT    RES    SHR S %CPU %MEM      TIME+ COMMAND
   1561 lxd       20  0  1726436 851048 751808 S 100.0 10.5   8:21.99 qemu-system-x86

Relançons notre machine virtuelle en indiquant l’utilisation de deux CPU :

root@node1:~# lxc launch images:debian/12 vm1 --vm --target node2 --config limits.cpu=2

Lançons le même stress :

root@node1:~# lxc exec vm1 -- stress -c 2
stress: info: [409] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
Examinons le résultat de top dans la machine virtuelle :
root@node1:~# lxc exec vm1 -- top
top - 08:32:57 up 3 min, 0 user, load average: 1.54, 0.67, 0.26
Tasks: 102 total,   3 running, 99 sleeping,   0 stopped,   0 zombie
%Cpu(s): 71.4 us, 14.3 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 14.3 st
MiB Mem :    955.5 total,    581.1 free,    258.4 used,    268.9 buff/cache
MiB Swap:     0.0 total,     0.0 free,     0.0 used.    697.1 avail Mem
 
    PID USER     PR  NI    VIRT    RES    SHR S %CPU  %MEM     TIME+ COMMAND
    410 root     20   0    3364    108     0  R 93.8   0.0   1:04.86 stress
    411 root     20   0    3364    108     0  R 93.8   0.0   1:04.69 stress

Nous avons bien deux processus utilisant environ 100% du CPU, c'est-à-dire deux cœurs. En effet, cette fois-ci LXD a dédié deux cœurs à la machine virtuelle :

root@node1:~# lxc exec vm1 -- nproc
2

Regardons à nouveau l’utilisation du CPU sur l’hôte :

root@node1:~# lxc exec vm1 -- top
top - 10:37:56 up 1:45, 1 user, load average: 0.60, 1.02, 0.91
Tasks: 92 total,   1 running, 91 sleeping,   0 stopped,   0 zombie
%Cpu(s): 49.8 us, 0.6 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem :   7933.2 total,   5220.2 free,   1334.0 used,   2333.4 buff/cache
MiB Swap:   2109.0 total,   2109.0 free,     0.0 used.   6599.2 avail Mem
 
    PID USER     PR   NI    VIRT    RES    SHR S %CPU  %MEM     TIME+ COMMAND
   1744 lxd       20  0  1768328 855272 741672 S 198.7 10.5   8:32.76 qemu-system-x86

Le processus qemu-system-x86 utilise bien 200% du CPU c'est-à-dire deux cœurs. Ici c’est donc le problème inverse des conteneurs, par défaut LXD ne met qu’un seul cœur aux machines virtuelles et limits.cpu va nous servir à monter cette limite.

Conclusion

Pour conclure sur LXD, nous pouvons dire que cet orchestrateur est une alternative très intéressante aux produits un peu plus lourds cités au début de l’article. LXD implémente un orchestrateur dont les fonctionnalités sont directement liées aux briques présentes sur la machine exécutant nos conteneurs et nos machines virtuelles. Par exemple, si un système de fichiers ne supporte pas les snapshots, alors LXD ne proposera pas l’option. De même, si KVM n’est pas installé sur les nœuds hôtes, nous ne pourrons pas exécuter de machines virtuelles. Cette forte adhérence au système sous-jacent fait de LXD un orchestrateur extrêmement léger en termes d’administration et d’utilisation, pourvu que notre besoin rentre dans son périmètre fonctionnel.

Références

[1] D. Gourmel, « Proxmox : vis ma vie d’éleveur de machines virtuelles », Linux Pratique n°134, novembre 2022 : https://connect.ed-diamond.com/linux-pratique/lp-134/proxmox-vis-ma-vie-d-eleveur-de-machines-virtuelles

[2] N. Greneche, « Monter sa plateforme Cloud avec OpenNebula », Linux Pratique n°128, novembre 2021 : https://connect.ed-diamond.com/linux-pratique/lp-128/monter-sa-plateforme-cloud-avec-opennebula

[3] N. Greneche, « Libre-service de machines virtuelles avec OpenNebula », Linux Pratique n°130, mars 2022 : https://connect.ed-diamond.com/linux-pratique/lp-130/libre-service-de-machines-virtuelles-avec-opennebula

[4] https://access.redhat.com/documentation/fr-fr/red_hat_enterprise_linux/9/html/using_selinux/index

[5] E. Gaspar, « Isolez vos processus grâce à AppArmor », Linux Pratique n°113, mai 2019 :
https://connect.ed-diamond.com/Linux-Pratique/lp-113/isolez-vos-processus-grace-a-apparmor

[6] F. Maury, « Namespaces et seccomp BPF : un zoom sur la conteneurisation Linux », MISC n°102, mars 2019 : https://connect.ed-diamond.com/MISC/misc-102/namespaces-et-seccomp-bpf-un-zoom-sur-la-conteneurisation-linux

[7] R. Koucha, « Contrôle des processus avec les cgroups », GNU/Linux Magazine n°141, septembre 2011 : https://connect.ed-diamond.com/GNU-Linux-Magazine/glmf-141/controle-des-processus-avec-les-cgroups

[8] R. Koucha, « Les namespaces ou l’art de se démultiplier », GNU/Linux Magazine n°239, juillet 2020 : https://connect.ed-diamond.com/GNU-Linux-Magazine/glmf-239/les-namespaces-ou-l-art-de-se-demultiplier

[9] R. Koucha, « Les structures de données des namespaces dans le noyau », GNU/Linux Magazine n°243, décembre 2020 : https://connect.ed-diamond.com/GNU-Linux-Magazine/glmf-243/les-structures-de-donnees-des-namespaces-dans-le-noyau

[10] R. Koucha, « Le fonctionnement des namespaces dans le noyau », GNU/Linux Magazine n°245, février 2021 : https://connect.ed-diamond.com/GNU-Linux-Magazine/glmf-245/le-fonctionnement-des-namespaces-dans-le-noyau

[11] N. Greneche, « La mise en conteneur d’une application ou d’un service avec LXD », Linux Pratique Hors-Série n°45, juin 2019 : https://connect.ed-diamond.com/Linux-Pratique/lphs-045/la-mise-en-conteneur-d-une-application-ou-d-un-service-avec-lxd

[12] S. Maccagnoni-Munch, « Un stockage plus souple avec Logical Volume Manager », GNU/Linux Magazine Hors-Série n°72, mai 2014 : https://connect.ed-diamond.com/GNU-Linux-Magazine/glmfhs-072/un-stockage-plus-souple-avec-logical-volume-manager

[13] O. Delhomme, « Présentation et installation du système de stockage réparti Ceph », GNU/Linux Magazine n°179, février 2015 : https://connect.ed-diamond.com/GNU-Linux-Magazine/glmf-179/presentation-et-installation-du-systeme-de-stockage-reparti-ceph

[14] O. Delhomme, « Mise en œuvre de Ceph », GNU/Linux Magazine n°180, mars 2015 :
https://connect.ed-diamond.com/GNU-Linux-Magazine/GLMF-180/Mise-en-aeuvre-de-Ceph

[15] J. Delamarche, « Contrôle des processus avec les cgroups », GNU/Linux Magazine n°141, septembre 2011 : https://connect.ed-diamond.com/GNU-Linux-Magazine/glmf-141/controle-des-processus-avec-les-cgroups



Article rédigé par

Par le(s) même(s) auteur(s)

Équilibrage de charge avec IPVS

Magazine
Marque
Linux Pratique
HS n°
Numéro
55
Mois de parution
octobre 2022
Spécialité(s)
Résumé

IP Virtual Server (IPVS) est un équilibreur de charge agissant au niveau 4 du modèle OSI. Il est implémenté sous forme d’un module noyau s’appuyant sur le framework Netfilter, ce qui le rend efficace sur l’équilibrage des services par rapport à leurs ports TCP/UDP, mais totalement agnostique aux protocoles applicatifs transportés (LDAP, HTTP, etc.).

Libre-service de machines virtuelles avec OpenNebula

Magazine
Marque
Linux Pratique
Numéro
130
Mois de parution
mars 2022
Spécialité(s)
Résumé

Dans un article précédent, nous avons mis en place une infrastructure OpenNebula basique [1]. Nous allons maintenant configurer cette plateforme pour proposer aux utilisateurs un guichet de libre-service de machines virtuelles. L’idée est que les utilisateurs puissent créer eux-mêmes leurs machines virtuelles.

Monter sa plateforme Cloud avec OpenNebula

Magazine
Marque
Linux Pratique
Numéro
128
Mois de parution
novembre 2021
Spécialité(s)
Résumé

OpenNebula est un orchestrateur libre de machines virtuelles (KVM, VMWare) et conteneurs lourds (LXC). Son rôle est d’organiser et placer les machines virtuelles sur une infrastructure physique. C’est un peu le chaînon manquant entre le serveur physique et les orchestrateurs de conteneurs applicatifs types Kubernetes.

Les derniers articles Premiums

Les derniers articles Premium

Sécurisez vos applications web : comment Symfony vous protège des menaces courantes

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Les frameworks tels que Symfony ont bouleversé le développement web en apportant une structure solide et des outils performants. Malgré ces qualités, nous pouvons découvrir d’innombrables vulnérabilités. Cet article met le doigt sur les failles de sécurité les plus fréquentes qui affectent même les environnements les plus robustes. De l’injection de requêtes à distance à l’exécution de scripts malveillants, découvrez comment ces failles peuvent mettre en péril vos applications et, surtout, comment vous en prémunir.

Bash des temps modernes

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Les scripts Shell, et Bash spécifiquement, demeurent un standard, de facto, de notre industrie. Ils forment un composant primordial de toute distribution Linux, mais c’est aussi un outil de prédilection pour implémenter de nombreuses tâches d’automatisation, en particulier dans le « Cloud », par eux-mêmes ou conjointement à des solutions telles que Ansible. Pour toutes ces raisons et bien d’autres encore, savoir les concevoir de manière robuste et idempotente est crucial.

Présentation de Kafka Connect

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Un cluster Apache Kafka est déjà, à lui seul, une puissante infrastructure pour faire de l’event streaming… Et si nous pouvions, d’un coup de baguette magique, lui permettre de consommer des informations issues de systèmes de données plus traditionnels, tels que les bases de données ? C’est là qu’intervient Kafka Connect, un autre composant de l’écosystème du projet.

Le combo gagnant de la virtualisation : QEMU et KVM

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

C’est un fait : la virtualisation est partout ! Que ce soit pour la flexibilité des systèmes ou bien leur sécurité, l’adoption de la virtualisation augmente dans toutes les organisations depuis des années. Dans cet article, nous allons nous focaliser sur deux technologies : QEMU et KVM. En combinant les deux, il est possible de créer des environnements de virtualisation très robustes.

Les listes de lecture

8 article(s) - ajoutée le 01/07/2020
Découvrez notre sélection d'articles pour faire vos premiers pas avec les conteneurs, apprendre à les configurer et les utiliser au quotidien.
11 article(s) - ajoutée le 02/07/2020
Si vous recherchez quels sont les outils du DevOps et comment les utiliser, cette liste est faite pour vous.
8 article(s) - ajoutée le 02/07/2020
Il est essentiel d'effectuer des sauvegardes régulières de son travail pour éviter de perdre toutes ses données bêtement. De nombreux outils sont disponibles pour nous assister dans cette tâche.
Voir les 60 listes de lecture

Abonnez-vous maintenant

et profitez de tous les contenus en illimité

Je découvre les offres

Déjà abonné ? Connectez-vous