Gérer les ressources à l'aide de groupes de contrôle

Explique comment les groupes de contrôle organisent les processus, comment systemd applique les stratégies de ressources et quand gérer les groupes de contrôle manuellement.

Les groupes de contrôle, appelés cgroups, sont une fonctionnalité de noyau Oracle Linux qui organise les services systemd et, si nécessaire, les processus individuels (PIDs), en groupes hiérarchiques pour l'allocation des ressources système, telles que la CPU, la mémoire et les E/S.

Par exemple, si vous avez identifié trois processus auxquels le temps CPU doit être alloué dans un rapport de 150:100:50, vous pouvez créer trois cgroups, chacun avec une pondération de CPU correspondant à l'une des trois valeurs du rapport, et affecter le processus approprié à chaque cgroup.

Important

Utilisez systemd pour configurer cgroups.

La création manuelle de répertoires cgroup dans le système de fichiers virtuel /sys/fs/cgroup (comme indiqué dans cette rubrique) peut être utile pour illustrer les concepts sous-jacents. Toutefois, lorsque vous utilisez cette approche pour des scénarios spécifiques, tels que le débogage ou les tests temporaires. Pour la plupart des cas d'utilisation, utilisez systemd pour configurer cgroups afin de garantir une gestion correcte et persistante des ressources.

Par défaut, systemd crée une valeur cgroup pour les éléments suivants :

  • Chaque service systemd est configuré sur l'hôte.

    Par exemple, un serveur peut avoir le groupe de contrôle NetworkManager.service pour regrouper les processus appartenant au service NetworkManager, et le groupe de contrôle firewalld.service pour regrouper les processus appartenant au service firewalld, etc.

  • Chaque utilisateur (UID) sur l'hôte.

La fonctionnalité cgroup est montée en tant que système de fichiers virtuel sous /sys/fs/cgroup. Chaque cgroup possède un répertoire correspondant dans le système de fichiers /sys/fs/cgroup. Par exemple, le fichier cgroups créé par systemd pour les services qu'il gère peut être vu en exécutant la commande ls -l /sys/fs/cgroup/system.slice | grep ".service" comme indiqué dans l'exemple de bloc de code suivant :

ls -l /sys/fs/cgroup/system.slice | grep ".service"
            ...root root 0 Mar 22 10:47 atd.service
            ...root root 0 Mar 22 10:47 auditd.service
            ...root root 0 Mar 22 10:47 chronyd.service
            ...root root 0 Mar 22 10:47 crond.service
            ...root root 0 Mar 22 10:47 dbus-broker.service
            ...root root 0 Mar 22 10:47 dtprobed.service
            ...root root 0 Mar 22 10:47 firewalld.service
            ...root root 0 Mar 22 10:47 httpd.service
            ...

Vous pouvez également créer un fichier cgroups personnalisé en créant des répertoires sous le système de fichiers virtuel /sys/fs/cgroup et en affectant des ID de processus (PIDs) à un autre fichier cgroups en fonction de la configuration système requise. Toutefois, il est recommandé d'utiliser systemd pour configurer cgroups au lieu de créer cgroups manuellement sous /sys/fs/cgroup..

Pour connaître la méthode recommandée de gestion de cgroups via systemd, reportez-vous à la section Using Systemd to Manage Control Groups.

Deux versions des groupes de contrôle sont disponibles dans le noyau Linux.

Groupes de contrôle version 1 (cgroups v1)

Fournit une hiérarchie de contrôleurs par ressource. Chaque ressource (CPU, mémoire, E/S, etc.) possède sa propre arborescence de groupes de contrôle. Cela peut rendre la coordination entre les ressources difficile. Utilise une API héritée. Désormais considéré comme obsolète mais disponible pour compatibilité sur les systèmes pris en charge.

Groupes de contrôle version 2 (cgroups v2)

Utilise une hiérarchie unifiée et unique pour tous les contrôleurs, ce qui permet une meilleure coordination entre les ressources et une gestion plus simple. Utilise une API moderne et simplifiée. Il s'agit de la mise en œuvre privilégiée et activement développée.

Le tableau suivant récapitule la disponibilité par version d'Oracle Linux :

Prise en charge des versions cgroups par la version Oracle Linux
Version d'Oracle Linux cgroups v1 cgroups v2
Oracle Linux 8 : Disponible (par défaut) Disponible (activer manuellement)
Oracle Linux 9 Disponible (compatibilité) Disponible (par défaut)
Oracle Linux 10 Non disponible (obsolète) Disponible (par défaut)

Pour plus d'informations sur les groupes de contrôle, consultez les pages de manuel cgroups(7) et sysfs(5).

Activation de cgroups v2 sur Oracle Linux 8

  1. Vérifiez les montages actuels.
    sudo mount -l | grep cgroup

    Si la sortie affiche déjà cgroup2 sur /sys/fs/cgroup, aucune autre action n'est requise.

  2. Ajoutez le paramètre d'initialisation de hiérarchie unifiée.
    sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"

    La commande ajoute systemd.unified_cgroup_hierarchy=1 à chaque entrée de noyau de sorte que la version 2 soit montée à l'initialisation.

  3. Réinitialisez pour appliquer la modification.
  4. Vérifiez que cgroups v2 est monté.
    sudo mount -l | grep cgroup

    Recherchez cgroup2 on /sys/fs/cgroup dans la sortie.

Vérifier les cgroups v2 sur Oracle Linux 9 et Oracle Linux 10

Confirmez le point de montage.
sudo mount -l | grep cgroup
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,seclabel,nsdelegate,memory_recursiveprot)

A propos des contrôleurs de ressources de noyau

Les groupes de contrôle gèrent l'utilisation des ressources via des contrôleurs de ressources du noyau. Un contrôleur de ressources de noyau représente une ressource unique, telle que le temps CPU, la mémoire, la bande passante réseau ou les E/S de disque.

Pour identifier les contrôleurs de ressources montés dans le système, vérifiez le contenu du fichier /procs/cgroups, par exemple exécutez :

less /proc/cgroups
#subsys_name    hierarchy       num_cgroups     enabled
cpuset  0       103     1
cpu     0       103     1
cpuacct 0       103     1
blkio   0       103     1
memory  0       103     1
devices 0       103     1
freezer 0       103     1
net_cls 0       103     1
perf_event      0       103     1
net_prio        0       103     1
hugetlb 0       103     1
pids    0       103     1
rdma    0       103     1
misc    0       103     1

Pour une explication détaillée des contrôleurs de ressources de noyau de cgroups, reportez-vous à la page de manuel cgroups(7).

A propos du système de fichiers de groupe de contrôle

La fonctionnalité cgroup est montée en tant que système de fichiers hiérarchique dans /sys/fs/cgroup.

Le répertoire /sys/fs/cgroup est également appelé groupe de contrôle racine.

Le contenu du répertoire du groupe de contrôle root varie légèrement en fonction de la version montée, mais sur les systèmes utilisant cgroups v2, vous voyez généralement des entrées similaires aux suivantes :

ls /sys/fs/cgroup
cgroup.controllers      cpuset.mems.effective  memory.stat
cgroup.max.depth        cpu.stat               misc.capacity
cgroup.max.descendants  dev-hugepages.mount    sys-fs-fuse-connections.mount
cgroup.procs            dev-mqueue.mount       sys-kernel-config.mount
cgroup.stat             init.scope             sys-kernel-debug.mount
cgroup.subtree_control  io.pressure            sys-kernel-tracing.mount
cgroup.threads          io.stat                system.slice
cpu.pressure            memory.numa_stat       user.slice
cpuset.cpus.effective   memory.pressure
Vous pouvez utiliser la commande mkdir pour créer des sous-répertoires cgroup dans le groupe de contrôle root. Par exemple, vous pouvez créer les sous-répertoires cgroup suivants :
  • /sys/fs/cgroup/MyGroups/

  • /sys/fs/cgroup/MyGroups/cgroup1

  • /sys/fs/cgroup/MyGroups/cgroup2

Remarque

La meilleure pratique de conception consiste à ce que l'élément cgroups enfant soit d'au moins 2 niveaux au sein de l'élément /sys/fs/cgroup. Les exemples de la liste précédente suivent cet exercice en utilisant le premier groupe enfant, MyGroups, en tant que parent qui contient les différents éléments cgroups nécessaires pour le système.

Chaque élément cgroup de la hiérarchie contient les fichiers suivants :

cgroup.controllers

Ce fichier en lecture seule répertorie les contrôleurs disponibles dans le fichier cgroup actuel. Le contenu de ce fichier correspond au contenu du fichier cgroup.subtree_control dans le fichier parent cgroup.

cgroup.subtree_control

Ce fichier contient les contrôleurs dans le fichier cgroup.controllers qui sont activés pour l'enfant immédiat de cgroup en cours cgroups.

Lorsqu'un contrôleur (par exemple, pids) est présent dans le fichier cgroup.subtree_control, les fichiers d'interface de contrôleur correspondants (par exemple, pids.max) sont automatiquement créés dans les enfants immédiats du fichier cgroup actuel.

Pour obtenir un exemple de procédure permettant de créer des groupes enfant dans lesquels vous pouvez implémenter la gestion des ressources pour une application, reportez-vous à la section Setting CPU Weight to Regulate Distribution of CPU Time.

Pour enlever une valeur cgroup, assurez-vous que la valeur cgroup ne contient pas d'autres groupes enfant, puis enlevez le répertoire. Par exemple, pour enlever le groupe enfant /sys/fs/cgroup/MyGroups/cgroup1, vous pouvez exécuter la commande suivante :

sudo rmdir /sys/fs/cgroup/MyGroups/cgroup1

A propos des modèles de distribution des ressources

Les modèles de distribution suivants vous permettent d'implémenter le contrôle ou la réglementation dans la distribution des ressources à utiliser par cgroups v2 :

Pondérations

Dans ce modèle, les poids de tous les groupes de contrôle sont totalisés. Chaque groupe reçoit une fraction de la ressource en fonction du rapport entre le poids du groupe et le poids total.

Considérez 10 groupes témoins, chacun ayant un poids de 100 pour un total combiné de 1000. Dans ce cas, chaque groupe peut utiliser un dixième d'une ressource spécifiée.

Le poids est généralement utilisé pour distribuer les ressources sans conservation de statut. Pour appliquer cette ressource, l'option CPUWeight est utilisée.

Limites

Dans ce modèle, un groupe peut utiliser la quantité configurée d'une ressource. Si une ressource telle que l'utilisation de la mémoire pour un processus dépasse la limite, le noyau peut arrêter le processus avec un message de manque de mémoire (oom).

Vous pouvez également surengager des ressources afin que la somme des limites des sous-groupes puisse dépasser la limite du groupe parent. L'engagement excessif suppose que les ressources de tous les sous-groupes n'atteignent pas toutes leurs limites en même temps.

Pour implémenter ce modèle de distribution, l'option MemoryMax est souvent utilisée.

Protections

Dans ce modèle, une limite protégée est affectée à un groupe. Si l'utilisation de la ressource du groupe reste dans la quantité protégée, le noyau ne peut pas priver le groupe de l'utilisation de la ressource au profit d'autres groupes qui sont en concurrence pour la même ressource. Dans ce modèle, un surengagement de ressources est autorisé.

Pour implémenter ce modèle, l'option MemoryLow est souvent utilisée.

Répartitions

Dans ce modèle, un montant absolu spécifique est alloué pour l'utilisation de ressources de type fini, telles que le budget en temps réel.

Gestion des cgroups v2 à l'aide de sysfs

Montre comment créer et régler des hiérarchies de cgroups v2 directement dans /sys/fs/cgroup à des fins de dépannage ou de tests temporaires.

Important

Utilisez systemd pour gérer toutes les ressources lorsque cela est possible. Pour plus d'informations, reportez-vous à Utilisation de Systemd pour gérer les groupes de contrôle.

Les exemples fournis ici fournissent le contexte des actions effectuées par systemd sur un système et montrent les fonctionnalités en dehors de systemd. Les informations fournies peuvent être utiles lors du débogage de problèmes avec cgroups.

L'exemple de procédure consiste à allouer du temps CPU entre cgroups et le fait que des PID d'application différents leur sont affectés. Les valeurs de temps CPU et de PID d'application sont définies dans les fichiers cpu.weight et cgroup.procs de chaque groupe.

L'exemple inclut également les étapes requises pour garantir que le contrôleur cpu et ses fichiers associés, y compris le fichier cpu.weight, sont disponibles dans le fichier cgroups que vous devez créer sous /sys/fs/cgroup.

Préparation du groupe de contrôle pour la distribution du temps CPU

Cette procédure explique comment préparer manuellement un groupe de contrôle pour gérer la répartition du temps CPU. L'approche recommandée pour la configuration des groupes de contrôle est d'utiliser systemd.

  1. Vérifiez que le contrôleur cpu est disponible en haut de la hiérarchie, dans le groupe de contrôle racine.

    Impression du contenu du fichier /sys/fs/cgroup/cgroup.controllers à l'écran :

    sudo cat /sys/fs/cgroup/cgroup.controllers
    cpuset cpu io memory hugetlb pids rdma misc

    Vous pouvez ajouter tous les contrôleurs répertoriés dans le fichier cgroup.controllers au fichier cgroup.subtree_control dans le même répertoire pour les mettre à la disposition de l'enfant immédiat du groupe cgroups.

  2. Ajoutez le contrôleur cpu au fichier cgroup.subtree_control pour le mettre à la disposition de l'enfant immédiat cgroups de la racine.

    Par défaut, seuls les contrôleurs memory et pids se trouvent dans le fichier. Pour ajouter le contrôleur cpu, saisissez :

    echo "+cpu" | sudo tee /sys/fs/cgroup/cgroup.subtree_control
    
  3. Vérifiez éventuellement que le contrôleur cpu a été ajouté comme prévu.
    sudo cat /sys/fs/cgroup/cgroup.subtree_control
    cpu memory pids
  4. Créez un groupe enfant sous le groupe de contrôle root afin de devenir le nouveau groupe de contrôle pour la gestion des ressources CPU sur les applications.
    sudo mkdir /sys/fs/cgroup/MyGroups
  5. Vous pouvez éventuellement répertorier le contenu du nouveau sous-répertoire, ou groupe enfant, et confirmer que le contrôleur cpu est présent comme prévu.
    ls -l /sys/fs/cgroup/MyGroups
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 cgroup.controllers
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 cgroup.events
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cgroup.freeze
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cgroup.max.depth
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cgroup.max.descendants
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cgroup.procs
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 cgroup.stat
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cgroup.subtree_control
    …​
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 cpu.stat
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cpu.weight
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 cpu.weight.nice
    …​
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 memory.events.local
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 memory.high
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 memory.low
    …​
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 pids.current
    -r—​r—​r--. 1 root root 0 Jun  1 10:33 pids.events
    -rw-r—​r--. 1 root root 0 Jun  1 10:33 pids.max
  6. Activez le contrôleur cpu dans le fichier cgroup.subtree_control du répertoire MyGroups pour le mettre à la disposition de son enfant immédiat cgroups.
    echo "+cpu" | sudo tee /sys/fs/cgroup/MyGroups/cgroup.subtree_control
  7. Vérifiez éventuellement que le contrôleur cpu est activé pour les groupes enfant sous MyGroups.
    sudo cat /sys/fs/cgroup/MyGroups/cgroup.subtree_control
    cpu

Définition du poids de la CPU pour réguler la distribution du temps CPU

Cette procédure décrit comment définir la pondération de la CPU pour trois processus différents en utilisant un groupe de contrôle pour gérer la répartition du temps CPU. L'approche recommandée pour la configuration des groupes de contrôle est d'utiliser systemd.

Cette procédure repose sur les hypothèses suivantes :

  • L'application qui consomme trop de ressources CPU est sha1sum, comme indiqué dans l'exemple de sortie suivant de la commande top :

    sudo top
    ...
    PID   USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
    33301 root      20   0   18720   1756   1468 R  99.0   0.0   0:31.09 sha1sum
    33302 root      20   0   18720   1772   1480 R  99.0   0.0   0:30.54 sha1sum
    33303 root      20   0   18720   1772   1480 R  99.0   0.0   0:30.54 sha1sum
    1 root      20   0  109724  17196  11032 S   0.0   0.1   0:03.28 systemd                     
    2 root      20   0       0      0      0 S   0.0   0.0   0:00.00 kthreadd                    
    3 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_gp                      
    4 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_par_gp                  
              ...
  • Les processus sha1sum ont des ID personnalisés 33301, 33302 et 33303, comme indiqué dans l'exemple de sortie précédent.

Important

Avant de procéder à la procédure suivante, vous devez effectuer les préparatifs de cgroup-v2 comme décrit dans la section Preparing the Control Group for Distribution of CPU Time. Si vous avez ignoré ces préparatifs, vous ne pouvez pas terminer cette procédure.

  1. Créez 3 groupes enfant dans le sous-répertoire MyGroups.
    sudo mkdir /sys/fs/cgroup/MyGroups/g1
    sudo mkdir /sys/fs/cgroup/MyGroups/g2
    sudo mkdir /sys/fs/cgroup/MyGroups/g3
  2. Configurez le poids de la CPU pour chaque groupe enfant.
    echo "150" | sudo tee /sys/fs/cgroup/MyGroups/g1/cpu.weight
    echo "100" | sudo tee /sys/fs/cgroup/MyGroups/g2/cpu.weight
    echo "50" | sudo tee /sys/fs/cgroup/MyGroups/g3/cpu.weight
  3. Appliquez les ID personnalisés de l'application aux groupes enfant correspondants.
    echo "33301" | sudo tee /sys/fs/cgroup/MyGroups/g1/cgroup.procs
    echo "33302" | sudo tee /sys/fs/cgroup/MyGroups/g2/cgroup.procs
    echo "33303" | sudo /sys/fs/cgroup/MyGroups/g3/cgroup.procs

    Ces commandes définissent les applications sélectionnées pour qu'elles deviennent membres des groupes de contrôle MyGroups/g*/. Le temps CPU de chaque processus sha1sum dépend de la répartition du temps CPU configurée pour chaque groupe.

    Les poids des groupes g1, g2 et g3 qui ont des processus en cours d'exécution sont récapitulés au niveau de MyGroups, qui est le groupe de contrôle parent.

    Avec cette configuration, lorsque tous les processus s'exécutent en même temps, le noyau alloue à chacun des processus sha1sum le temps CPU proportionné en fonction du fichier cpu.weight de leur cgroup respectif, comme suit :

    Groupe enfant Paramètre cpu.weight Pourcentage d'allocation de temps CPU
    g1 150 ~50% (150/300)
    g2 100 ~33% (100/300)
    g3 50 ~16% (50/300)

    Si un groupe enfant n'a pas de processus en cours d'exécution, l'allocation de temps CPU pour les processus en cours d'exécution est recalculée en fonction du poids total des groupes enfants restants avec des processus en cours d'exécution. Par exemple, si le groupe enfant g2 n'a aucun processus en cours d'exécution, le poids total devient 200, soit le poids de g1+g3. Dans ce cas, le temps CPU de g1 devient 150/200 (~75%) et de g3, 50/200 (~25%)

  4. Vérifiez que les applications s'exécutent dans les groupes de contrôle spécifiés.
    sudo cat /proc/33301/cgroup /proc/33302/cgroup /proc/33303/cgroup
    0::/MyGroups/g1
    0::/MyGroups/g2
    0::/MyGroups/g3
  5. Vérifiez la consommation actuelle de la CPU après avoir défini les poids de la CPU.
    top
    ...
    PID   USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
    33301 root      20   0   18720   1748   1460 R  49.5   0.0 415:05.87 sha1sum
    33302 root      20   0   18720   1756   1464 R  32.9   0.0 412:58.33 sha1sum
    33303 root      20   0   18720   1860   1568 R  16.3   0.0 411:03.12 sha1sum
    760 root      20   0  416620  28540  15296 S   0.3   0.7   0:10.23 tuned
    1 root      20   0  186328  14108   9484 S   0.0   0.4   0:02.00 systemd
    2 root      20   0       0      0      0 S   0.0   0.0   0:00.01 kthread
    ...