Recherche de site Web

Comment écrire et effectuer des installations sans surveillance d’Ubuntu avec autoinstall


Il est crucial de pouvoir provisionner et créer des installations reproductibles d’un système d’exploitation, en particulier dans les environnements d’entreprise. Pour effectuer des installations sans surveillance, Ubuntu prechargeait les fichiers de préconfiguration et de démarrage Debian. À partir d’Ubuntu Server 20.04 et de la version 23.04 du bureau Ubuntu, ces méthodes d’installation sont devenues obsolètes et la distribution a adopté un nouveau format d’installation automatique, qui tire parti de cloud-init.

Dans ce tutoriel, nous apprenons à écrire un fichier d’auto-installation Ubuntu et à l’utiliser pour effectuer des installations reproductibles sans surveillance.

Dans ce tutoriel, vous allez apprendre :

  • Comment écrire un fichier d’autoinstall et définir une installation Ubuntu dans tous ses aspects
  • Comment passer le fichier d’installation automatique aux installateurs de bureau et de serveur Ubuntu

Présentation du fichier d’installation automatique

Étant une distribution dérivée de Debian, Ubuntu supportait à l’origine les fichiers de préconfiguration comme méthode d’exécution d’installations sans surveillance et reproductibles. La prise en charge de la syntaxe d’installation de Kickstart a été ajoutée plus tard en tant que couche de compatibilité, mais toutes les commandes Kickstart n’ont pas été implémentées. À partir d’Ubuntu Server 20.04, et depuis Ubuntu desktop 23.04, Ubuntu a adopté sa propre méthode d’auto-installation, basée sur la syntaxe YAML : autoinstall.

La première chose que l’on voit généralement dans les fichiers d’autoinstall, c’est le commentaire « #cloud-config » : c’est nécessaire si nous voulons que le fichier soit traité par cloud-init (nous y reviendrons plus tard). La clé principale utilisée dans le fichier de configuration est l’installation automatique ; La syntaxe du fichier version, en revanche, est spécifiée avec la clé de version. Au moment de la rédaction de cet article, seule la version 1 est disponible :

#cloud-config
autoinstall:
  version: 1

Choisir une source

Pour spécifier « l’environnement » que nous voulons installer, nous pouvons utiliser la clé source, qui prend un mappage comme valeur. À l’intérieur de ce mappage, nous passons le nom de l’environnement que nous voulons installer comme valeur de la clé id. Lors de l’installation d’Ubuntu desktop, par exemple, nous pouvons choisir entre ubuntu-minimal-desktop et ubuntu-desktop à part entière. Si la clé est omise, la première source disponible est utilisée :

#cloud-config
autoinstall:
  source:
    id: ubuntu-desktop-minimal

Définition des paramètres régionaux du système, du fuseau horaire et de la disposition du clavier

Pour définir les paramètres régionaux du système, nous utilisons la clé locale. Les paramètres du clavier, en revanche, sont spécifiés via la touche du clavier. Cette clé prend un mappage comme valeur ; Dans l’exemple ci-dessous, nous spécifions uniquement la mise en page que nous voulons utiliser (nous) ; Il est également possible de spécifier d’autres paramètres, tels que la variante de mise en page. Enfin, pour définir le fuseau horaire du système, nous utilisons la clé de fuseau horaire :

#cloud-config
autoinstall:
  locale: en_US.UTF-8
  keyboard:
    layout: us
  timezone: Europe/Rome

Configuration des interfaces réseau

Pour configurer le réseau du système, nous utilisons la clé réseau, en utilisant la syntaxe netplan. Dans l’exemple ci-dessous, je précise que je souhaite que l’interface Ethernet enp1s0 soit configurée automatiquement via dhcp4 :

#cloud-config
autoinstall:
  network:
    version: 2
    ethernets:
      enp1s0:
        dhcp4: true

Configuration du nom d’hôte et de l’utilisateur initial du système

Pour utiliser notre système en toute sécurité, nous devons créer au moins un utilisateur non privilégié. Nous devons également définir le nom d’hôte du système. Ces deux aspects sont gérés via la clé d’identité. La clé prend un mappage comme valeur ; Nous définissons le nom d’utilisateur, le mot de passe et le nom d’hôte, avec les clés respectives :

#cloud-config
autoinstall:
  identity:
    username: egidio
    hostname: linuxconfig
    password: '$6$mzOdSSVUfhWRNhcX$mkm.drDfOLfpZRX/58ouJqMvitV2O0147VgKzKGYE6Qx4adJ8TXqMHs2dh2L7kT4TW5e97FCRDkGK1J.LouyV.'

Comme vous pouvez le voir dans l’exemple, le mot de passe que nous fournissons doit déjà être haché à l’aide de l’algorithme sha512.

Configuration du serveur SSH

Dans le fichier d’autoinstall, nous avons la possibilité de spécifier si nous voulons installer et configurer le serveur SSH. Nous pouvons activer ou désactiver l’authentification par mot de passe, et éventuellement passer la liste des clés publiques autorisées qui seront ajoutées au fichier authorized_keys de l’utilisateur initial :

#cloud-config
autoinstall:
  ssh:
    install-server: true
    allow-pw: true
    authorized-keys: []

Installation de packages supplémentaires

Pour spécifier une liste de paquets supplémentaires à extraire par le gestionnaire de paquets apt-get, dans le cadre de l’installation du système, nous pouvons utiliser la clé packages. En voici un exemple :

#cloud-config
autoinstall:
  packages:
    - git
    - python3-pip

Pour installer des packages snap, à la place, nous utilisons le mot-clé snaps. Le mot-clé accepte une liste de mappages comme valeur. Dans chaque mappage, nous utilisons les touches name, channel et classic pour spécifier, respectivement, le nom du package snap à installer, le canal à partir duquel le snap doit être installé (la valeur par défaut est « stable »), et si le package snap doit être installé en mode classique (la valeur par défaut est « false ») :

#cloud-config
autoinstall:
  snaps:
    - name: pycharm-community
      channel: stable 
      classic: true

Définition de l’action post-installation

Pour définir l’action post-installation, nous utilisons la touche d’arrêt. Cette clé accepte deux valeurs possibles : « poweroff » et « reboot » :

#cloud-config
autoinstall:
  shutdown: reboot

Définition de la configuration du stockage

L’un des aspects les plus importants de l’installation du système est la configuration du partitionnement. Lors de l’installation interactive d’Ubuntu, nous pouvons choisir parmi quelques mises en page prédéfinies ou créer une configuration personnalisée. Nous pouvons faire la même chose lors d’installations automatiques. Les mises en page prédéfinies disponibles sont : lvm, direct et zfs.

La disposition lvm est la valeur par défaut : elle crée les partitions standard EFI (dans le cas des systèmes UEFI modernes) et de démarrage, et installe le reste du système sur un volume logique LVM. La taille du volume logique racine est déterminée en fonction d’une politique : lorsqu’elle est définie sur « scaled » (par défaut), la quantité d’espace affectée au volume logique dépend de la taille du groupe de volumes. Lorsque c’est possible, un peu d’espace est laissé inutilisé, pour permettre la création de snapshots :

Taille VGTaille VG de la racine
Moins de 10 Gio100 % de l’espace disponible
Entre 10 Gio et 20 Gio10 Gio
Entre 20Gio et 200 Gio50 % de l’espace disponible
Plus de 200 Gio100 Gio

Lorsque la stratégie est définie sur « all », tout l’espace disponible est affecté au volume logique racine. Dans ce contexte, la clé demot de passe peut être utilisée pour activer le chiffrement LUKS et pour fournir le mot de passe de chiffrement :

#cloud-config
autoinstall:
  storage:
    layout:
      name: lvm
      policy: all
      password: mysecretpassword

La disposition directe installe Ubuntu sur des partitions standard. Sur les systèmes UEFI, il crée une partition EFI d’une taille de 1 Gio et alloue le reste de l’espace à la partition racine.

Enfin, la disposition zfs installe le système sur un pool ZFS, créant ainsi plusieurs volumes. Ci-dessous, vous pouvez voir une capture d’écran de l’installation de zfs après une nouvelle installation d’Ubuntu :

Choix d’un disque pour l’installation

En plus de la disposition des partitions, nous pouvons définir explicitement quel disque doit être utilisé pour l’installation. Nous le faisons via la clé de correspondance. Nous pouvons sélectionner un disque par chemin, par fournisseur, modèle, série, etc. Si le mot-clé est omis, l’installation se fait sur le plus grand disque disponible. Dans l’exemple ci-dessous, nous sélectionnons un disque par chemin (/dev/vda) :

#cloud-config
autoinstall:
  storage:
    layout:
      name: lvm
      match:
        path: /dev/vda

Création d’une mise en page personnalisée

Pour définir une disposition de partitions personnalisée, nous utilisons le mot-clé config. Ce mot-clé accepte une liste de mappages en valeur, chacun décrivant une commande de l’installateur curtin. Voyons un exemple. Supposons que nous voulions installer Ubuntu sur un LVM lors de l’installation de LUKS, en créant les partitions suivantes :

  1. Une petite partition EFI de 600 Mo, formatée en fat32, à monter sur /boot/efi
  2. Une partition de démarrage de 1 Gio, formatée en ext4 à monter sur /boot
  3. Une troisième partition qui s’étend sur le reste de l’espace, chiffrée avec LUKS, et formatée comme un volume physique LVM
  4. Un volume logique LVM de 45 Gio à monter sur /
  5. Un volume logique LVM de 50 Gio à monter sur /home

Voici comment nous procéderions. La première chose que nous devons faire est d’utiliser la commande disk. Il est utilisé pour configurer des disques et créer des tables de partition :

#cloud-config
autoinstall:
  storage:
    config:
      - id: disk-vda
        type: disk
        ptable: gpt
        path: /dev/vda
        wipe: superblock-recursive

Avec le mot-clé id, nous fournissons un identifiant pour la section et la commande : cela nous permet de référencer le disque lors de l’utilisation d’autres commandes. Avec le mot-clé type, en revanche, nous spécifions la commande que nous voulons exécuter, qui, dans ce cas, est « disk ».

Lorsque la clé ptable est présente, une table de partition du type spécifié est créée sur le disque. Dans ce cas, nous avons utilisé « gpt » comme valeur. Le mot-clé path est utilisé pour identifier le disque par son chemin (/dev/vda).

Le mot-clé wipe est très important : lorsqu’il est utilisé, il détruit le contenu des disques ou des partitions. Il existe de nombreux types de « balayage » que nous pouvons utiliser : superblock, superblock-récursif, zéro, aléatoire et pvremove. Nous utilisons superblock lorsque nous voulons effacer uniquement le superbloc du disque, et superblock-recursive lorsque nous voulons effacer également les éventuels superblocs intégrés (ils peuvent être présents lors de l’utilisation de LVM, par exemple). En utilisant les effacements zéro ou random, nous pouvons écraser le disque avec des zéros ou des données aléatoires, respectivement. Enfin, pvremove efface spécifiquement les métadonnées LVM afin de s’assurer que le disque ne fait pas partie d’une configuration LVM. Dans l’exemple ci-dessus, nous avons utilisé superblock-recursive, ce qui devrait être suffisant dans la plupart des cas.

Création de partitions standard avec la commande « partition »

Nous devons maintenant créer les trois partitions « standard » sur le disque. La première est la partition EFI, la seconde la partition qui sera montée sur /boot, et la troisième est la partition qui sera chiffrée avec LUKS, et utilisée comme un volume physique LVM. Pour créer une partition, nous utilisons la commande partition. Dans les exemples ci-dessous, par souci de clarté, nous nous concentrons sur les commandes actuelles, en omettant celles que nous avons utilisées précédemment :

#cloud-config
autoinstall:
  storage:
    config:
      # [...]

      - id: efipart
        type: partition
        device: disk-vda
        offset: 1048576
        size: 600M
        flag: boot
        grub_device: true

      - id: bootpart
        type: partition
        device: disk-vda
        size: 1G

      - id: pvpart
        type: partition
        device: disk-vda
        size: -1

Comme la partition « efipart » est la première, nous avons utilisé le mot-clé offset pour nous assurer qu’elle est créée à 1MiB dès le début du disque (la valeur est fournie en octets : 1048576). Nous avons utilisé le mot-clé flag pour spécifier un drapeau à définir sur la partition, « boot » dans ce cas. Enfin, nous avons utilisé le mot-clé grub_device pour nous assurer que GRUB est installé sur la partition.

Dans toutes les définitions, nous avons utilisé la clé de périphérique pour référencer le disque sur lequel la partition doit être créée, et la clé de taille pour spécifier la taille de la partition. Dans le cas de la partition « pvpart », nous utilisons « -1 » comme valeur : cela garantit que la partition occupe tout l’espace restant sur le disque.

Création d’un volume LUKS chiffré à l’aide de la commande dm_crypt

Comme prochaine étape, nous voulons utiliser LUKS pour chiffrer la partition « pvpart ». Nous pouvons le faire en utilisant la commande dm_crypt :

#cloud-config
autoinstall:
  storage:
    config:
      # [...]

      - id: pvpart-crypt
        type: dm_crypt
        volume: pvpart
        key: mysecretpassword

Lors de l’utilisation de la commande dm_crypt, nous transmettons l’identificateur de la partition que nous voulons chiffrer en tant que valeur de la clé de volume, et nous utilisons key pour fournir la phrase de passe de chiffrement.

Création du groupe de volumes LVM et des volumes logiques

Pour créer un groupe de volumes LVM, nous utilisons la commande lvm_volgroup et le mot-clé devices pour lister les volumes physiques que nous voulons ajouter au groupe :

#cloud-config
autoinstall:
  storage:
    config:
      # [...]
     
      - id: vg0
        type: lvm_volgroup
        name: vg0
        devices:
          - pvpart-crypt

Pour créer des volumes logiques, nous utilisons la commande lvm_partition. Nous spécifions le nom du LV avec la clé de nom, le groupe de volumes sur lequel le LV doit être créé en tant que valeur de volgroup, et sa taille, via la clé de taille :

#cloud-config
autoinstall:
  storage:
    config:
      # [...]
      - id: root_lv
        type: lvm_partition
        name: root_lv
        volgroup: vg0
        size: 45G
 
      - id: home_lv
        type: lvm_partition
        name: home_lv
        volgroup: vg0
        size: 50G

Formatage des partitions

Pour créer des systèmes de fichiers sur les partitions que nous avons définies, et définir leurs points de montage, nous utilisons la commande format. Nous utilisons le mot-clé volume pour référencer la partition par id, et le mot-clé fstype pour spécifier quel système de fichiers doit être créé :

#cloud-config
autoinstall:
  storage:
    config:
      # [...]
    
      - id: efipart_fs
        type: format
        volume: efipart
        fstype: fat32

      - id: bootpart_fs
        type: format
        volume: bootpart
        fstype: ext4

      - id: root_lv_fs
        type: format
        volume: root_lv
        fstype: ext4

      - id: home_lv_fs
        type: format
        volume: home_lv
        fstype: ext4

Enfin, pour spécifier l’emplacement du système de fichiers qui doit être monté, nous utilisons la commande mount. Avec la clé de périphérique, nous spécifions l’identifiant du système de fichiers ; avec path, à la place, son point de montage :

#cloud-config
autoinstall:
  storage:
    config:
      # [...]
     
      - id: efipart-mount
        type: mount
        device: efipart_fs
        path: /boot/efi

      - id: bootpart-mount
        type: mount
        device: bootpart_fs
        path: /boot

      - id: root_lv_mount
        type: mount
        device: root_lv_fs
        path: /

      - id: home_lv_mount
        type: mount
        device: home_lv_fs
        path: /home

Transmission de la configuration à l’installateur d’Ubuntu

Voici à quoi ressemble notre fichier de configuration d’installation automatique dans son intégralité :

#cloud-config
autoinstall:
  version: 1

  source:
    id: ubuntu-server-minimal

  locale: en_US.UTF-8
  keyboard:
    layout: us
  timezone: Europe/Rome

  network:
    version: 2
    ethernets:
      enp1s0:
        dhcp4: true

  identity:
    username: egidio
    hostname: linuxconfig
    password: '$6$mzOdSSVUfhWRNhcX$mkm.drDfOLfpZRX/58ouJqMvitV2O0147VgKzKGYE6Qx4adJ8TXqMHs2dh2L7kT4TW5e97FCRDkGK1J.LouyV.'

  ssh:
    install-server: true
    allow-pw: true
    authorized-keys: []

  packages:
    - git
    - python3-pip

  snaps:
    - name: pycharm-community
      channel: stable 
      classic: true

  shutdown: reboot
  storage:
    config:
      - id: disk-vda
        type: disk
        ptable: gpt
        path: /dev/vda
        wipe: superblock-recursive

      - id: efipart
        type: partition
        device: disk-vda
        offset: 1048576
        size: 600M
        flag: boot
        grub_device: true

      - id: bootpart
        type: partition
        device: disk-vda
        size: 1G

      - id: pvpart
        type: partition
        device: disk-vda
        size: -1

      - id: pvpart-crypt
        type: dm_crypt
        volume: pvpart
        key: mysecretpassword

      - id: vg0
        type: lvm_volgroup
        name: vg0
        devices:
          - pvpart-crypt

      - id: root_lv
        type: lvm_partition
        name: root_lv
        volgroup: vg0
        size: 45G
 
      - id: home_lv
        type: lvm_partition
        name: home_lv
        volgroup: vg0
        size: 50G

      - id: efipart_fs
        type: format
        volume: efipart
        fstype: fat32

      - id: bootpart_fs
        type: format
        volume: bootpart
        fstype: ext4

      - id: root_lv_fs
        type: format
        volume: root_lv
        fstype: ext4

      - id: home_lv_fs
        type: format
        volume: home_lv
        fstype: ext4

      - id: efipart-mount
        type: mount
        device: efipart_fs
        path: /boot/efi

      - id: bootpart-mount
        type: mount
        device: bootpart_fs
        path: /boot

      - id: root_lv_mount
        type: mount
        device: root_lv_fs
        path: /

      - id: home_lv_mount
        type: mount
        device: home_lv_fs
        path: /home

Comment passer la configuration à l’installateur d’Ubuntu ? Lors de l’installation de la version Desktop d’Ubuntu, la méthode la plus simple et la plus pratique consiste à rendre notre fichier de configuration disponible via HTTP ou FTP, et à passer son URL dans la section appropriée de l’installateur graphique :

Un fichier de configuration d’autoinstall est automatiquement créé après chaque installation d’Ubuntu, même celles effectuées de manière interactive. Vous pouvez trouver le fichier enregistré sous le nom /var/log/installer/autoinstall-user-data. Le fichier peut être utilisé pour répliquer l’installation.

Si nous voulons effectuer une installation complètement automatisée, ou utiliser la configuration autoinstall lors de l’installation du serveur Ubuntu, nous devons utiliser cloud-init, et utiliser la configuration comme un fichier de données cloud-config : c’est à cela que sert le commentaire « #cloud-config » au tout début du fichier d’autoinstall.

Pour que cloud-init puisse lire le fichier au démarrage, nous devons le renommer en user-data et créer un fichier vide nommé meta-data dans le même répertoire. Nous appuyons sur « e » pour modifier la première entrée du menu GRUB ISO en direct :

On modifie ensuite la ligne commençant par « linux », en ajoutant la chaîne suivante avant les trois tirages d’union (l’échappement du point-virgule est important !) :

autoinstall ds=nocloud-net\;s=<directory-URL>

Où <URL-de-répertoire> est l’URL du répertoire contenant les fichiers de données utilisateur et de métadonnées :

À ce stade, pour démarrer l’installation, il suffit d’appuyer sur Ctrl-x.

Réflexions finales

Depuis Ubuntu Server 20.04 et Ubuntu desktop 23.04, il est possible d’effectuer des installations système sans surveillance et reproductibles en utilisant le format natif d’autoinstall. Dans ce tutoriel, nous avons vu comment écrire un fichier d’autoinstallation, et certaines des clés qui peuvent être utilisées dans celui-ci. Enfin, nous avons vu comment passer le fichier aux installateurs de bureau et de serveur Ubuntu. Pour une référence complète de l’installation automatique d’Ubuntu, veuillez consulter la documentation officielle.

Articles connexes: