From d33ed7cf7c7b823543c2921c4fd88bd4ad0642f2 Mon Sep 17 00:00:00 2001 From: Florian Maury Date: Wed, 29 May 2024 17:06:25 +0200 Subject: [PATCH] ajout article Proxmox/FCOS 1 --- posts/proxmox-fcos1.md | 255 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 posts/proxmox-fcos1.md diff --git a/posts/proxmox-fcos1.md b/posts/proxmox-fcos1.md new file mode 100644 index 0000000..6af2c51 --- /dev/null +++ b/posts/proxmox-fcos1.md @@ -0,0 +1,255 @@ +--- +title: Expérimentation de Fedora CoreOS sur Proxmox +slug: proxmox-fcos1 +authors: Florian Maury +description: "Un article discutant de l'installation d'un serveur sur Fedora CoreOS sur Proxmox et des défis rencontrés" +date: 2024-05-17T00:00:00+02:00 +type: posts +draft: false +categories: +- devops +tags: +- proxmox +- fcos +- knot +lang: fr +--- + +Ce billet est le premier d'une série de billets traitant de la création d'une +infrastructure virtualisée à l'aide de Proxmox[^proxmox] pour la partie +hyperviseur, de Fedora CoreOS[^fcos] pour le système d'exploitation des machines +virtuelles invitées (*guests*). L'infrastructure codifiée (*Infrastructure as +Code*) est réalisée avec OpenTofu[^opentofu] (Hashicorp Terraform ayant rejoint +le côté obscur de la Force). + +[^proxmox]: https://www.proxmox.com/en/ +[^fcos]: https://fedoraproject.org/coreos/ +[^opentofu]: https://opentofu.org/ + +## Présentation de Proxmox + +Proxmox est un ensemble d'outils, voire une distribution Linux à part entière +reposant sur Debian, permettant l'administration d'une infrastructure +virtualisée en ligne de commande, via une interface web, ou grâce à une API. +Proposant des options de stockage réparti, de réseau étendu à un groupe +d'instances (*cluster*), de groupes de sécurité, de haute disponibilité, pour +n'en citer que quelques-unes, il s'agit d'une solution qui peut remplacer +aisément VMWare, au minimum sur les cas d'usage relativement simples. + +## Présentation de Fedora CoreOS + +Fedora CoreOS est une distribution Linux orientée sur la stabilité et la +sécurité. Son objectif principal est l'hébergement de conteneurs, et pour cette +raison, elle est pourvue d'un socle minimaliste et durci, mis à jour +automatiquement. Ces mises à jour automatiques sont aisément réversibles en +cas de problème, grâce à son approche pseudo-immuable[^pseudo-integrity], +reposant sur rpm-ostree, et son système de mise à jour (Zincati) permet +également d'orchestrer ces dernières de façon à maintenir un service hautement +disponible. + +Fedora CoreOS est également un système d'exploitation à part en cela +qu'il est conçu pour ne pas avoir besoin d'interagir directement avec le +système, que ce soit pour l'installation/configuration ou l'administration. +L'idée est qu'un cas de changement de configuration, on réinstalle totalement le +système. Au premier démarrage, lors de l'exécution de l'initramfs, le programme +ignition[^ignition] exécute une recette qui configure le système : formatage et +partitionnement des disques, ajout des utilisateurs, copies de fichiers et de +services, etc.. + +Si cette approche peut sembler lourde de prime abord, elle présente en réalité +l'avantage d'apporter la sérénité à ses administrateurs et administratrices ; en +effet, il est dès lors possible de réaliser la recette de la nouvelle +configuration à l'identique dans un environnement de préproduction, sans risque +d'interférence avec l'existant (*snowflake servers*[^snowflakes]). + +[^pseudo-integrity]: https://mastodon.social/@pid_eins/112393043769199622 +[^ignition]: https://coreos.github.io/ignition/ +[^snowflakes]: https://www.learnsteps.com/what-are-snowflake-servers/ + +Ignition et cloud-init[^cloud-init] sont des cousins éloignés. Les deux +participent à la configuration et la personnalisation d'une image système. Le +moment de l'exécution est cependant très différent et importe. En effet, +Ignition intervient lors de l'initramfs, tandis que cloud-init intervient plus +tard lors du démarrage du système d'exploitation. Ignition est donc en mesure de +modifier les tables des partitions avant que le véritable système d'exploitation +ne démarre, et préconfigure le système comme si cette configuration avait +toujours existé ou avait été modifiée lors d'une exécution précédente. + +[^cloud-init]: https://cloud-init.io/ + +Ignition possède néanmoins quelques limitations, assumées, notamment si on le +compare à Ansible. En effet, Ansible possède de très nombreux greffons lui +permettant d'effectuer des actions riches sur un système en cours d'exécution. +Ignition permet essentiellement la copie de fichiers et de services, et les +opérations complexes doivent être effectuées par des scripts shell (Fedora +CoreOS n'installe pas Python, par exemple). Ce choix est raisonnable étant donné +que relativement peu d'opérations d'administration sont attendues sur le socle +faisant tourner Fedora CoreOS. + +En outre, Ansible Vault permet le stockage et le déploiement sécurisé de +secrets, y compris dans les outils de versionnement de code comme git. Ignition, +pour sa part, ne permet pas la communication de secrets de manière sécurisée ; +au mieux, il est possible de les stocker dans un fichier qui sera téléchargé +puis fusionné avec le reste de la configuration par Ignition. Cette solution +n'étant pas très satisfaisante, il est donc nécessaire d'utiliser un +gestionnaire de secrets comme OpenBao (Hashicorp Vault ayant rejoint le côté +obscur de la Force)[^openbao] avec l'emballage de réponses[^respwrap], Bitwarden +Send[^bwsend] ou Bitwarden Secret Manager[^bwsm]. + +[^openbao]: https://openbao.org/ +[^respwrap]: https://developer.hashicorp.com/vault/docs/concepts/response-wrapping +[^bwsend]: https://bitwarden.com/fr-fr/products/send/ +[^bwsm]: https://bitwarden.com/fr-fr/products/secrets-manager/ + +## Défis d'un déploiement de Fedora CoreOS sur Proxmox + +Proxmox dispose d'une couche de compatibilité native avec Cloud-init. Celle-ci +n'est hélas pas générique, et ne permet pas de configurer toutes les options de +Cloud-init. Avec OpenTofu et le fournisseur `bpg/proxmox`[^bpgprox], il est +possible de fabriquer à la volée un ISO disposant du label CIDATA, et ainsi +d'exploiter le mode "nocloud" de cloud-init[^nocloud]. Tout ceci n'aide +cependant pas au déploiement de Fedora CoreOS. + +[^bpgprox]: https://registry.terraform.io/providers/bpg/proxmox/latest +[^nocloud]: https://cloudinit.readthedocs.io/en/latest/reference/datasources/nocloud.html + +Il existe une multitude de moyens de fournir un fichier de configuration à +Ignition : par HTTP après une indication par PXE ou sur la ligne de commande du +noyau, directement dans le fichier ISO d'installation après une personnalisation +de ce dernier, dans une variable du micrologiciel (firmware), etc. Hélas, +l'utilisation d'un ISO séparé, à l'instar du mode "nocloud" de cloud-init, n'est +pas une option. Nous allons néanmoins voir qu'aucune des autres options n'est +native à Proxmox ou satisfaisante. + +### Fourniture de l'adresse du fichier Ignition par PXE + +Proxmox dispose d'une couche réseau programmable/configurable (*Software-defined +Network* (SDN)) assez développée. Cette dernière permet la définition de +différentes zones réseau, avec un filtrage des flux par règles et par groupes de +sécurité. En outre, elle fournit différents services, dont un serveur DHCP +branché sur un IPAM (*IP Address Management*), avec possible synchronisation des +adresses avec un serveur DNS. + +Hélas, il n'est pas possible (par l'interface web ou l'API) de personnaliser la +configuration DHCP pour y rajouter les options nécessaires à PXE, ni d'ajouter +un service pour publier les fichiers de configuration Ignition par HTTP ou TFTP. + +Il est bien sûr possible de se connecter en console, en root, pour modifier +cette configuration, mais cela demande des privilèges élevés sur l'hyperviseur, +et ce n'est pas officiellement supporté par Proxmox. Il est donc préférable de +rechercher une voie alternative, supportée et ne nécessitant que peu de +privilèges. + +### Fourniture du fichier de configuration par personnalisation du fichier ISO + +La personnalisation du fichier ISO de Fedora CoreOS est assez aisée. En effet, +ses développeurs fournissent, notamment sous la forme de conteneurs, des outils +pour ajouter des fichiers et modifier la ligne de commande du +noyau[^customizeiso]. + +[^customizeiso]: https://docs.fedoraproject.org/en-US/fedora-coreos/live-booting/#_booting_via_iso + +Cette approche nécessite cependant d'avoir un fichier ISO distinct par poste à +installer. Ce fichier doit à nouveau être téléversé en intégralité à chaque +modification de la configuration Ignition, ce qui est consommateur de bande +passante. Il peut surement être possible d'utiliser un LXC hébergé par Proxmox +pour faire cette personnalisation directement sur l'hyperviseur, sans nécessiter +le téléversement. + +Au niveau stockage, il est possible de ne pas trop surconsommer du fait que +Proxmox prend en charge nativement btrfs[^btrfs] et ZFS, et que ces systèmes de +fichiers permettent la déduplication des blocs. Cette approche relève cependant +d'une certaine forme de bricolage, avec de potentielles pertes de performances +dans le cas de ZFS ou d'espace disque dans le cas de btrfs si la déduplication +n'est pas demandée assez souvent. + +[^btrfs]: https://btrfs.readthedocs.io/en/latest/Deduplication.html +[^zfs]: https://openzfs.org/wiki/Main_Page + +### Fourniture du fichier de configuration par une variable du micrologiciel + +La fourniture du fichier de configuration par une variable de micrologiciel +s'effectue en ajoutant un argument à la commande qemu qui lance la machine +virtuelle. Cet argument ressemble à la ligne suivante : + +``` +-fw_cfg name=opt/com.coreos/config,file=/local/path/to/config.ign +``` + +Cet argument peut être fourni en modifiant le fichier de configuration de la +machine virtuelle sur l'hyperviseur dans le répertoire +`/etc/pve/qemu-server/.conf`. Cette méthode nécessite néanmoins la +connexion en utilisateur root (via le console ou en SSH), ce qui n'est pas +forcément souhaitable, et la manipulation plus ou moins manuelle de fichiers +système. + +Il peut être également fourni lors des appels à l'API, et le greffon OpenTofu +`bpg/proxmox` permet de le faire avec l'attribut `kvm_paramters` de la ressource +`proxmox_virtual_environment_vm`. Cette méthode nécessite cependant qu'OpenTofu +se connecte avec l'utilisateur `root@pam`, avec mot de passe et sans avoir +défini de second facteur d'authentification. En effet, Proxmox ne permet pas +l'utilisation de jetons d'API, même pour l'utilisateur `root@pam`, pour cette +opération. Cette approche abaisse donc significativement le niveau de sécurité +et n'est donc pas souhaitable. + +En outre, l'option permettant la définition d'une variable dans le micrologiciel +prend en argument le chemin vers le fichier de configuration Ignition. Ce chemin +est local à l'hyperviseur. Hélas, il n'est pas possible de téléverser sur un +serveur Proxmox un fichier arbitraire par l'API ou l'interface web, malgré +l'existence d'une fonctionnalité de "snippets"[^snippets_api]. Il est donc là +encore nécessaire de se connecter en SSH/SFTP pour téléverser le fichier de +configuration... + +[^snippets_api]: https://forum.proxmox.com/threads/creating-snippets-using-pve-api.54081/ + +### Convertir un fichier cloud-init + +Geco IT[^gecoit] a créé un script qui permet de convertir certaines options de +cloud-init en fichier de configuration Ignition. + +[^gecoit]: https://wiki.geco-it.net/public:pve_fcos + +Leur méthode de création de VM ne passe pas par l'API Proxmox mais utilise un +autre script shell qui lance des outils en ligne de commandes de la +distribution Proxmox. Ces commandes sont exécutées en tant que root, et parmi +celles-ci, la commande suivante : + +``` +qm set -hookscript :snippets/hook-fcos.sh +``` + +L'attribut `-hookscript` peut être défini par l'API de Proxmox, et par le +greffon `bpg/proxmox` d'OpenTofu. Cependant, à l'instar de l'attribut `-args`, +celui-ci n'est accepté que si le compte d'API utilisé est `root@pam`, +c'est-à-dire le compte root du serveur Proxmox, avec une authentification par +mot de passe et sans second facteur d'authentification. + +En conséquence, cette méthode n'apporte aucune sécurité additionnelle par +rapport à la précédente discutée, tout en réduisant l'expressivité du fichier de +configuration Ignition. + +## Une proposition de solution : une machine virtuelle d'installation + +Comme nous avons pu le voir dans les sections précédentes, l'usage de l'API +Proxmox pour les attributs `-args` et `-hookscript` est rédhibitoire puisque +nécessitant non seulement d'utiliser le mot de passe du compte root dans la +configuration OpenTofu, mais aussi de désactiver les seconds facteurs +d'authentification. + +La solution PXE est certainement la plus élégante, mais l'impossibilité de +configurer le serveur DHCP de Proxmox (sans passer par le shell) pour permettre +un tel démarrage nous en prive. Finalement, l'approche ISO personnalisé ne +passerait pas à l'échelle d'un parc complet. + +Nous disposons cependant ici de toutes les briques suffisantes pour construire +une solution satisfaisante ! + +L'idée est la suivante : personnaliser un ISO de Fedora CoreOS afin d'y ajouter +un fichier Ignition permettant d'installer un serveur DHCP (pour distribuer les +IPs mais aussi la configuration PXE), un serveur HTTP pour servir les fichiers +indiqués par PXE, et un serveur SFTP afin de déposer les fichiers de +configuration Ignition servis par HTTP. + +À l'origine, je souhaitais détailler ici la solution, mais son développement +s'est avéré suffisamment complexe (et surprenant) pour constituer un billet de +blog séparé. À suivre !