Utiliser Systemd pour gérer les groupes de contrôle
Présente les concepts de cgroups dans Oracle Linux et montre comment systemd organise et gère le contrôle des ressources.
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 devez répartir la ressource de CPU entre trois services systemd, myservice1.service, myservice2.service et myservice3.service, dans un rapport de 150:100:50, vous pouvez utiliser les outils systemd pour affecter à chaque service cgroup correspondant une pondération de CPU correspondant à sa part cible.
systemd est responsable de la création et de la gestion de cgroups dans le système de fichiers virtuel /sys/fs/cgroup/.
La suite systemd fournit des méthodes sécurisées de haut niveau pour configurer les ressources cgroup, telles que l'utilisation de fichiers de dépôt ou de la commande systemctl set-property. La modification directe des objets systemd dans le système de fichiers virtuel /sys/fs/cgroup/ n'est pas recommandée.
Par défaut, systemd crée une valeur cgroup pour les éléments suivants :
-
Chaque service
systemdest configuré sur l'hôte.Par exemple, un serveur peut avoir le groupe de contrôle
NetworkManager.servicepour regrouper les processus appartenant au serviceNetworkManager, et le groupe de contrôlefirewalld.servicepour regrouper les processus appartenant au servicefirewalld, 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 a un dossier 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 élément cgroups personnalisé en dehors des branches systemd, par exemple sous un emplacement tel que /sys/fs/cgroup/MyGroups/, et affecter des ID de processus (PIDs) à des éléments cgroups différents en fonction des besoins du système. Cependant, cette approche ne doit être utilisée que pour des scénarios spécifiques, tels que le débogage ou les tests temporaires. Pour la plupart des cas d'utilisation, nous recommandons d'utiliser systemd pour configurer cgroups afin de garantir une gestion correcte et persistante des ressources.
Oracle Linux fournit deux types de groupe de contrôle :
- Groupes de contrôle version 1 (
cgroups v1) -
Ces groupes fournissent une hiérarchie de contrôleurs par ressource.
Chaque ressource (CPU, mémoire, E/S, etc.) possède sa propre hiérarchie de groupes de contrôle. Un inconvénient de ce groupe est la difficulté d'établir une bonne coordination de l'utilisation des ressources entre les groupes qui pourraient appartenir à des hiérarchies de processus différentes.
- Groupes de contrôle version 2 (
cgroups v2) -
Ces groupes fournissent une hiérarchie de groupes de contrôle unique par rapport à laquelle tous les contrôleurs de ressources sont montés. Dans cette hiérarchie, vous pouvez obtenir une meilleure coordination des utilisations des ressources entre les différents contrôleurs de ressources. Cette version est une amélioration par rapport à
cgroups v1dont la flexibilité excessive a empêché une bonne coordination de l'utilisation des ressources entre les consommateurs du système.
Oracle Linux 8 inclut les deux versions, cgroups v1 étant activé et monté par défaut. Oracle Linux 9 fournit également les deux versions, mais active et monte cgroups v2 par défaut.
Oracle Linux 10 offre uniquement l'implémentation de la version 2 des groupes de contrôle. cgroups v1 est en phase d'abandon et n'est pas disponible. cgroups v2 est activé et monté par défaut.
Pour plus d'informations sur les groupes de contrôle, reportez-vous aux pages de manuel cgroups(7) et sysfs(5).
A propos des groupes de contrôle et de systemd
Les groupes de contrôle peuvent être utilisés par le système systemd et le gestionnaire de services pour la gestion des ressources. systemd utilise ces groupes pour organiser les unités et les services qui consomment des ressources. Pour plus d'informations sur systemd, reportez-vous à Gestion du système avec systemd.
systemd fournit différents types d'unité, dont trois à des fins de contrôle des ressources :
-
Service : processus ou groupe de processus dont les paramètres sont basés sur un fichier de configuration d'unité. Les services englobent des processus spécifiés dans une "collecte" de sorte que
systemdpuisse démarrer ou arrêter les processus en un seul ensemble. Les noms de service suivent le formatname.service. -
Portée : groupe de processus créés en externe, tels que les sessions utilisateur, les conteneurs, les machines virtuelles, etc.
Comme pour les services, les portées encapsulent ces processus créés et sont démarrées ou arrêtées par les processus arbitraires, puis inscrites par
systemdlors de l'exécution. Les noms de portée suivent le formatname.scope. -
Tranche : groupe d'unités organisées hiérarchiquement dans lequel se trouvent les services et les portées.
Ainsi, les tranches elles-mêmes ne contiennent pas de processus. Les portées et les services d'une tranche définissent plutôt les processus. Chaque nom d'unité de tranche correspond au chemin d'accès à un emplacement dans la hiérarchie. Les tranches racine, généralement
user.slicepour tous les processus utilisateur etsystem.slicepour les processus système, sont créées automatiquement dans la hiérarchie. Les tranches parent existent immédiatement sous la tranche racine et suivent le formatparent-name.slice. Ces tranches racine peuvent alors avoir des sous-tranches sur plusieurs niveaux.
Le service, la portée et les unités de tranche sont directement mappés avec les objets de la hiérarchie des groupes de contrôle. Lorsque ces unités sont activées, elles sont mappées directement avec les chemins de groupe de contrôle créés à partir des noms d'unités. Pour afficher la correspondance entre les types d'unité de ressource systemd et les groupes de contrôle, saisissez :
sudo systemd-cgls
Working directory /sys/fs/cgroup:
├─user.slice (#1243)
│ → trusted.invocation_id: 50ce3909b2644f919ee420adc39edb4b
│ ├─user-1001.slice (#4167)
│ │ → trusted.invocation_id: 02e80a960d4549a7a9c69ce0fb546c26
│ │ ├─session-2.scope (#4405)
│ │ │ ├─2417 sshd: alice [priv]
│ │ │ ├─2430 sshd: alice@pts/0
│ │ │ ├─2431 -bash
│ │ │ ├─2689 sudo systemd-cgls
│ │ │ ├─2691 systemd-cgls
│ │ │ └─2692 less
...
│ └─user@984.service … (#3827)
│ → trusted.delegate: 1
│ → trusted.invocation_id: 09b47ce9f3124239b75814114353f3f2
│ └─init.scope (#3861)
│ ├─2058 /usr/lib/systemd/systemd --user
│ └─2099 (sd-pam)
├─init.scope (#19)
│ └─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 17
└─system.slice (#53)
...
├─chronyd.service (#2467)
│ → trusted.invocation_id: c0f77aaa9c7844e6bef6a6898ae4dd56
│ └─1358 /usr/sbin/chronyd -F 2
├─auditd.service (#2331)
│ → trusted.invocation_id: 756808add6a348609316c9e8c1801846
│ └─1310 /sbin/auditd
├─tuned.service (#3079)
│ → trusted.invocation_id: 2c358135fc46464d862b05550338d4f4
│ └─1415 /usr/bin/python3 -Es /usr/sbin/tuned -l -P
├─systemd-journald.service (#1651)
│ → trusted.invocation_id: 7cb7ccb14e044a899aadf47bbb583ada
│ └─977 /usr/lib/systemd/systemd-journald
├─atd.service (#3623)
│ → trusted.invocation_id: 597a7a4e5646468db407801b8562d869
│ └─1915 /usr/sbin/atd -f
├─sshd.service (#3419)
│ → trusted.invocation_id: 490504a683fc4311ab0fbeb0864a1a34
│ └─1871 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
...
Pour obtenir un exemple d'utilisation des commandes systemd telles que systemctl pour gérer les ressources, reportez-vous à Contrôle de l'accès aux ressources système. Pour plus de détails techniques, reportez-vous aux pages de manuel systemctl(1), systemd-cgls(1) et systemd.resource-control(5).
Utilisation de systemd pour gérer les cgroups v2
Montre comment systemd structure les cgroups v2 pour les services et les utilisateurs et comment inspecter la hiérarchie.
La méthode préférée pour gérer l'allocation de ressources avec cgroups v2 est d'utiliser la fonctionnalité de groupe de contrôle fournie par systemd.
Pour plus d'informations sur l'activation de la fonctionnalité cgroups v2 sur le système, reportez-vous à la section Managing Resources Using Control Groups
Par défaut, systemd crée un dossier cgroup pour chaque service systemd configuré sur l'hôte. systemd nomme ces dossiers au format servicename.service, où servicename est le nom du service associé au dossier.
Pour afficher la liste des dossiers cgroup créés par systemd pour les services, exécutez la commande ls sur la branche system.slice du système de fichiers cgroup, comme indiqué dans l'exemple de bloc de code suivant :
ls /sys/fs/cgroup/system.slice/
... ... ...
app_service1.service cgroup.subtree_control httpd.service
app_service2.service chronyd.service ...
... crond.service ...
cgroup.controllers dbus-broker.service ...
cgroup.events dtprobed.service ...
cgroup.freeze firewalld.service ...
... gssproxy.service ...
... ... ...
Dans le bloc de commande précédent :
-
Les dossiers app_service1.
serviceet app_service2.servicereprésentent les services d'application personnalisés qui peuvent s'exécuter sur le système.
Outre les groupes de contrôle de service, systemd crée également un dossier cgroup pour chaque utilisateur sur l'hôte.
Pour voir le fichier cgroups créé pour chaque utilisateur, vous pouvez exécuter la commande ls sur la branche user.slice du système de fichiers cgroup, comme indiqué dans l'exemple de bloc de code suivant :
ls /sys/fs/cgroup/user.slice/
cgroup.controllers cgroup.subtree_control user-1001.slice
cgroup.events cgroup.threads user-982.slice
cgroup.freeze cgroup.type ...
... ... ...
... ... ...
... ... ...
Dans le bloc de code précédent :
-
Chaque dossier utilisateur
cgroupest nommé au formatuser-UID.slice. Par conséquent, le groupe de contrôleuser-1001.sliceest destiné à un utilisateur dontUIDest 1001, par exemple.
systemd fournit un accès de haut niveau aux fonctionnalités cgroups et de contrôleur de ressources de noyau afin que vous n'ayez pas à accéder directement au système de fichiers.
Par exemple, pour définir la pondération de la CPU d'un service appelé app_service1.service, exécutez la commande systemctl set-property comme suit :
sudo systemctl set-property app_service1.service CPUWeight=150
Ainsi, systemd vous permet de gérer la distribution des ressources au niveau de l'application, plutôt qu'au niveau du PID de processus utilisé lors de la configuration de cgroups sans utiliser la fonctionnalité systemd.
A propos des tranches et de l'allocation des ressources dans systemd
Cette section examine la façon dont systemd divise initialement chacun des contrôleurs de noyau par défaut, par exemple CPU, memory et blkio, en parties appelées "tranches", comme illustré par l'exemple de graphique à secteurs suivant :
Vous pouvez également créer des tranches personnalisées pour la distribution des ressources, comme indiqué dans la section Définition des options de contrôleur de ressources et création de tranches personnalisées.

Comme le montre le graphique à secteurs précédent, chaque contrôleur de ressources est divisé par défaut de manière égale entre les 3 tranches suivantes :
-
Système (
system.slice). -
Utilisateur (
user.slice). -
Machine (
machine.slice).
La liste suivante examine chaque tranche de plus près. Pour les besoins de la discussion, les exemples de la liste se concentrent sur le contrôleur de CPU.
- Système (
system.slice) -
Cette tranche de ressources est utilisée pour gérer l'allocation des ressources entre les démons et les unités de service.
Comme indiqué dans l'exemple de graphique à secteurs précédent, la tranche système est divisée en autres sous-tranches. Par exemple, dans le cas de ressources CPU, nous pouvons disposer d'allocations de sous-tranches dans la tranche système qui incluent les éléments suivants :-
httpd.service(CPUWeight=100) -
sshd.service(CPUWeight= 100) -
crond.service(CPUWeight= 100) -
app1.
service(CPUWeight=100) -
app2.
service(CPUWeight=100)
serviceet app2.servicereprésentent les services d'application personnalisés qui peuvent s'exécuter sur le système. -
- Utilisateur (
user.slice) - Cette tranche de ressource est utilisée pour gérer l'allocation des ressources entre les sessions utilisateur. Une tranche unique est créée pour chaque
UID, quel que soit le nombre de connexions actives par l'utilisateur associé sur le serveur. En continuant avec notre exemple de graphique à secteurs, les sous-tranches peuvent être les suivantes :-
user1 (
CPUWeight=100,UID=982) -
user2 (
CPUWeight=100,UID=1001)
-
- Machine (
machine.slice) - Cette tranche de la ressource est utilisée pour gérer l'allocation des ressources entre les machines virtuelles hébergées, telles que les invités KVM et les conteneurs Linux. La tranche de machine n'est présente sur un serveur que si ce dernier héberge des machines virtuelles ou des conteneurs Linux.
Les allocations de partage ne définissent pas de limite maximale pour une ressource.
Dans les exemples précédents, la tranche user.slice compte 2 utilisateurs : user1 et user2. Une part égale de la ressource de CPU disponible pour le parent user.slice est allouée à chaque utilisateur. Toutefois, si les processus associés à user1 sont inactifs et ne nécessitent aucune ressource de CPU, son partage de CPU est disponible pour l'allocation à user2 si nécessaire. Dans ce cas, user2 peut même être alloué à la ressource CPU entière répartie sur le parent user.slice si cela est requis par d'autres utilisateurs.
Pour limiter la ressource CPU, vous devez définir la propriété CPUQuota sur le pourcentage requis.
Tranches, services et portées dans la hiérarchie cgroup
L'analogie des graphiques à secteurs utilisée dans les sections précédentes permet de conceptualiser la division des ressources en tranches. Cependant, en termes d'organisation structurelle, les groupes de contrôle sont organisés dans une hiérarchie. Vous pouvez afficher la hiérarchie de groupe de contrôle systemd sur le système en exécutant la commande systemd-cgls comme suit :
Pour afficher l'intégralité de la hiérarchie cgroup, en commençant par la tranche racine -.slice, comme dans l'exemple suivant, veillez à exécuter systemd-cgls à partir de l'extérieur du point de montage du groupe de contrôle /sys/fs/cgroup/.
Sinon, si vous exécutez la commande à partir de /sys/fs/cgroup/, la sortie commence à partir de l'emplacement cgroup à partir duquel la commande a été exécutée. Pour plus d'informations, reportez-vous à systemd-cgls(1).
systemd-cgls
Control group /:
-.slice
...
├─user.slice (#1429)
│ → user.invocation_id: 604cf5ef07fa4bb4bb86993bb5ec15e0
│ ├─user-982.slice (#4131)
│ │ → user.invocation_id: 9d0d94d7b8a54bcea2498048911136c8
│ │ ├─session-c1.scope (#4437)
│ │ │ ├─2416 /usr/bin/sudo -u ocarun /usr/libexec/oracle-cloud-agent/plugins/runcommand/runcommand
│ │ │ └─2494 /usr/libexec/oracle-cloud-agent/plugins/runcommand/runcommand
│ │ └─user@982.service … (#4199)
│ │ → user.delegate: 1
│ │ → user.invocation_id: 37c7aed7aa6e4874980b79616acf0c82
│ │ └─init.scope (#4233)
│ │ ├─2437 /usr/lib/systemd/systemd --user
│ │ └─2445 (sd-pam)
│ └─user-1001.slice (#7225)
│ → user.invocation_id: ce93ad5f5299407e9477964494df63b7
│ ├─session-2.scope (#7463)
│ │ ├─20304 sshd: oracle [priv]
│ │ ├─20404 sshd: oracle@pts/0
│ │ ├─20405 -bash
│ │ ├─20441 systemd-cgls
│ │ └─20442 less
│ └─user@1001.service … (#7293)
│ → user.delegate: 1
│ → user.invocation_id: 70284db060c1476db5f3633e5fda7fba
│ └─init.scope (#7327)
│ ├─20395 /usr/lib/systemd/systemd --user
│ └─20397 (sd-pam)
├─init.scope (#19)
│ └─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 28
└─system.slice (#53)
...
├─dbus-broker.service (#2737)
│ → user.invocation_id: 2bbe054a2c4d49809b16cb9c6552d5a6
│ ├─1450 /usr/bin/dbus-broker-launch --scope system --audit
│ └─1457 dbus-broker --log 4 --controller 9 --machine-id 852951209c274cfea35a953ad2964622 --max-bytes 536870912 --max-fds 4096 --max-matches 131072 --audit
...
├─chronyd.service (#2805)
│ → user.invocation_id: e264f67ad6114ad5afbe7929142faa4b
│ └─1482 /usr/sbin/chronyd -F 2
├─auditd.service (#2601)
│ → user.invocation_id: f7a8286921734949b73849b4642e3277
│ ├─1421 /sbin/auditd
│ └─1423 /usr/sbin/sedispatch
├─tuned.service (#3349)
│ → user.invocation_id: fec7f73678754ed687e3910017886c5e
│ └─1564 /usr/bin/python3 -Es /usr/sbin/tuned -l -P
├─systemd-journald.service (#1837)
│ → user.invocation_id: bf7fb22ba12f44afab3054aab661aedb
│ └─1068 /usr/lib/systemd/systemd-journald
├─atd.service (#3961)
│ → user.invocation_id: 1c59679265ab492482bfdc9c02f5eec5
│ └─2146 /usr/sbin/atd -f
├─sshd.service (#3757)
│ → user.invocation_id: 57e195491341431298db233e998fb180
│ └─2097 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
├─crond.service (#3995)
│ → user.invocation_id: 4f5b380a53db4de5adcf23f35d638ff5
│ └─2150 /usr/sbin/crond -n
...
L'exemple de sortie précédent montre comment tous les groupes de contrôle "*.slice" résident sous la tranche racine -.slice. Sous la tranche racine, vous pouvez voir les groupes de contrôle user.slice et system.slice, chacun avec ses propres sous-tranches enfant cgroup.
En examinant la sortie de la commande systemd-cgls , vous pouvez voir comment, à l'exception de root -.slice, tous les processus se trouvent sur des noeuds feuille. Cette disposition est appliquée par cgroups v2, dans une règle appelée règle "aucun processus interne". Pour plus d'informations sur la règle "aucun processus interne", reportez-vous à la page cgroups (7).
La sortie de l'exemple de commande systemd-cgls précédent montre également comment les tranches peuvent avoir des groupes de contrôle enfant descendants qui sont des portées systemd. Les portées systemd sont examinées dans la section suivante.
Portées systemd
La portée systemd est un type d'unité systemd qui regroupe les processus actifs de service système qui ont été lancés indépendamment de systemd. Les unités de portée sont des unités cgroups transitoires créées par programmation à l'aide des interfaces de bus de systemd.
Par exemple, dans l'exemple de code suivant, l'utilisateur avec UID 1001 a exécuté la commande systemd-cgls, et la sortie indique que session-2.scope a été créé pour les processus que l'utilisateur a générés indépendamment de systemd (y compris le processus pour la commande elle-même, 21380 sudo systemd-cgls) :
Dans l'exemple suivant, la commande a été exécutée à partir du point de montage du groupe de contrôle
/sys/fs/cgroup/. Par conséquent, au lieu de la tranche racine, la sortie commence à partir de l'emplacement cgroup à partir duquel la commande a été exécutée.sudo systemd-cgls
Working directory /sys/fs/cgroup:
...
├─user.slice (#1429)
│ → user.invocation_id: 604cf5ef07fa4bb4bb86993bb5ec15e0
│ → trusted.invocation_id: 604cf5ef07fa4bb4bb86993bb5ec15e0
...
│ └─user-1001.slice (#7225)
│ → user.invocation_id: ce93ad5f5299407e9477964494df63b7
│ → trusted.invocation_id: ce93ad5f5299407e9477964494df63b7
│ ├─session-2.scope (#7463)
│ │ ├─20304 sshd: oracle [priv]
│ │ ├─20404 sshd: oracle@pts/0
│ │ ├─20405 -bash
│ │ ├─21380 sudo systemd-cgls
│ │ ├─21382 systemd-cgls
│ │ └─21383 less
│ └─user@1001.service … (#7293)
│ → user.delegate: 1
│ → trusted.delegate: 1
│ → user.invocation_id: 70284db060c1476db5f3633e5fda7fba
│ → trusted.invocation_id: 70284db060c1476db5f3633e5fda7fba
│ └─init.scope (#7327)
│ ├─20395 /usr/lib/systemd/systemd --user
│ └─20397 (sd-pam)
Définition des options du contrôleur de ressources et création de tranches personnalisées
Présente trois approches (fichiers d'unité, drop-ins et systemctl set-property) pour affiner les contrôleurs de ressources et les dispositions de tranche.
systemd fournit les méthodes suivantes pour définir les options de contrôleur de ressources, telles que CPUWeight, CPUQuota, etc., afin de personnaliser l'allocation de ressources sur le système :
-
Utilisation des fichiers d'unité de service.
-
Utilisation de fichiers de dépôt.
-
Utilisation de la commande
systemctl set-property.
Les sections suivantes fournissent des exemples de procédures d'utilisation de chacune de ces méthodes pour configurer les ressources et les tranches du système.
Utiliser des fichiers d'unité de service
Pour définir des options dans un fichier d'unité de service, procédez comme suit :
Utiliser des fichiers de dépôt
Pour configurer des ressources à l'aide d'un fichier de dépôt, procédez comme suit :
Utilisation de systemctl set-property
La commande systemctl set-property place les fichiers de configuration à l'emplacement suivant :
/etc/systemd/system.control
Vous ne devez pas modifier manuellement les fichiers créés par la commande systemctl set-property.
La commande systemctl set-property ne reconnaît pas toutes les propriétés de contrôle des ressources utilisées dans les fichiers d'unité système et de dépôt abordés précédemment dans cette rubrique.
La procédure suivante montre comment utiliser la commande systemctl set-property pour configurer l'allocation de ressources :