Support Ukrain
Adaltas logoAdaltasAdaltas logoAdaltas
NixOS : Activer le support des machines virtuelles de LXD avec Flakes

NixOS : Activer le support des machines virtuelles de LXD avec Flakes

COTTART Kellian

By COTTART Kellian

13 mai 2022

Catégories
Hack
Formation
Tags
GitHub
Enseignement et tutorial
Linux
LXD
Packaging
VM
NixOS
Open source

Nixpkgs est une collection grandissante de packages pour Nix et NixOS. Même avec plus de 80,000 packages, il est pourtant commun d’avoir besoin d’une fonctionnalité qui n’existe pas encore.

Cette année, nous avons écrit un tutoriel expliquant la création de son propre package pour NixOS. L’incorporation de ce package dans le système était compliquée et nécessitait d’avoir un suivi du package qu’on implémente.

Prenons un exemple pratique : LXD est un gestionnaire de conteneurs et de machines virtuelles. Il supporte les machines virtuelles nativement depuis LXD 4.0. Cependant, sous NixOS, la fonctionnalité n’est pas supportée, et nous devons trouver des solutions palliatives pour l’utiliser. Pour permettre à LXD de lancer des machines virtuelles sur NixOS, nous avons besoin d’une correction à la fois reproductible et portable.

Pour ce faire, nous allons utiliser la fonctionnalité lxd-agent réglant ce problème. Celle-ci a été publiée par astridyu, une contributrice à nixpkgs. La fonctionnalité n’a pas encore été implémentée dans la branche Master de nixpkgs et est encore une pull request à la date de rédaction, le 19 avril 2022.

Notre objectif est d’intégrer cette pull request à notre nixpkgs afin de pouvoir lancer des machines virtuelles. Nous allons utiliser Flakes dans ce but. Il s’agit d’une fonctionnalité expérimentale du gestionnaire de packages Nix permettant de la reproductibilité pour le déploiement de dépendances. Nous l’utiliserons afin d’assembler différents nixpkgs ensemble. Il s’agit d’une caractéristique que l’on appelle composabilité.

Si la pull request a été merge, ce tutoriel devient obsolète. Pour obtenir la fonctionnalité, il suffit de mettre à jour son Nix ou NixOS à la dernière version de la branche master.

Pré-requis

Étape 1 - Installation de ZFS

ZFS est un système de fichiers utilisé pour générer des espaces de stockage dans LXD. C’est le seul système de fichiers supporté par cette méthode pour le moment.

ZFS doit être installé sur la machine NixOS avant l’installation de LXD. Pour l’installer, naviguez jusqu’à votre fichier configuration.nix situé dans /etc/nixos/ et ajoutez les lignes suivantes à votre configuration.

boot = {        
  # Activation de ZFS
  initrd.supportedFilesystems = [ "zfs" ];        
  supportedFilesystems = [ "zfs" ];         
  zfs.requestEncryptionCredentials = true;  

  # paramètre empêchant une erreur avec ZFS au démarrage
  loader.grub.copyKernels=true;

  # paramètre interdisant l'option 'freeze' à zfs, pouvant corrompre le système de fichiers
  kernelParams= [ "nohibernate" ];
};

services.zfs = {   
  # Options recommandées pour zfs                     
  autoScrub.enable = true;                  
  autoSnapshot.enable = true;
};

Dans ce même fichier, la propriété networking.hostId doit être attribuée. Seuls des IDs de 32 bits générés depuis le terminal avec head -c 8 /etc/machine-id sont acceptés.

Attribuez cet ID au sein du fichier de configuration.

networking = {
  hostId = "<id>";
};

Maintenant, rebuildez le lecteur switch avec la commande sudo nixos-rebuild switch.

Si le build échoue parce que vous avez déjà installé LXD, référez-vous à cette section de l’article.

Étape 2 - Installation de Flakes

Pour installer Flakes, il suffit de rajouter dans configuration.nix :

# Installation de Flakes
nix = {
  package = pkgs.nixFlakes; # ou attributs versionnés, comme nix_2_7
  extraOptions = ''experimental-features = nix-command flakes'';
};

Vous devez rebuilder votre lecteur switch à nouveau.

Démarrage avec Flakes

Nous allons exploiter la puissance de Flakes pour patcher notre système en combinant différentes versions de nixpkgs. Les versions que nous allons utiliser sont :

La pull request peut être suivie grâce à son numéro : #166858.

Ensuite, nous allons remplacer le package LXD de la branche master de nixpkgs avec celui de la branche lxd-vms du nixpkgs d’astridyu pour avoir la fonctionnalité lxd-agent appliquée à LXD.

Pour utiliser Flakes, il est nécessaire de créer un fichier nommé flake.nix dans /etc/nixos. Remplissons ce fichier avec sudo nano /etc/nixos/flake.nix.

Dans ce fichier, nous devons décrire quels dépôts nixpkgs nous voulons ajouter à notre configuration et comment les fusionner.

Note : Vérifiez que votre nom d’hôte (hostname) est défini au sein du champ networking.hostName dans votre configuration. Il est requis.

{
  description = "Configuration NixOS de LXD";

  # Entrées: les nixpkgs désirés dans la configuration
  inputs = {
    # branche principale de nixpkgs
    nixpkgs.url = "nixpkgs/master";

    # fork de nixpkgs contenant la fonctionnalité désirée (github:username/repository/branch)
    nixpkgs-lxdvm = {
      url = "github:astridyu/nixpkgs/lxd-vms";
    };
  };

  # Sorties: overlay de nikpkgs avec notre version customisée
  outputs = { self, nixpkgs, nixpkgs-lxdvm }:
    let
      system = "x86_64-linux";
      # Création de l'overlay de notre nouveau systeme
      overlay-lxdvm = final: prev: {
         lxdvm = import nixpkgs-lxdvm {
           inherit system;
           # autoriser les packages non-libres
           config.allowUnfree = true;
         };
      };
    in {
      nixosConfigurations."<hostname>" = nixpkgs.lib.nixosSystem {
        inherit system;
        modules = [
          # Création d'un module overlay, accessible depuis configuration.nix
          ({ config, pkgs, ... }: { nixpkgs.overlays = [ overlay-lxdvm ]; })
          ./configuration.nix
        ];
      };
    };
}

Installation de LXD

Nous devons modifier notre configuration.nix pour activer la virtualisation de LXD.

# Permet de lancer des vm avec un socket virtuel sur le réseau
boot.kernelModules = ["vhost_vsock"];

# Ajout de lxd, override du package
virtualisation = {
  lxd = {
    enable=true;

    # utilisation forcée du package de notre overlay
    package = pkgs.lxdvm.lxd.override {useQemu = true;};
    recommendedSysctlSettings=true;
  };

  # ... Le reste de la configuration de virtualisation
};

Rebuildez le lecteur switch. Si le système le demande, il est nécessaire d’utiliser l’option --impure lors du rebuild.

Cette option est nécessaire car Flakes utilise un mode d’évaluation pur lors du rebuild, peu documenté. Flakes interdit l’utilisation de chemins absolus, ce qui pourrait rendre l’évaluation impure. L’incorporation de packages non-supportés est la cause la plus probable.

Démarrage de LXD avec machines virtuelles

Pour commencer à utiliser LXD, il est recommandé d’initialiser un espace de stockage. Cette initialisation se fait avec la commande sudo lxd init.

La commande demandera de renseigner des champs pour le premier espace de stockage que LXD créée. Nous recommandons la configuration suivante lors de la première utilisation.

Would you like to use LXD clustering? (yes/no) [default=no]: no
Do you want to configure a new storage pool? (yes/no) [default=yes]: yes

Name of the new storage pool [default=default]: test-storage

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

Create a new ZFS pool? (yes/no) [default=yes]:

Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]:

Size in GB of the new loop device (1GB minimum) [default=30GB]:

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

Would you like to create a new local network bridge? (yes/no) [default=yes]:

What should the new bridge be called? [default=lxdbr0]: test-bridge

What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:

What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:

Would you like the LXD server to be available over the network? (yes/no) [default=no]:

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

Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:

Si rien n’est renseigné pour un champ, la valeur par défaut sera prise.

Une fois l’espace de stockage configuré, il est alors possible de lancer de nouvelles machines virtuelles avec la commande lxc launch --vm -s . L’image de la machine virtuelle sera téléchargée automatiquement, puis elle sera configurée et lancée.

Pour consulter vos machines virtuelles, faites lxc ls.

Problèmes courants

Si le rebuild échoue, c’est à cause d’une installation pré-existante de LXD. Un espace de stockage de LXD existe déjà, et nixos-rebuild switch ne peut pas aboutir. Plus exactement, des volumes sont toujours montés et il est obligatoire de les supprimer car il est nécessaire de rebuild LXD à partir de zéro.

Commencez par générer à nouveau votre fichier hardware-configuration.nix en exécutant nixos-generate-config.

Dans ce fichier, le chemin vers vos volumes montés est mentionné, et vous devez les démonter et les supprimer de la manière suivante :

  • sudo umount -v /var/lib/lxd/storage-pools/ pour démonter l’espace de stockage.
  • sudo rm -r /var/lib/lxd pour supprimer le dossier LXD entier.

Il faut alors à nouveau rebuild le système.

Conclusion

Félicitations ! Vous êtes désormais capable de lancer des machines virtuelles avec LXD sur NixOS, et vous avez appris à vous servir de Flakes pour créer un overlay pour votre nixpkgs.

Cette méthode deviendra obsolète lorsque la pull request sera merge, mais elle reste pertinente si vous souhaitez intégrer des fonctionnalités absentes de la branche master.

Canada - Maroc - France

International locations

10 rue de la Kasbah
2393 Rabbat
Canada

Nous sommes une équipe passionnée par l'Open Source, le Big Data et les technologies associées telles que le Cloud, le Data Engineering, la Data Science le DevOps…

Nous fournissons à nos clients un savoir faire reconnu sur la manière d'utiliser les technologies pour convertir leurs cas d'usage en projets exploités en production, sur la façon de réduire les coûts et d'accélérer les livraisons de nouvelles fonctionnalités.

Si vous appréciez la qualité de nos publications, nous vous invitons à nous contacter en vue de coopérer ensemble.