
🌐 Aussi en: English · Deutsch · Español
📦 Ce qui devait être un rapide « je monte un NAS ce week-end » s’est transformé en une semaine de terriers de lapin, de yak shaving et d’un nombre déraisonnable de commits git. Mais bon – le homelab s’en porte mieux, et tout est désormais automatisé et documenté. Comme d’habitude, l’intégralité du code Ansible se trouve ici :
👉 github.com/aptupgrademe/www_k3s
Avant d’en venir au NAS et à OpenZFS – le vrai plat de résistance –, je vous déballe rapidement les quêtes annexes survenues en chemin. Si vous êtes pressé, sautez directement à la partie ZFS. Je ne vous jugerai pas.
🐿️ Quêtes annexes : tout ce qui n’était pas le NAS
Vous connaissez la chanson. Vous commencez à configurer un NAS et, trois jours plus tard, vous corrigez des règles d’alerte Grafana et rédigez un guide d’exploitation en français. Voici ce qui s’est passé :
🔒 Correctifs de sécurité (l’édition « attends, c’était ouvert ?! »)
- rpcbind écoutait sur le port 111 – publiquement. NFS n’est utilisé nulle part. Corrigé. 😬
- rkhunter envoyait chaque matin des e-mails « infected! » – parce que SourceForge était passé aux redirections HTTPS et que
curlne les suivait pas. Ajout decurl -L. J’ai aussi automatisérkhunter --propupdaprèsdnf-automatic, pour que les mises à jour de sécurité nocturnes ne ressemblent pas à des rootkits. - Les règles d’alerte Grafana avaient leurs seuils codés en dur dans le PromQL, ce qui provoquait des erreurs « condition must not be empty » dès que les métriques passaient sous le seuil. Seuils déplacés dans l’évaluateur. Ça marche enfin vraiment.
- Durcissement systemd déployé via des drop-ins : le score d’exposition de
sshdest passé de 9,6 → 7,8, celui denode_exporteret deprometheusde 9,2 → 4,4 chacun. - Services inutiles supprimés :
rpcbind,gssproxy,sssd– aucun n’était nécessaire, tous tournaient.
⚡ Performances
- Autoptimize installé sur WordPress : le nombre de balises JS/CSS est tombé de 40 à 6. Poids de la page réduit d’environ 18 %.
- robots.txt renvoyait une 404. Yoast SEO le génère dynamiquement en PHP, mais nginx le traitait comme un fichier statique. Une directive
try_filesplus tard – corrigé. tcp_max_syn_backlogrelevé de 512 à 4096 pour correspondre àsomaxconn.- Transparent Huge Pages passé de
alwaysàmadvise– la valeur par défaut provoque des pics de latence dans les pods K3s, MariaDB et Redis.
🎨 Design & SEO
- L’en-tête du blog a eu droit à une refonte : le logo Superman est désormais à droite (en miroir, pour qu’il regarde vers l’intérieur au lieu de s’envoler hors de la page), le titre du site à gauche, sur un fond sombre assorti aux barres de navigation. Petits détails, grande différence.
- 165 images n’avaient pas de texte alternatif. Corrigé avec un script WP-CLI qui déduit automatiquement les descriptions des noms de fichiers. Ça, ça a pris plus de temps que l’installation du NAS.
- robots.txt expose désormais correctement aux moteurs de recherche le sitemap généré par Yoast.
- Ajout de « Home » comme première entrée du menu de navigation. Visiblement, revenir à la page d’accueil n’avait rien d’évident. Oups.
📚 Documentation
Parce qu’apparemment j’aime écrire de la doc plus que de raison : les guides d’exploitation sont désormais disponibles en allemand, anglais et français pour WordPress, Nextcloud et le nouveau NAS. Oui, en français. Le dossier docs/ du dépôt contient les six fichiers HTML.
🗄️ Le plat de résistance : un NAS OpenZFS sous Debian 13
Bien. Ce que j’avais réellement prévu de faire.
Pourquoi ZFS ? Un bref historique
ZFS a été développé à l’origine par Sun Microsystems et livré pour la première fois avec Solaris 10 en 2005. Le nom signifiait « Zettabyte File System » – Sun ne faisait pas dans la modestie. Il a été conçu de zéro pour résoudre des problèmes que les systèmes de fichiers UNIX traditionnels camouflaient depuis des décennies : la corruption silencieuse, les états incohérents après un crash, et l’horreur générale d’un fsck sur de gros volumes.
Lorsqu’Oracle a racheté Sun en 2010, le développement open source de ZFS a donné naissance au fork OpenZFS – aujourd’hui le projet communautaire activement maintenu qui tourne sous Linux, FreeBSD, macOS et d’autres. C’est lui que nous utilisons.
Une chose que j’ai longtemps crue : ZFS, c’est un truc de FreeBSD. En fait, pas tout à fait. OpenZFS est présent dans les dépôts de Debian 13 et s’installe proprement. Je l’utilise pour la première fois, je n’ai donc pas encore de chiffres concrets. Mon intuition : le débit brut pourrait être légèrement inférieur à celui d’une configuration ext4/mdadm optimisée – mais en échange, les sommes de contrôle, la détection de la corruption silencieuse et les snapshots rendent les données nettement plus sûres. On verra comment il tient la route. 🧪
✅ Ce qui rend ZFS génial
- Sommes de contrôle de bout en bout – chaque bloc reçoit une somme de contrôle à l’écriture, vérifiée à la lecture. La corruption silencieuse (« bit rot ») est détectée et, dans un pool redondant, réparée automatiquement.
- Copy-on-Write (CoW) – les données ne sont jamais écrasées sur place. Les snapshots deviennent ainsi quasiment gratuits et le problème du « write hole » du RAID 5 disparaît.
- Snapshots – des copies d’un dataset à un instant donné, créées instantanément et stockées de façon économe. Retour en arrière en quelques secondes.
- RAID intégré (RAIDZ) – pas de contrôleur RAID séparé, pas de corruption silencieuse des métadonnées. RAIDZ1/2/3 sont natifs dans ZFS.
- Compression – transparente, par dataset.
zstdfait gagner 30 à 50 % d’espace sur les documents et les sauvegardes pour un coût CPU négligeable. - Cache ARC – ZFS gère son propre cache de lecture adaptatif en RAM. Plus de RAM = lectures plus rapides.
- Stockage mutualisé – tous les datasets se partagent dynamiquement l’espace du pool. Fini le découpage en partitions fixes.
⚠️ Les contreparties
- Gourmand en RAM – l’ARC est vorace. Un vrai NAS veut 16 à 32 Go.
- Pas d’agrandissement facile du RAIDZ – impossible d’ajouter simplement un disque à un vdev RAIDZ existant. ZFS 2.2+ a introduit l’extension, mais ce n’est toujours pas instantané.
- RAM ECC vivement recommandée – ZFS fait confiance à la RAM. Si la RAM corrompt silencieusement un bit avant l’écriture, ZFS calcule une somme de contrôle valide sur la donnée corrompue. L’ECC empêche cela.
- Courbe d’apprentissage – pools, vdevs, datasets, propriétés. Un modèle mental différent de celui des systèmes de fichiers traditionnels. Ça vaut le coup, mais comptez un week-end.
🏗️ La configuration concrète
Auparavant, les trois mêmes SSD faisaient tourner un RAID5 logiciel Linux classique (md) avec de l’ext4 par-dessus. Ça marchait, mais sans aucune des garanties d’intégrité, des snapshots ni de la compression de ZFS. Il était temps de passer à la vitesse supérieure.
Le matériel est un HP MicroServer Gen10 Plus V2 – Intel Xeon E-2314, 31 Go de RAM. Organisation du stockage :
sdb(SSD de 465 GB) → système Debian 13sda+sdc+sdd(3× SSD WD Red SA500 de 1,8 TB) → ZFS RAIDZ1sde(HDD Toshiba de 1,8 TB) →/mnt/usb, sauvegarde externe
Le rôle Ansible crée le pool comme ceci :
zpool create -f
-o ashift=12 # 4K sector alignment for modern SSDs
-o autotrim=on # TRIM commands for SSD health
-O compression=zstd # transparent compression
-O atime=off # no access-time writes on reads
-O xattr=sa # Samba xattrs in inodes (faster)
-O recordsize=128k # overridden to 1M per dataset
-O mountpoint=/raid5
data raidz /dev/disk/by-id/ata-WD_Red_SA500_...
📁 Samba – source unique de vérité
Le choix de conception clé : les définitions des partages Samba dans vars.yml pilotent tout. Le rôle Ansible les parcourt en boucle pour créer les datasets ZFS, définir les propriétaires et écrire smb.conf. Ajoutez un partage à un seul endroit – le reste suit automatiquement :
nas_samba_shares:
- name: shared
path: "{{ nas_zfs_mountpoint }}/shared"
valid_users: user3
force_user: user3
- name: user1
path: "{{ nas_zfs_mountpoint }}/user1"
valid_users: user3
force_user: user3
Samba tourne en SMB3 avec la prise en charge du multicanal et des E/S asynchrones. La propriété ZFS xattr=sa stocke les attributs étendus Windows directement dans l’inode plutôt que dans des fichiers cachés, ce qui accélère sensiblement les métadonnées. 🎛️
🤖 Jenkins, GitLab & Pi-hole
Le MicroServer fait un peu plus que servir des fichiers :
Jenkins (port 8090) exécute deux tâches de sauvegarde nocturnes – des sauvegardes basées sur rsync de deux instances Nextcloud distantes (instance-a et instance-b). La clé SSH utilisée pour ces connexions est stockée chiffrée dans Ansible Vault et restaurée dans /home/user3/.ssh/ à chaque nouvelle installation. Même une réinstallation complète du système ne casse pas la connectivité des sauvegardes.
GitLab CE 19.1 (port 80) sert de serveur Git local. Avoir un GitLab sur site pour les projets du homelab, c’est ne dépendre d’aucun service externe. Le rôle Ansible gère toute la configuration post-installation via l’API GitLab : il définit le mot de passe root, crée un utilisateur standard, un groupe homelab et un projet vide www_k3s – le tout de manière idempotente.
Pi-hole v6 (port 8000 pour l’interface web, port 53 pour le DNS) bloque les publicités au niveau du réseau. Il est sur le port 8000 au lieu du port 80 par défaut, car GitLab y habite déjà. Les serveurs DNS en amont sont 8.8.8.8/8.8.4.4.
Et comme c’est un serveur HP : HPE AMSD (Agentless Management Service) est installé en premier – avant tout le reste. Sans lui, le BMC iLO ne reçoit pas les données de température du système et les ventilateurs tournent à fond. Bruyant. Très bruyant.
Tout cela – NAS comme serveurs Internet – n’est qu’à une commande ansible-playbook d’une reconstruction complète :
👉 github.com/aptupgrademe/www_k3s
Prochaine étape : réinstaller réellement hp1 et lancer le playbook pour la première fois sur une Debian 13 toute propre. Je vous dirai si ZFS sous Linux est à la hauteur de sa réputation. 🤞






