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.

Note

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 systemd configuré sur l'hôte.

    Par exemple, un serveur peut avoir le groupe de contrôle NetworkManager.service pour regrouper les processus détenus par le service NetworkManager et le groupe de contrôle firewalld.service pour regrouper les processus détenus par le 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 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 v1 dont 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 systemd puisse démarrer ou arrêter les processus en tant que jeu unique. Les noms de service respectent le format name.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 systemd lors de l'exécution. Les noms de portée respectent le format name.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.slice pour tous les processus basés sur l'utilisateur et system.slice pour 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 format parent-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.

Note

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.service et app_service2.service repré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 cgroup d'utilisateur est nommé selon le format user-UID.slice. Ainsi, le groupe de contrôle user-1001.slice est destiné à un utilisateur dont UID est 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 :

Note

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.

Graphique à secteurs avec 3 tranches de taille égale, étiquetées Système, Machine et Utilisateur. L'utilisateur et le système sont divisés en sous-tranches.

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)

Dans la liste précédente, app1.service et app2.service repré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.
Note

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 :

Conseil

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) :

Note

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 :

  1. Créez le fichier /etc/systemd/system/myservice1.service avec le contenu suivant :
    [Service]
    Type=oneshot
    ExecStart=/usr/lib/systemd/generate_load.sh
    TimeoutSec=0
    StandardOutput=tty
    RemainAfterExit=yes
    
    [Install]
    WantedBy=multi-user.target
  2. Le service créé à l'étape précédente nécessite un script bash /usr/lib/systemd/generate_load.sh. Créez le fichier avec le contenu suivant :
    #!/bin/bash
    for i in {1..4};do while : ; do : ; done & done
  3. Rendre le script exécutable :
    sudo chmod +x /usr/lib/systemd/generate_load.sh
  4. Activez et démarrez le service :
    sudo systemctl enable myservice1 --now
  5. Exécutez la commande systemd-cgls et vérifiez que le service myservice1 s'exécute sous system.slice :
    systemd-cgls
    Control group /:
    -.slice
    ...
    ├─user.slice (#1429)
    ...
    └─system.slice (#53)
      ...
      ├─myservice1.service (#7939)
      │ → user.invocation_id: e227f8f288444fed92a976d391e6a897
      │ ├─22325 /bin/bash /usr/lib/systemd/generate_load.sh
      │ ├─22326 /bin/bash /usr/lib/systemd/generate_load.sh
      │ ├─22327 /bin/bash /usr/lib/systemd/generate_load.sh
      │ └─22328 /bin/bash /usr/lib/systemd/generate_load.sh
      ├─pmie.service (#4369)
      │ → user.invocation_id: 68fcd40071594481936edf0f1d7a8e12
       ...
  6. Créez une tranche personnalisée pour le service.

    Ajoutez la ligne Slice=my_custom_slice.slice à la section [Service] du fichier myservice1.service, créée à l'étape précédente, comme indiqué dans le bloc de code suivant :

    [Service]
    Slice=my_custom_slice.slice
    Type=oneshot
    ExecStart=/usr/lib/systemd/generate_load.sh
    TimeoutSec=0
    StandardOutput=tty
    RemainAfterExit=yes
    
    [Install]
    WantedBy=multi-user.target
    
    Attention

    Utilisez des traits de soulignement au lieu de tirets pour séparer les termes dans les noms de tranche.

    Dans systemd, un tiret dans un nom de tranche est un caractère spécial : dans systemd, les tirets dans les noms de tranche sont utilisés pour décrire le chemin cgroup complet de la tranche (à partir de la tranche racine).

    Par exemple, si vous spécifiez un nom de tranche comme "my-custom-slice.slice", au lieu de créer une tranche de ce nom, systemd crée le chemin cgroups suivant sous la tranche racine : my.slice/my-custom.slice/my-custom-slice.slice.

  7. Après avoir modifié le fichier, assurez-vous que systemd recharge ses fichiers de configuration, puis redémarrez le service :
    sudo systemctl daemon-reload
    sudo systemctl restart myservice1
  8. Exécutez la commande systemd-cgls et vérifiez que le service myservice1 est maintenant exécuté sous la tranche personnalisée my_custom_slice :
    systemd-cgls
    Control group /:
    -.slice
    ...
    ├─user.slice (#1429)
    ...
    ├─my_custom_slice.slice (#7973)
    │ → user.invocation_id: a8a493a8db1342be85e2cdf1e80255f8
    │ └─myservice1.service (#8007)
    │   → user.invocation_id: 9a4a6171f2844e479d4a0f347aac38ce
    │   ├─22385 /bin/bash /usr/lib/systemd/generate_load.sh
    │   ├─22386 /bin/bash /usr/lib/systemd/generate_load.sh
    │   ├─22387 /bin/bash /usr/lib/systemd/generate_load.sh
    │   └─22388 /bin/bash /usr/lib/systemd/generate_load.sh
    ├─init.scope (#19)
    │ └─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 28
    └─system.slice (#53)
      ├─irqbalance.service (#2907)
      │ → user.invocation_id: 00d64c9b9d224f179496a83536dd60bb
      │ └─1464 /usr/sbin/irqbalance --foreground
     ...
    

Utilisation de fichiers Drop-in

Pour configurer des ressources à l'aide d'un fichier de dépôt :

  1. Créez le répertoire de votre fichier de dépôt de service.
    Conseil

    Le répertoire "drop-in" pour les fichiers de dépôt d'un service est à /etc/systemd/system/service_name.service.dservice_name est le nom du service.

    Dans notre exemple avec le service myservice1, nous exécuterions la commande suivante :

    sudo mkdir -p /etc/systemd/system/myservice1.service.d/
  2. Créez 2 fichiers de dépôt appelés 00-slice.conf et 10-CPUSettings.conf dans le répertoire myservice1.service.d créé à l'étape précédente.
    Note

    • Plusieurs fichiers de dépôt portant des noms différents sont appliqués dans l'ordre lexicographique.

    • Ces fichiers de dépôt ont priorité sur le fichier d'unité de service.

  3. Ajoutez le contenu suivant à 00-slice.conf
    [Service]
    Slice=my_custom_slice2.slice
    MemoryAccounting=yes
    CPUAccounting=yes
    

    Le paramètre de tranche Slice=my_custom_slice2.slice dans le fichier de dépôt a priorité sur l'entrée Slice=my_custom_slice.slice ajoutée au fichier d'unité de service à une étape précédente.

  4. Et ajoutez le contenu suivant à 10-CPUSettings.conf
    [Service]
    CPUWeight=200
    
  5. Créez un second service (myservice2) et affectez-lui un CPUWeight différent de celui affecté à myservice1 :
    1. Créez le fichier /etc/systemd/system/myservice2.service avec le contenu suivant :
      [Service]
      Slice=my_custom_slice2.slice
      Type=oneshot
      ExecStart=/usr/lib/systemd/generate_load2.sh
      TimeoutSec=0
      StandardOutput=tty
      RemainAfterExit=yes
      
      [Install]
      WantedBy=multi-user.target
    2. Le service créé à l'étape précédente nécessite un script bash /usr/lib/systemd/generate_load2.sh. Créez le fichier avec le contenu suivant :
      #!/bin/bash
      for i in {1..4};do while : ; do : ; done & done
    3. Rendre le script exécutable :
      sudo chmod +x /usr/lib/systemd/generate_load2.sh
    4. Créez un dépôt dans le fichier /etc/systemd/system/myservice2.service.d/10-CPUSettings.conf pour myservice2 avec le contenu suivant :
      [Service]
      CPUWeight=400
      
  6. Assurez-vous que systemd recharge ses fichiers de configuration, puis redémarrez myservice1, et activez et démarrez myservices2 :
    sudo systemctl daemon-reload
    sudo systemctl restart myservice1
    sudo systemctl enable myservice2 --now
  7. Exécutez la commande systemd-cgtop pour afficher les groupes de contrôle triés selon leur utilisation des ressources. Vous pouvez voir dans l'exemple de sortie suivant comment, en plus de l'utilisation des ressources de chaque tranche, la commande systemd-cgtop affiche l'utilisation des ressources dans chaque tranche. Vous pouvez donc l'utiliser pour vérifier que la pondération de l'UC a été divisée comme prévu.
    systemd-cgtop
    Control Group                                     Tasks   %CPU   Memory  Input/s Output/s
    /                                                   228  198.8   712.5M        -        -
    my_custom_slice2.slice                                8  198.5     1.8M        -        -
    my_custom_slice2.slice/myservice2.service             4  132.8   944.0K        -        -
    my_custom_slice2.slice/myservice1.service             4   65.6   976.0K        -        -
    user.slice                                           18    0.9    43.9M        -        -
    user.slice/user-1001.slice                            6    0.9    13.7M        -        -
    user.slice/user-1001.slice/session-2.scope            4    0.9     9.4M        -        -
    system.slice                                         60    0.0   690.8M        -        -
    

Utilisation de systemctl set-property

La commande systemctl set-property place les fichiers de configuration à l'emplacement suivant :

/etc/systemd/system.control
Attention

Vous ne devez pas modifier manuellement les fichiers que la commande set-property systemctl crée.

Note

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 :

  1. Dans notre exemple, créez un autre fichier de service à l'emplacement /etc/systemd/system/myservice3.service avec le contenu suivant :
    [Service]
    Type=oneshot
    ExecStart=/usr/lib/systemd/generate_load3.sh
    TimeoutSec=0
    StandardOutput=tty
    RemainAfterExit=yes
    [Install]
    WantedBy=multi-user.target
  2. Réglez la tranche du service à my_custom_slice2 (la même tranche utilisée par les services créés à partir des étapes précédentes) en ajoutant la ligne suivante à la section [Service] dans le fichier myservice3.service :
    Slice=my_custom_slice2.slice
    Note

    La tranche doit être définie dans le fichier service-unit, car la commande systemctl set-property ne reconnaît pas la propriété Slice.

  3. Le service créé à l'étape précédente nécessite un script bash /usr/lib/systemd/generate_load3.sh. Créez le fichier avec le contenu suivant :
    #!/bin/bash
    for i in {1..4};do while : ; do : ; done & done
  4. Rendre le script exécutable :
    sudo chmod +x /usr/lib/systemd/generate_load3.sh
  5. Assurez-vous que systemd recharge ses fichiers de configuration, puis activez et démarrez le service :
    sudo systemctl daemon-reload
    sudo systemctl enable myservice3 --now
  6. Exécutez systemd-cgtop pour vérifier que les 3 services, myservice1, myservice2 et myservice3, sont tous exécutés dans la même tranche.
  7. Utilisez la commande systemctl set-property pour régler CPUWeight pour myservice3 à 800 :
    sudo systemctl set-property myservice3.service CPUWeight=800
  8. Confirmez qu'un fichier de dépôt a été créé pour vous sous /etc/systemd/system.control/myservice3.service.d. Toutefois, vous ne devez pas modifier le fichier :
    cat /etc/systemd/system.control/myservice3.service.d/50-CPUWeight.conf
    # This is a drop-in unit file extension, created via "systemctl set-property"
    # or an equivalent operation. Do not edit.
    [Service]
    CPUWeight=800
    
  9. Assurez-vous que systemd recharge ses fichiers de configuration et redémarrez tous les services :
    sudo systemctl daemon-reload
    sudo systemctl restart myservice1
    sudo systemctl restart myservice2
    sudo systemctl restart myservice3
  10. Exécutez la commande systemd-cgtop pour vérifier que la pondération de l'UC a été divisée comme prévu :
    systemd-cgtop
    Control Group                                         Tasks   %CPU   Memory  Input/s Output/s
    /                                                       235  200.0   706.1M        -        -
    my_custom_slice2.slice                                   12  198.4     2.9M        -        -
    my_custom_slice2.slice/myservice3.service                 4  112.7   976.0K        -        -
    my_custom_slice2.slice/myservice2.service                 4   56.9   996.0K        -        -
    my_custom_slice2.slice/myservice1.service                 4   28.8   988.0K        -        -
    user.slice                                               18    0.9    44.1M        -        -
    user.slice/user-1001.slice                                6    0.9    13.9M        -        -
    user.slice/user-1001.slice/session-2.scope                4    0.9     9.5M        -        -