Utilisation de Systemd pour gérer les groupes de contrôle
Introduit les concepts 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 fonction de noyau Oracle Linux qui organise les services systemd et, si nécessaire, les processus individuels (PIDs) en groupes hiérarchiques pour l'affectation de ressources système, telles que l'UC, la mémoire et les E/S.
Par exemple, si vous devez diviser la ressource d'UC entre trois services systemd, myservice1.service, myservice2.service et myservice3.service, dans un ratio de 150:100:50, vous pouvez utiliser les outils systemd pour affecter à chaque service cgroup correspondant une pondération d'UC 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 moyens sécurisés de haut niveau pour configurer les ressources cgroup, par exemple en utilisant des fichiers de dépôt ou 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
systemdconfiguré sur l'hôte.Par exemple, un serveur peut avoir le groupe de contrôle
NetworkManager.servicepour regrouper les processus détenus par le serviceNetworkManageret le groupe de contrôlefirewalld.servicepour regrouper les processus détenus par le 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, 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 illustré 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 des cgroups personnalisés en dehors des branches systemd, par exemple sous un emplacement tel que /sys/fs/cgroup/MyGroups/, et affecter des ID processus (PIDs) à des 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 temporaire ou le test. Pour la plupart des cas d'utilisation, nous recommandons d'utiliser systemd pour configurer cgroups afin de garantir une gestion des ressources correcte et persistante.
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ôleur par ressource.
Chaque ressource, telle que la CPU, la mémoire, les 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 à différentes hiérarchies de processus.
- Groupes de contrôle version 2 (
cgroups v2) -
Ces groupes fournissent une hiérarchie de groupe de contrôle unique sur 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é 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 la mise en oeuvre de la version 2 des groupes de contrôle. cgroups v1 est obsolète et n'est pas disponible. cgroups v2 est activé et monté par défaut.
Pour plus d'informations sur les groupes de contrôle, voir les pages de manuel cgroups(7) et sysfs(5).
À propos des groupes de contrôle et 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, voir 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" afin que
systemdpuisse démarrer ou arrêter les processus en tant que jeu unique. Les noms de service respectent le formatname.service. -
Portée : Groupe de processus créés à l'externe, tels que les sessions d'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 enregistrées par
systemdlors de l'exécution. Les noms de portée respectent le formatname.scope. -
Tranche : Groupe d'unités organisées hiérarchiquement dans lequel se trouvent les services et les étendues.
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'une 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 basés sur l'utilisateur etsystem.slicepour les processus basés sur le système, sont créées automatiquement dans la hiérarchie. Les tranches parents existent immédiatement sous la tranche racine et suivent le formatparent-name.slice. Ces tranches racine peuvent ensuite comporter des sous-tranches à plusieurs niveaux.
Le service, la portée et les unités de tranche sont directement mappés aux objets de la hiérarchie du groupe de contrôle. Lorsque ces unités sont activées, elles sont mappées directement pour contrôler les chemins de groupe créés à partir des noms d'unités. Pour afficher le mappage entre les types d'unité de ressource systemd et les groupes de contrôle, entrez :
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 un exemple d'utilisation des commandes systemd telles que systemctl pour gérer les ressources, voir Contrôle de l'accès aux ressources du système. Pour plus de détails techniques, consultez les pages de manuel systemctl(1), systemd-cgls(1) et systemd.resource-control(5).
Utilisation de systemd pour gérer les cgroups v2
Indique comment systemd structure cgroups v2 pour les services et les utilisateurs et comment inspecter la hiérarchie.
La méthode privilégiée pour gérer l'affectation de ressources avec cgroups v2 consiste à 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, voir Gestion des ressources à l'aide de groupes de contrôle.
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 voir 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 illustré 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 commandes précédent :
-
Les dossiers app_service1.
serviceet app_service2.servicereprésentent des services d'application personnalisés qui peuvent s'exécuter sur le système.
En plus des groupes de contrôle de service, systemd crée également un dossier cgroup pour chaque utilisateur sur l'hôte.
Pour voir la valeur cgroups créée pour chaque utilisateur, vous pouvez exécuter la commande ls sur la branche user.slice du système de fichiers cgroup, comme illustré 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
cgroupd'utilisateur est nommé selon le formatuser-UID.slice. Ainsi, le groupe de contrôleuser-1001.sliceest destiné à un utilisateur dontUIDest 1001, par exemple.
systemd fournit un accès de haut niveau aux fonctions de contrôleur de ressources cgroups et de noyau afin que vous n'ayez pas à accéder directement au système de fichiers.
Par exemple, pour définir la pondération d'UC d'un service nommé 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 répartition des ressources au niveau de l'application, plutôt que le niveau PID du processus utilisé lors de la configuration de cgroups sans utiliser la fonctionnalité systemd.
À propos des tranches et de l'affectation de 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 répartition des ressources, comme indiqué dans la section Définition des options du 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. À des fins de discussion, les exemples de la liste se concentrent sur le contrôleur CPU.
- Système (
system.slice) -
Cette tranche de ressource est utilisée pour gérer l'affectation des ressources entre les démons et les unités de service.
Comme le montre l'exemple précédent de graphique à secteurs, le fragment de système est divisé en sous-tranches supplémentaires. Par exemple, dans le cas de ressources d'UC, nous pouvons avoir des 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 des services d'application personnalisés pouvant s'exécuter sur le système. -
- Utilisateur (
user.slice) - Cette tranche de ressource est utilisée pour gérer l'allocation de ressources entre les sessions d'utilisateur. Une seule tranche 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 clients KVM et les conteneurs Linux. La tranche de machine n'est présente sur un serveur que si le serveur 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. Un partage égal de la ressource d'UC disponible pour le parent user.slice est affecté à chaque utilisateur. Toutefois, si les processus associés à user1 sont inactifs et ne nécessitent aucune ressource d'UC, son partage d'UC est disponible pour affectation à user2 si nécessaire. Dans un tel cas, user2 peut même être affecté à l'ensemble de la ressource d'UC répartie sur le parent user.slice si elle est requise par d'autres utilisateurs.
Pour plafonner la ressource d'UC, vous devez régler la propriété CPUQuota au pourcentage requis.
Tranches, services et étendues dans la hiérarchie cgroup
L'analogie des graphiques à secteurs utilisée dans les sections précédentes est un moyen utile de conceptualiser la division des ressources en tranches. Cependant, en termes d'organisation structurelle, les groupes de contrôle sont organisés en une hiérarchie. Vous pouvez voir la hiérarchie du groupe de contrôle systemd sur le système en exécutant la commande systemd-cgls comme suit :
Pour voir la hiérarchie cgroup entière, à partir de la tranche racine -.slice, comme dans l'exemple suivant, assurez-vous d'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 à l'emplacement cgroup à partir duquel la commande a été exécutée. Voir systemd-cgls(1) pour plus d'informations.
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 ayant ses propres sous-tranches enfants cgroup.
En examinant la sortie de la commande systemd-cgls , vous pouvez voir comment, à l'exception de la racine -.slice, tous les processus se trouvent sur des noeuds feuilles. Cet arrangement est appliqué par cgroups v2, dans une règle appelée règle "aucun processus interne". Voir cgroups (7) pour plus d'informations sur la règle "aucun processus interne".
La sortie de l'exemple de commande systemd-cgls précédent montre également comment les tranches peuvent avoir des groupes de contrôle enfants descendants qui sont des portées systemd. Les portées systemd sont vérifiées dans la section suivante.
étendues systemd
La portée systemd est un type d'unité systemd qui regroupe les processus de traitement de service système lancés indépendamment de systemd. Les unités de portée sont des cgroups transitoires créés 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 affiche session-2.scope a été créé pour les processus que l'utilisateur a générés dynamiquement 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 régler avec précision 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'affectation de ressources sur le système :
-
utilisation des fichiers d'unités de service;
-
Utilisation de fichiers de dépôt.
-
À l'aide de la commande
systemctl set-property.
Les sections suivantes présentent des exemples de procédures permettant d'utiliser chacune de ces méthodes pour configurer des ressources et des tranches dans le système.
Utilisation des fichiers d'unités de service
Pour définir des options dans un fichier d'unité de service :
Utilisation de fichiers Drop-in
Pour configurer des ressources à l'aide d'un fichier de dépôt :
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 que la commande set-property systemctl crée.
La commande systemctl set-property ne reconnaît pas toutes les propriétés de contrôle de ressource utilisées dans les fichiers d'unité système et de dépôt décrits précédemment dans cette rubrique.
La procédure suivante montre comment utiliser la commande systemctl set-property pour configurer l'affectation de ressources :