
🌐 Aussi en: English · Deutsch · Español
Deep Dive de la série autour de l’Ansible Tour. Niveau : administration Linux avancée. Le tour explique les rôles ; les deep dives expliquent la technique en dessous – comment elle fonctionne, pourquoi elle est là, ce que cette installation en fait exactement, comment l’exploiter au quotidien et ce qui aurait existé d’autre.
Le 16 octobre 2026, les trois serveurs ont eu droit à une passe de réglage : le blog et deux serveurs Nextcloud. Aucun n’était lent. La question était autre : il y avait de la mémoire libre sur les trois – où aiderait-elle vraiment, et où ne ferait-elle que paraître occupée ? Cet article parcourt la méthode, chaque changement avec le chiffre qui le justifie, ce qui a été laissé tel quel exprès, et ce que disent les mesures quatre jours plus tard.
🧭 La méthode
- Des pics sur sept jours, pas des instantanés. Un coup d’œil à
topmontre un instant. Prometheus garde 30 jours d’échantillons toutes les 15 secondes ;max_over_time(…[7d])donne la pire minute de la semaine, celle que les limites doivent supporter. - Compter au lieu de supposer. Combien de fichiers PHP existent, combien de tables temporaires vont sur disque chaque jour, combien d’instances inotify sont utilisées – chaque fois une seule commande.
- Une raison par changement. Chaque réglage ci-dessous a une mesure à côté. Les réglages sans mesure n’ont pas été touchés.
- Avant et après. Les mêmes requêtes après le déploiement, plus des métriques de conteneurs qui montrent si une limite est désormais trop serrée.
Les ressources, et ce qu’on y lit
| Ressource | Métrique | Piège |
|---|---|---|
| CPU | consommation par conteneur rapportée à sa limite ; bridage CFS | Un conteneur peut être bridé alors que l’hôte est inactif – le goulet, c’est la limite, pas la machine. |
| Mémoire | working set rapporté à la limite | « Utilisée » inclut le cache de pages ; la RAM libre n’est pas perdue, Linux s’en sert pour les fichiers. |
| Mémoire des workers | PSS au lieu de RSS | Le RSS compte la mémoire partagée (OPcache) dans chaque processus et exagère ici d’un facteur cinq. |
| Files d’attente | listen queue de FPM, max_children reached | Une file à zéro signifie assez de workers – davantage ne coûterait que de la mémoire. |
| Limites du noyau | instances et watches inotify, descripteurs de fichiers | Elles échouent avec des erreurs étranges (« too many open files ») bien avant que quoi que ce soit paraisse plein. |
🛡️ Pourquoi s’en donner la peine quand rien n’est lent
- Relever une limite coûte peu avant qu’elle ne morde et cher à diagnostiquer ensuite, quand le symptôme est un client de synchronisation qui bloque une fois par semaine.
- Les valeurs par défaut sont la supposition de quelqu’un d’autre. Deux d’entre elles se trompaient d’un facteur quatre pour Nextcloud.
- Savoir ce qu’il ne faut pas changer, c’est la moitié du résultat : de plus grands tampons au mauvais endroit ne font que déplacer le goulet ou le masquer.
🔧 Ce qui a été changé
| Domaine | Mesuré | Changé en | Où |
|---|---|---|---|
| Workers PHP-FPM (Nextcloud) | pic de 17 sur 20 et 10 sur 12 occupés en même temps | 30 et 20 workers ; limites des conteneurs 6 et 5 Gio | variables d’hôte |
| OPcache (Nextcloud) | 15 500 et 17 800 fichiers PHP ; limite 10 000 = 16 229 emplacements | 256 Mo, 20 000 fichiers (32 531 emplacements) | ConfigMap PHP |
| APCu (Nextcloud) | défaut de PHP 32 Mo, un segment pour tous les workers | 128 Mo | ConfigMap PHP |
| Fichiers temporaires MariaDB | 2 000 à 3 500 tables temporaires par jour sur disque | /tmp en tmpfs (hôte : 4 Go, pod du blog : 512 Mio) | unité MariaDB / pod |
| Collabora | « échec du chargement de la bureautique » au démarrage à froid | 10 et 6 processus de documents prédémarrés | variables d’hôte |
| Requêtes PHP bloquées | aucune limite de durée réelle | request_terminate_timeout 300 s blog / 3 600 s Nextcloud | pool FPM |
| Noyau : inotify | défaut 128 instances par utilisateur ; root en utilisait déjà 63 | 8 192 instances, 524 288 watches | common_sysctl |
| Noyau : écriture différée | pages sales écrites à 10 / 30 % de la RAM | 5 / 10 % | common_sysctl |
Pourquoi ceux-là et pas d’autres
- Workers : 17 sur 20, c’est 85 % au pic – le prochain après-midi chargé aurait fait la queue. Les limites des conteneurs ont suivi les pools, pas l’inverse : PSS par worker fois
max_children, plus OPcache et APCu, avec de la marge. - OPcache : sur le plus petit serveur Nextcloud, 1 500 fichiers n’y entraient jamais et étaient compilés à chaque requête. C’est le nombre de fichiers qui en décide, pas une impression.
- Les tables temporaires avec des colonnes TEXT ne peuvent jamais utiliser le moteur mémoire, augmenter
tmp_table_sizen’aurait donc rien changé. Mettre en RAM le répertoire où elles s’écrivent, si. Un piège en chemin : combiné àPrivateTmp=yes, le répertoire privé de systemd sur disque l’emporte et le tmpfs est ignoré sans un mot – découvert en testant avecsystemd-run, pas en lisant. Et dans le pod du blog, un volume en mémoire compte dans la limite mémoire du conteneur, qui est donc passée de 768 Mio à 1 280 Mio. - inotify : K3s, containerd et chaque pod avec un observateur de fichiers prennent des instances en tant que root. 63 sur 128, c’est bien aujourd’hui, et une erreur mystérieuse après les quelques pods suivants.
- L’écriture différée à 10 % au lieu de 30 % de 23 Go, c’est au plus 2,3 Go de données non écrites au lieu de 7 Go – des blocages plus courts quand le noyau doit enfin écrire, et moins de données perdues lors d’un crash brutal.
tuned et sysctl : qui l’emporte
AlmaLinux fait tourner tuned avec le profil virtual-guest, qui fixe lui-même vm.dirty_ratio = 30. Notre 10 est ce que le noyau indique, parce que tuned réapplique /etc/sysctl.d/ après son propre profil (reapply_sysctl = 1, la valeur par défaut). Sans cela, le profil annulerait discrètement le réglage à chaque démarrage. La seule preuve fiable est la valeur en direct avec sysctl -n après un redémarrage.
🧊 Ce qui a été laissé tel quel exprès
| Domaine | Mesuré | Pourquoi pas |
|---|---|---|
| Buffer pool InnoDB | taux de succès > 99,8 %, pools plus grands que les données (2 Go pour 344 Mo) | Plus de mémoire ne peut pas améliorer un cache qui contient déjà tout. |
| Redis | 1 à 1,5 Mo utilisés | Rien à gagner. |
| PHP-FPM du blog | pic de 6 workers sur 12, file au plus 1 | Le pool était assez grand. |
| OPcache du blog | ~4 600 fichiers PHP, limite 10 000 | Ça tient. |
| Connexions MariaDB | pic de 15 sur 50 | Largement de la marge. |
La mémoire libre que rien n’utilise n’est pas perdue non plus : Linux la remplit de cache de fichiers, exactement ce que veut un serveur de fichiers.
📊 Quatre jours plus tard
| Blog | Nextcloud A | Nextcloud B | |
|---|---|---|---|
| Pic de workers PHP actifs (7 jours) | 8 sur 12 | 13 sur 30 | 9 sur 20 |
max_children atteint | 0 | 0 | 0 |
| Pic mémoire du conteneur / limite | 538 Mio / 1 Gio | 763 Mio / 6 Gio | 277 Mio / 5 Gio |
| Périodes CPU bridées | 2,1 % | 2,2 % | 0,2 % |
| Requêtes PHP lentes (> 5 s) | 0 | 0 | 0 |
| Requêtes de base lentes (> 1 s) | 0 | 0 | 0 |
| Mémoire disponible sur l’hôte | 5,0 sur 7,5 Go | 19 sur 23 Go | 8,5 sur 11,4 Go |
Aucun pool ne s’est approché de sa limite, aucun conteneur de sa limite mémoire, le bridage reste à quelques pour cent, et les hôtes ont encore la majeure partie de leur mémoire libre. Les changements ont coûté peu et ont supprimé trois vrais plafonds – workers, emplacements de bytecode, limite de durée – avant que quiconque ne s’y heurte.
L’erreur de mesure
En rassemblant les chiffres ci-dessus, la première requête pour le conteneur PHP du blog a renvoyé un pic de 940 Mio pour une limite de 1 Gio – ce qui aurait aussitôt réclamé une limite plus haute. La requête additionnait toutes les séries du conteneur : pendant un déploiement, l’ancien et le nouveau pod existent en même temps, et juste après le redémarrage d’un conteneur, cAdvisor rapporte brièvement l’ancien et le nouveau cgroup. Le pic d’un seul pod était de 538 Mio. Additionner par pod, ou prendre le maximum par pod, est la bonne lecture ; un simple sum sur le nom du conteneur additionne des choses qui n’ont jamais existé au même moment dans un même processus.
🧰 Refaire l’exercice
# worst minute of the week, per pod (not summed over pods!)
max_over_time(max by (pod) (container_memory_working_set_bytes{container="nextcloud-fpm"})[7d:1m])
# share of CPU periods throttled
sum(increase(container_cpu_cfs_throttled_periods_total{container="nextcloud-fpm"}[7d]))
/ sum(increase(container_cpu_cfs_periods_total{container="nextcloud-fpm"}[7d]))
# PHP-FPM peak and queue
max_over_time(sum(phpfpm_active_processes)[7d:1m])
max_over_time(max(phpfpm_listen_queue)[7d:1m])- Quand : après un changement de charge (nouveaux utilisateurs, nouvelle app), après une mise à niveau majeure, et sinon tous les quelques mois.
- Où regarder d’abord : le tableau de bord « Container-Ressourcen » (limites, bridage, OOM kills) et les alertes sur la mémoire et le bridage des conteneurs, qui envoient un mail quand une limite devient serrée.
- Quoi noter : la mesure à côté du réglage. Le guide d’exploitation a un tableau exactement pour cela, afin que la prochaine passe parte de chiffres, pas de souvenirs.
🆘 Antisèche : symptôme → commande
La version courte de cet article, pour le moment où quelque chose ne va pas. À lancer sur l’hôte en root ; <…> sont des espaces réservés.
| Symptôme | Commande |
|---|---|
| Un pod manque-t-il de mémoire ? | max_over_time(max by (pod) (container_memory_working_set_bytes{container="<c>"})[7d:1m]) |
| Un pod est-il bridé (throttling) ? | sum(increase(container_cpu_cfs_throttled_periods_total{container="<c>"}[7d])) |
| Y a-t-il assez de workers PHP ? | max_over_time(sum(phpfpm_active_processes)[7d:1m]) |
| Quelque chose a-t-il été tué faute de mémoire ? | journalctl -k | grep -i "out of memory" |
| Que reste-t-il à l’hôte ? | free -h; uptime; df -h / |
| Où regarder en premier | # Grafana: dashboard "Container-Ressourcen" (limits, throttling, OOM kills) |
🔭 La suite
- Des tests de charge avec k6 contre une instance de test, pour voir où sont les plafonds au lieu de les attendre.
- Des seuils d’alerte tirés des pics mesurés plutôt que de chiffres ronds – le premier, pour la file PHP-FPM, est venu de 14 jours de données en octobre 2026.
- La planification de capacité : la croissance mensuelle des données du plus grand serveur Nextcloud face à son disque.
⚖️ Alternatives – et pourquoi mesurer d’abord
| Approche | Point fort | Faiblesse |
|---|---|---|
| Régler selon une liste de contrôle | Rapide, aucun outil nécessaire | Change ce dont l’auteur de la liste avait besoin, pas ce dont ce serveur a besoin. |
| Une machine plus grosse | Aide toujours un peu | Masque le plafond au lieu de le déplacer ; coûte chaque mois. |
| Outils APM commerciaux | Traces jusqu’à la fonction | Coût, un agent dans chaque conteneur, et disproportionné pour ces charges. |
| Mesurer, puis changer une chose | Chaque changement a une raison et un contrôle | Exige des métriques déjà en place – c’est pourquoi elles sont venues en premier. |
Le résultat le plus précieux de la journée n’était pas un réglage mais une liste : huit changements, chacun avec un chiffre, et cinq choses laissées telles quelles, chacune aussi avec un chiffre. La prochaine passe partira de là, et si une valeur s’avère fausse, on saura sur quoi elle reposait.


