Accueil
» Comment faire
»
Limiter l'utilisation du processeur et de la mémoire d'une commande avec les cgroups d'Ubuntu
Limiter l'utilisation du processeur et de la mémoire d'une commande avec les cgroups d'Ubuntu
Si une commande ralentit votre bureau Ubuntu ou provoque une saturation de la mémoire sur un serveur, placez-la, ainsi que ses processus enfants, dans un cgroup géré par systemd, en limitant l'utilisation du processeur et de la mémoire. Sur les versions actuelles d'Ubuntu, systemd-run --scopela méthode la plus simple consiste à exécuter la commande dans un contexte temporaire, puis à laisser systemd appliquer les limitations via les cgroups.
L'exemple ci-dessous limite la charge de travail à la moitié de la capacité d'un processeur et à 1 Gio de mémoire. Ces limites s'appliquent à l'ensemble du système, y compris aux processus enfants ; elles ne garantissent pas une vitesse d'exécution spécifique du programme.
Pourquoi un processus a besoin d'une limite de cgroup
Un processus gourmand en ressources peut entrer en conflit avec les applications interactives, tandis qu'un processus consommant beaucoup de mémoire peut entraîner une erreur de récupération de mémoire ou une saturation de la mémoire système. Un cgroup regroupe un processus et ses descendants afin que le noyau puisse gérer et limiter ce groupe. Le système systemd d'Ubuntu offre une interface conviviale pour ces contrôles.
Les paramètres du processeur et de la mémoire fonctionnent différemment. CPUQuota=50%limite le temps processeur à la moitié de la capacité d'un processeur, en moyenne sur une période d'ordonnancement. Une valeur de 200%représente jusqu'à deux processeurs disponibles. Il s'agit d'un plafond, et non d'une priorité ou d'une réservation de processeur. MemoryMax=1Gdéfinit un plafond strict pour la mémoire allouée au cgroup ; si la charge de travail dépasse ce plafond, le noyau peut récupérer de la mémoire ou forcer l'arrêt d'un processus du cgroup en cas de mémoire insuffisante. Choisissez une limite laissant une marge pour l'application et ses processus enfants.
1. Vérifiez qu'Ubuntu utilise cgroup v2
Les systèmes Ubuntu utilisant systemd emploient généralement la hiérarchie unifiée cgroup v2. Vérifiez la configuration active avant de vous fier aux chemins indiqués ultérieurement :
stat -fc %T /sys/fs/cgroup
systemctl --version | head -n 1
La première commande devrait afficher un résultat cgroup2fs. Si elle indique un autre type de système de fichiers, les chemins de fichiers cgroup v2 de cet article ne s'appliquent pas tels quels. Les propriétés systemd peuvent être prises en charge avec une hiérarchie différente ; dans ce cas, consultez la documentation de votre distribution plutôt que de copier les chemins v2.
Vérifiez également la version exacte de systemd si une propriété est refusée. La documentation Noble d'Ubuntu décrit `systemctl` CPUQuota=et MemoryMax=`systemctl` comme des paramètres de contrôle des ressources ; les anciennes versions d'Ubuntu peuvent inclure des versions de systemd différentes.
2. Démarrez la charge de travail dans un périmètre limité.
Exécutez le programme systemd-runen remplaçant son exécutable et ses arguments réels. Pour une commande dans le répertoire courant, utilisez `--command` ./et transmettez tous les arguments après-- :
Lancer une commande dans un contexte systemd transitoire avec des limites de CPU et de mémoire.
Pour une commande utilisateur, essayez d'abord sans privilèges d' sudoadministrateur. Si systemd signale qu'un contrôleur ou une propriété demandée est indisponible, le gestionnaire d'utilisateurs n'a peut-être pas l'autorisation de la déléguer ; une nouvelle tentative en tant que superutilisateur peut convenir pour une charge système globale, mais cela modifie le contexte de sécurité de la commande. N'exécutez pas un programme non fiable en tant que superutilisateur sans précaution. Si l'utilisation du gestionnaire de commandes système en tant que superutilisateur est nécessaire, n'utilisez cette méthode sudo systemd-run --scope ...qu'après avoir pris en compte ce changement.
Le terminal reste connecté à l'oscilloscope pendant l'exécution de la commande. Appuyer sur la touche Entrée Ctrl+Cinterrompt l'opération au premier plan. L'oscilloscope est éphémère et disparaît généralement après la fin des processus. Il s'agit d'une méthode pratique pour lancer une commande avec des limites, plutôt que d'une stratégie permanente pour les lancements ultérieurs.
3. Déterminez la portée et examinez ses limites.
systemd-runaffiche le nom de l'unité créée, généralement quelque chose comme run-….scope. Pendant que la commande est toujours en cours d'exécution, listez l'arborescence cgroup :
systemd-cgls
Repérez la portée transitoire et vérifiez que le programme cible et ses enfants apparaissent bien en dessous. C'est important car un enfant exécuté en dehors de cette portée ne sera pas soumis à la même limite de cgroup.
Utilisez l'arbre cgroup pour confirmer que le programme et ses processus sont regroupés sous la portée transitoire.
Utilisez le nom de portée imprimé dans la commande suivante. Remplacez-le run-abc.scopepar le nom réel :
systemctl show run-abc.scope \
-p ControlGroup -p CPUQuotaPerSecUSec -p MemoryMax
CPUQuotaPerSecUSec=50000Cela correspond à un quota de 50 % lorsque la période de quota de systemd est de 100 ms ; la MemoryMax=1073741824taille est de 1 Gio en octets. Les valeurs en temps réel sont plus pertinentes que de supposer que chaque hôte acceptera chaque requête sans modification, car les cgroups parents et les contrôleurs disponibles peuvent limiter le résultat effectif.
Vérifiez le groupe de contrôle signalé par l'oscilloscope ainsi que les limites de processeur et de mémoire configurées.
4. Vérifiez les fichiers cgroup du noyau et ajustez-les en toute sécurité.
Cette ControlGrouppropriété indique le chemin du cgroup relatif à /sys/fs/cgroup. Stockez-le dans une variable d'environnement afin que les commandes suivent le chemin réellement défini sur votre machine :
Sur cgroup v2, cpu.maxla valeur indique un quota et une période en microsecondes. Par exemple, ` 50000 100000--100 ms` signifie 50 ms de temps CPU par période de 100 ms. memory.maxLa valeur maximale de mémoire est indiquée en octets. Si les fichiers sont manquants, vérifiez que la portée est toujours active et que le noyau utilise cgroup v2.
Consultez les fichiers cgroup v2 du noyau pour vérifier le quota configuré et la limite de mémoire.
Si vous avez démarré une unité de service de longue durée et que vous devez ajuster ses limites, systemd permet de modifier les propriétés des ressources sur une unité active sudo systemctl set-property --runtime my-worker.service CPUQuota=50% MemoryMax=1G. Cela s'applique au cgroup de ce service et requiert les privilèges appropriés. systemd n'attache pas un processus déjà en cours d'exécution simplement parce que son PID est connu ; pour un processus ponctuel, arrêtez-le proprement et relancez-le avec les autorisations limitées. Pour un service persistant, configurez les propriétés dans l'unité de service ou un module systemd et redémarrez-le pendant une fenêtre de maintenance appropriée.
Vérifier le résultat
Maintenez la charge de travail active pendant l'inspection. Vérifiez que systemd-cglsle processus et ses enfants sont bien placés dans la portée prévue, que systemctl showles propriétés demandées sont bien signalées et que les fichiers correspondants cpu.maxexistent memory.maxavec des valeurs finies. À la fin du processus, la portée transitoire est supprimée, ce qui peut entraîner la disparition de ses fichiers cgroup.
Un quota limite le temps processeur, mais ne garantit pas un pourcentage fixe sur un moniteur de bureau. De plus, une limite stricte de mémoire peut entraîner des dysfonctionnements si l'application dépasse cette limite. Si la charge de travail devient instable, interrompez-la et augmentez la limite à une valeur sûre mesurée, ou utilisez un MemoryHigh=seuil de pression plus souple associé à une valeur plus élevée MemoryMax=. Pour un comportement précis, consultez la documentation de votre installation systemd et du noyau ; les références officielles sont le manuel d'utilisation de systemd-run sous Ubuntu , le manuel d'utilisation de systemd-control sous Ubuntu et la documentation du cgroup v2 du noyau Linux .