256 lines
13 KiB
Markdown
256 lines
13 KiB
Markdown
|
---
|
||
|
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/<vm_id>.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 <vmid> -hookscript <snippet_storage>: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 !
|