Maîtriser la politique OOM : Ajuster la réponse de Systemd aux événements de manque de mémoire
Les systèmes Linux sont conçus pour être robustes, mais sous forte charge ou en raison de fuites de mémoire, ils peuvent occasionnellement manquer de mémoire disponible. Lorsque cela se produit, le "tueur OOM" (Out-of-Memory) du noyau est invoqué pour terminer les processus, libérant ainsi de la mémoire et évitant un plantage du système. Cependant, le comportement par défaut du tueur OOM peut ne pas toujours être optimal, entraînant potentiellement la terminaison de services critiques. Systemd, en tant que système d'initialisation moderne et gestionnaire de services pour de nombreuses distributions Linux, offre des outils puissants pour affiner la manière dont les processus sont traités lorsque le système fait face à un épuisement de la mémoire.
Cet article se penche sur la configuration des politiques OOM (Out-Of-Memory) de systemd, en se concentrant spécifiquement sur les directives OOMScoreAdjust et OOMPolicy au sein des fichiers d'unité systemd. En comprenant et en manipulant ces paramètres, vous pouvez influencer de manière significative les processus que le noyau choisit de sacrifier, protégeant ainsi vos applications vitales et assurant la stabilité du système en cas de faibles ressources de mémoire.
Comprendre le tueur OOM de Linux
Avant de plonger dans la configuration de systemd, il est crucial de comprendre comment le tueur OOM fonctionne. Lorsque le noyau détecte qu'aucune mémoire supplémentaire ne peut être libérée pour satisfaire une demande d'allocation, il invoque le tueur OOM. Ce mécanisme scanne les processus en cours d'exécution et attribue un oom_score à chacun, représentant sa 'nocivité' ou sa probabilité d'être terminé. Les processus consommant de grandes quantités de mémoire, fonctionnant depuis longtemps ou ayant un oom_score plus élevé sont des candidats plus probables à la terminaison.
Le oom_score est calculé sur la base de plusieurs facteurs, y compris l'utilisation de la mémoire, la priorité du processus et la durée d'exécution du processus. Le noyau sélectionne ensuite le processus avec le oom_score le plus élevé à tuer, dans l'espoir de récupérer suffisamment de mémoire pour maintenir le système opérationnel. Bien qu'efficace, ce processus est réactif et peut parfois conduire à la terminaison de processus moins critiques, voire même d'importants si leur oom_score est involontairement élevé.
Systemd et le contrôle OOM
Systemd offre une approche plus granulaire pour gérer le comportement OOM des services individuels. Au lieu de s'appuyer uniquement sur le score OOM global du noyau, vous pouvez influencer le oom_score des processus gérés par les unités systemd et même définir des politiques spécifiques sur la façon dont ces unités doivent se comporter dans des conditions OOM.
La directive OOMScoreAdjust
La directive OOMScoreAdjust, disponible dans les fichiers d'unité systemd, vous permet d'influencer directement le oom_score des processus démarrés par cette unité. Ceci est réalisé en ajustant la valeur oom_score_adj dans le fichier /proc/[pid]/oom_score_adj pour le processus principal de l'unité.
- Valeurs : La plage pour
OOMScoreAdjustest de -1000 à 1000. - Une valeur de -1000 rend le processus insensible au tueur OOM.
- Une valeur de 1000 fait du processus un candidat de premier choix pour la terminaison.
- Une valeur de 0 signifie que le
oom_score_adjn'est pas modifié, et leoom_scoredu processus est déterminé par la logique par défaut du noyau.
Comment ça marche : Quand systemd démarre un service, il peut définir le oom_score_adj pour le processus correspondant. Une valeur oom_score_adj plus basse réduira le oom_score du processus, le rendant moins susceptible d'être tué. Inversement, une valeur plus élevée augmentera son oom_score.
Exemple : Pour qu'un service de base de données critique soit moins susceptible d'être terminé lors d'un événement OOM, vous pourriez ajouter ce qui suit à son fichier d'unité systemd (par exemple, /etc/systemd/system/mydatabase.service) :
[Service]
ExecStart=/usr/bin/my-database-server
OOMScoreAdjust=-500
Dans cet exemple, OOMScoreAdjust=-500 réduit significativement le oom_score du processus my-database-server, le rendant beaucoup moins susceptible d'être ciblé par le tueur OOM. Définir OOMScoreAdjust=-1000 le protégerait efficacement.
Astuce : Utilisez OOMScoreAdjust=-1000 avec une extrême prudence. Rendre un processus complètement insensible peut entraîner une instabilité du système si ce processus a une fuite de mémoire, car il ne sera jamais supprimé, potentiellement affamant d'autres processus essentiels.
La directive OOMPolicy
La directive OOMPolicy fournit des instructions plus spécifiques à systemd sur la manière de gérer les situations OOM pour une unité donnée. Elle dicte le comportement lorsque le système subit une pression de mémoire et que les processus de l'unité sont envisagés pour la terminaison.
- Valeurs possibles :
inherit(par défaut) : L'unité hérite de la politique OOM de son cgroup parent. C'est le paramètre le plus courant.continue: Le processus n'est pas tué, et le système continue de fonctionner. Cela peut conduire à un épuisement supplémentaire de la mémoire si le problème sous-jacent n'est pas résolu.kill: Le processus est tué par le tueur OOM.critical: Marque l'unité comme critique. Le système tentera de libérer de la mémoire en tuant les processus non critiques avant de recourir à la terminaison des processus au sein de cette unité critique.special:special:container: Lorsqu'une unité de conteneur est marquée avec cette politique, l'intégralité du conteneur est tuée si des conditions OOM se produisent.special:stop: Le service est arrêté (non tué) lorsque des conditions OOM se produisent.
Exemple : Pour désigner un serveur web comme critique, en s'assurant que d'autres processus non critiques sont terminés en premier :
[Service]
ExecStart=/usr/bin/nginx
OOMPolicy=critical
Exemple : Pour arrêter un service gracieusement au lieu de le laisser être tué par le tueur OOM :
[Service]
ExecStart=/usr/local/bin/my-batch-job
OOMPolicy=special:stop
Cette configuration signalerait au processus my-batch-job de s'arrêter proprement lorsque la pression de la mémoire est élevée, lui permettant de terminer sa tâche en cours si possible, plutôt que d'être brutalement terminé.
Avertissement : La politique continue doit être utilisée très parcimonieusement. Si un processus contribue à la pression de la mémoire et est autorisé à continuer, cela peut exacerber le problème, conduisant potentiellement à un gel complet du système ou à un plantage incontrôlé.
Application pratique et meilleures pratiques
- Identifier les services critiques : Déterminez quels services sont essentiels au fonctionnement de votre système (par exemple, bases de données, backends d'applications critiques, services réseau essentiels). Ce sont des candidats de premier choix pour l'ajustement de la politique OOM.
- Utiliser
OOMScoreAdjustpour un réglage fin : Pour les services critiques, utilisezOOMScoreAdjustpour abaisser leuroom_score. Commencez avec des valeurs modérées (par exemple, -200 à -500) et surveillez le comportement du système. N'augmentez l'ajustement que si nécessaire et soyez toujours conscient des risques de rendre un processus insensible. - Exploiter
OOMPolicy=critical: Pour les services absolument vitaux,OOMPolicy=criticalest une option robuste. Elle indique au système de prioriser la terminaison des autres processus avant d'envisager votre service critique. - Considérer
OOMPolicy=special:stoppour des arrêts gracieux : Si un service peut être arrêté et redémarré en toute sécurité, l'utilisation despecial:stoppermet un arrêt plus contrôlé qu'une terminaison immédiate. - Surveiller la mémoire du système : L'ajustement des politiques OOM est une mesure réactive. La meilleure approche consiste à surveiller de manière proactive l'utilisation de la mémoire du système et à s'attaquer à la cause première de l'épuisement de la mémoire (par exemple, fuites de mémoire, RAM insuffisante, code d'application inefficace).
- Tester minutieusement : Après avoir appliqué des modifications aux politiques OOM, testez minutieusement votre système sous charge pour vous assurer que le comportement souhaité est atteint et qu'aucune conséquence imprévue ne survient.
- Documenter les modifications : Conservez un registre de toutes les configurations de politique OOM effectuées dans les fichiers d'unité, y compris la justification de chaque modification.
Vérification des ajustements OOM
Après avoir modifié un fichier d'unité et rechargé systemd (sudo systemctl daemon-reload et sudo systemctl restart <service-name>), vous pouvez vérifier l'oom_score_adj du processus en cours d'exécution.
Tout d'abord, trouvez le PID du processus géré par l'unité systemd :
systemctl status <service-name>
Recherchez le Main PID dans la sortie.
Ensuite, vérifiez la valeur oom_score_adj pour ce PID :
cat /proc/<PID>/oom_score_adj
Si la valeur reflète votre paramètre OOMScoreAdjust, votre configuration est appliquée correctement.
Conclusion
Les directives de contrôle OOM de Systemd, OOMScoreAdjust et OOMPolicy, fournissent aux administrateurs des outils essentiels pour gérer le comportement du système en cas de pénurie de mémoire. En ajustant soigneusement ces paramètres, vous pouvez améliorer considérablement la résilience de vos systèmes, garantissant que les services critiques restent disponibles même lorsque le système est sous une pression mémoire sévère. N'oubliez pas que ces configurations font partie d'une stratégie plus large pour la stabilité du système, et qu'une gestion proactive de la mémoire reste le moyen le plus efficace de prévenir les événements OOM.