Uso de Systemd para Gestionar Grupos de Control

Introduce conceptos de cgroups en Oracle Linux y muestra cómo systemd organiza y gestiona el control de recursos.

Los grupos de control, denominados cgroups, son una función del núcleo de Oracle Linux que organiza los servicios systemd y, si es necesario, los procesos individuales (PIDs), en grupos jerárquicos para asignar recursos del sistema, como CPU, memoria y E/S.

Por ejemplo, si necesita dividir el recurso de CPU entre tres servicios systemd, myservice1.service, myservice2.service y myservice3.service, en un ratio de 150:100:50, puede utilizar las herramientas systemd para asignar a cada servicio cgroup correspondiente un peso de CPU que coincida con su recurso compartido de destino.

Nota

systemd es responsable de crear y gestionar su cgroups en el sistema de archivos virtual /sys/fs/cgroup/.

El conjunto systemd proporciona formas seguras y de alto nivel para configurar recursos cgroup, como el uso de archivos desplegables o el comando systemctl set-property. La modificación directa de los objetos systemd en el sistema de archivos virtual /sys/fs/cgroup/ no se recomienda.

Por defecto, systemd crea un cgroup para lo siguiente:

  • Cada servicio systemd configurado en el host.

    Por ejemplo, un servidor puede tener el grupo de control NetworkManager.service para agrupar procesos que son propiedad del servicio NetworkManager y el grupo de control firewalld.service para agrupar procesos que son propiedad del servicio firewalld, etc.

  • Cada usuario (UID) en el host.

La funcionalidad cgroup se monta como un sistema de archivos virtual en /sys/fs/cgroup.

Cada cgroup tiene una carpeta correspondiente en el sistema de archivos /sys/fs/cgroup. Por ejemplo, el cgroups creado por systemd para los servicios que gestiona se puede ver ejecutando el comando ls -l /sys/fs/cgroup/system.slice | grep ".service" como se muestra en el siguiente bloque de código de ejemplo:

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
...

También puede crear cgroups personalizado fuera de las bifurcaciones systemd, por ejemplo, en una ubicación como /sys/fs/cgroup/MyGroups/, y asignar identificadores de proceso (PIDs) a diferentes cgroups según las necesidades del sistema. Sin embargo, este enfoque solo se debe utilizar para escenarios específicos, como la depuración o la prueba temporales. Para la mayoría de los casos de uso, se recomienda utilizar systemd para configurar cgroups para garantizar una gestión de recursos correcta y persistente.

Oracle Linux proporciona dos tipos de grupos de control:

Grupos de control versión 1 (cgroups v1)

Estos grupos proporcionan una jerarquía de controlador por recurso.

Cada recurso, como CPU, memoria, E/S, etc., tiene su propia jerarquía de grupo de control. Una desventaja de este grupo es la dificultad de establecer una coordinación adecuada del uso de los recursos entre los grupos que podrían pertenecer a diferentes jerarquías de procesos.

Grupos de control versión 2 (cgroups v2)

Estos grupos proporcionan una única jerarquía de grupos de control en la que se montan todos los controladores de recursos. En esta jerarquía, puede obtener una mejor coordinación adecuada de los usos de los recursos en los distintos controladores de recursos. Esta versión supone una mejora con respecto a cgroups v1, cuya flexibilidad impidió una coordinación adecuada del uso de los recursos entre los consumidores del sistema.

Oracle Linux 8 incluye ambas versiones, con cgroups v1 activado y montado por defecto. Oracle Linux 9 también proporciona ambas versiones, pero activa y monta cgroups v2 por defecto.

Oracle Linux 10 solo ofrece la implementación de la versión 2 de los grupos de control. cgroups v1 está en desuso y no está disponible. cgroups v2 está activado y montado por defecto.

Para obtener más información sobre los grupos de control, consulte las páginas del manual cgroups(7) y sysfs(5).

Acerca de los grupos de control y systemd

El sistema y el gestor de servicios systemd pueden utilizar los grupos de control para la gestión de recursos. systemd utiliza estos grupos para organizar las unidades y los servicios que consumen recursos. Para obtener más información sobre systemd, consulte Managing the System With systemd.

systemd proporciona diferentes tipos de unidades, tres de los cuales son para fines de control de recursos:

  • Servicio: proceso o grupo de procesos cuyos valores se basan en un archivo de configuración de unidad. Los servicios abarcan procesos especificados en una "recopilación" para que systemd pueda iniciar o parar los procesos como un conjunto. Los nombres de servicio siguen el formato name.service.

  • Ámbito: grupo de procesos creados externamente, como sesiones de usuario, contenedores, máquinas virtuales, etc.

    De forma similar a los servicios, los ámbitos encapsulan estos procesos creados y los inician o paran los procesos arbitrarios y, a continuación, los registra systemd en tiempo de ejecución. Los nombres de ámbito siguen el formato name.scope.

  • Segmento: grupo de unidades organizadas jerárquicamente en el que se encuentran los servicios y los ámbitos.

    Por lo tanto, los segmentos en sí no contienen procesos. En su lugar, los ámbitos y servicios de un segmento definen los procesos. Cada nombre de una unidad de segmento corresponde a la ruta a una ubicación de la jerarquía. Los segmentos raíz, normalmente user.slice para todos los procesos basados en el usuario y system.slice para los procesos basados en el sistema, se crean automáticamente en la jerarquía. Los segmentos principales existen inmediatamente por debajo del segmento raíz y siguen el formato parent-name.slice. Estas porciones raíz pueden tener subsecciones en varios niveles.

El servicio, el ámbito y las unidades de división se asignan directamente a los objetos de la jerarquía del grupo de control. Cuando se activan estas unidades, se asignan directamente a las rutas de grupo de control que se crean a partir de los nombres de unidad. Para mostrar la asignación entre los tipos de unidades de recursos systemd y los grupos de control, escriba:

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
...

Para ver un ejemplo de cómo utilizar comandos systemd, como systemctl, para gestionar recursos, consulte Controlling Access to System Resources. Para más detalles técnicos, véase las páginas del manual systemctl(1), systemd-cgls(1) y systemd.resource-control(5).

Uso de systemd para gestionar cgroups v2

Muestra cómo systemd estructura cgroups v2 para servicios y usuarios y cómo inspeccionar la jerarquía.

El método preferido para gestionar la asignación de recursos con cgroups v2 es utilizar la funcionalidad de grupo de control proporcionada por systemd.

Nota

Para obtener información sobre la activación de la funcionalidad cgroups v2 en el sistema, consulte Gestión de recursos mediante grupos de control.

Por defecto, systemd crea una carpeta cgroup para cada servicio systemd configurado en el host. systemd asigna un nombre a estas carpetas con el formato servicename.service, donde servicename es el nombre del servicio asociado a la carpeta.

Para ver una lista de las carpetas cgroup que crea systemd para los servicios, ejecute el comando ls en la rama system.slice del sistema de archivos cgroup como se muestra en el siguiente bloque de código de ejemplo:

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              ...
...                     ...                           ...

En el bloque de comandos anterior:

  • Las carpetas app_service1.service y app_service2.service representan servicios de aplicación personalizados que se pueden ejecutar en el sistema.

Además de los grupos de control de servicio, systemd también crea una carpeta cgroup para cada usuario del host.

Para ver el cgroups creado para cada usuario, puede ejecutar el comando ls en la rama user.slice del sistema de archivos cgroup, como se muestra en el siguiente bloque de código de ejemplo:

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                   ...
...                     ...                           ...
...                     ...                           ...
...                     ...                           ...

En el bloque de código anterior:

  • Cada carpeta cgroup de usuario se denomina con el formato user-UID.slice. Por lo tanto, el grupo de control user-1001.slice es para un usuario cuyo UID es 1001, por ejemplo.

systemd proporciona acceso de alto nivel a las funciones de controlador de recursos de núcleo y cgroups para que no tenga que acceder al sistema de archivos directamente.

Por ejemplo, para definir el peso de CPU de un servicio denominado app_service1.service, ejecute el comando systemctl set-property de la siguiente manera:

sudo systemctl set-property app_service1.service CPUWeight=150

Por lo tanto, systemd permite gestionar la distribución de recursos en el nivel de aplicación, en lugar del nivel de PID de proceso utilizado al configurar cgroups sin utilizar la funcionalidad systemd.

Acerca de los segmentos y la asignación de recursos en systemd

En esta sección se analiza la forma en que systemd divide inicialmente cada uno de los controladores de núcleo por defecto, por ejemplo CPU, memory y blkio, en partes denominadas "porciones", como se ilustra en el siguiente gráfico circular de ejemplo:

Nota

También puede crear segmentos personalizados para la distribución de recursos, como se muestra en la sección Definición de opciones de controlador de recursos y creación de segmentos personalizados.

Gráfico circular con 3 segmentos de igual tamaño, etiquetados Sistema, Máquina y Usuario. El usuario y el sistema se dividen en subdivisiones.

Como muestra el gráfico circular anterior, de manera predeterminada, cada controlador de recursos se divide por igual entre los siguientes 3 segmentos:

  • Sistema (system.slice).

  • Usuario (user.slice).

  • Máquina (machine.slice).

La siguiente lista examina cada segmento más de cerca. Para fines de debate, los ejemplos de la lista se centran en el controlador de CPU.

Sistema (system.slice)

Este segmento de recursos se utiliza para gestionar la asignación de recursos entre daemons y unidades de servicio.

Como se muestra en el gráfico circular de ejemplo anterior, la porción del sistema se divide en subsecciones adicionales. Por ejemplo, en el caso de los recursos de CPU, es posible que tengamos asignaciones de subsegmentos dentro del segmento del sistema que incluyan lo siguiente:
  • httpd.service (CPUWeight=100)

  • sshd.service (CPUWeight =100)

  • crond.service (CPUWeight =100)

  • app1.service (CPUWeight =100)

  • app2.service (CPUWeight =100)

En la lista anterior, app1.service y app2.service representan servicios de aplicación personalizados que se pueden ejecutar en el sistema.
Usuario (user.slice)
Este segmento de recursos se utiliza para gestionar la asignación de recursos entre sesiones de usuario. Se crea un único segmento para cada UID independientemente del número de conexiones que el usuario asociado tenga activas en el servidor. Continuando con nuestro ejemplo de gráfico circular, las subdivisiones pueden ser las siguientes:
  • user1 (CPUWeight=100, UID=982)

  • user2 (CPUWeight=100, UID=1001)

Máquina (machine.slice)
Este segmento del recurso se utiliza para gestionar la asignación de recursos entre máquinas virtuales alojadas, como invitados de KVM y contenedores de Linux. El segmento de máquina solo está presente en un servidor si el servidor aloja máquinas virtuales o contenedores de Linux.
Nota

Las asignaciones de recursos compartidos no establecen un límite máximo para un recurso.

En los ejemplos anteriores, el segmento user.slice tiene 2 usuarios: user1 y user2. A cada usuario se le asigna una cuota igual del recurso de CPU disponible para el principal user.slice. Sin embargo, si los procesos asociados con user1 están inactivos y no requieren ningún recurso de CPU, el recurso compartido de CPU estará disponible para la asignación a user2 si es necesario. En tal situación, user2 incluso se puede asignar todo el recurso de CPU asignado al principal user.slice si lo necesitan otros usuarios.

Para limitar el recurso de CPU, debe definir la propiedad CPUQuota en el porcentaje necesario.

Porciones, Servicios y Ámbitos en la Jerarquía de cgroup

La analogía del gráfico circular utilizada en las secciones anteriores es una forma útil de conceptualizar la división de recursos en segmentos. Sin embargo, en términos de organización estructural, los grupos de control se organizan en una jerarquía. Puede ver la jerarquía del grupo de control systemd en el sistema ejecutando el comando systemd-cgls de la siguiente manera:

Consejo

Para ver toda la jerarquía cgroup, a partir del segmento raíz -.slice, como en el siguiente ejemplo, asegúrese de ejecutar systemd-cgls desde fuera del punto de montaje del grupo de control /sys/fs/cgroup/.

De lo contrario, si ejecuta el comando desde /sys/fs/cgroup/, la salida se inicia desde la ubicación cgroup desde la que se ha ejecutado el comando. Consulte systemd-cgls(1) para obtener más información.

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
  ...

La salida de ejemplo anterior muestra cómo residen todos los grupos de control "*.slice" en el segmento raíz -.slice. Debajo del segmento raíz, puede ver los grupos de control user.slice y system.slice, cada uno con sus propios segmentos secundarios cgroup.

Al examinar la salida del comando systemd-cgls , puede ver cómo, excepto para la raíz -.slice, todos los procesos están en nodos de hoja. Esta disposición se aplica mediante cgroups v2, en una regla denominada regla "sin procesos internos". Consulte cgroups (7) para obtener más información sobre la regla "sin procesos internos".

La salida del ejemplo de comando systemd-cgls anterior también muestra cómo los segmentos pueden tener grupos de control secundarios descendientes que son ámbitos systemd. Los ámbitos systemd se revisan en la siguiente sección.

ámbitos systemd

El ámbito systemd es un tipo de unidad systemd que agrupa los procesos de trabajo de servicio del sistema que se han iniciado independientemente de systemd. Las unidades de ámbito son transitorias cgroups creadas mediante programación mediante las interfaces de bus de systemd.

Por ejemplo, en el siguiente código de ejemplo, el usuario con UID 1001 ha ejecutado el comando systemd-cgls y la salida muestra que se ha creado session-2.scope para los procesos que el usuario ha generado independientemente de systemd (incluido el proceso para el propio comando, 21380 sudo systemd-cgls):

Nota

En el siguiente ejemplo, el comando se ha ejecutado desde el punto de montaje del grupo de control /sys/fs/cgroup/. Por lo tanto, en lugar del segmento raíz, la salida comienza desde la ubicación cgroup desde la que se ha ejecutado el comando.
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)

Configuración de opciones de controlador de recursos y creación de segmentos personalizados

Demuestra tres enfoques (archivos unitarios, drop-ins y systemctl set-property) para ajustar los controladores de recursos y los diseños de segmentos.

systemd proporciona los siguientes métodos para configurar opciones de controlador de recursos, como CPUWeight, CPUQuota, etc., para personalizar la asignación de recursos en el sistema:

  • Utilización de archivos de unidades de servicio.

  • Uso de archivos desplegables.

  • Mediante el comando systemctl set-property.

En las siguientes secciones, se proporcionan procedimientos de ejemplo para usar cada uno de estos métodos para configurar recursos y segmentos en el sistema.

Uso de archivos de unidades de servicio

Para establecer opciones en un archivo de unidad de servicio, realice los siguientes pasos:

  1. Cree el archivo /etc/systemd/system/myservice1.service con el siguiente contenido:
    [Service]
    Type=oneshot
    ExecStart=/usr/lib/systemd/generate_load.sh
    TimeoutSec=0
    StandardOutput=tty
    RemainAfterExit=yes
    
    [Install]
    WantedBy=multi-user.target
  2. El servicio creado en el paso anterior requiere un script bash /usr/lib/systemd/generate_load.sh. Cree el archivo con el siguiente contenido:
    #!/bin/bash
    for i in {1..4};do while : ; do : ; done & done
  3. Haga que el script se pueda ejecutar:
    sudo chmod +x /usr/lib/systemd/generate_load.sh
  4. Active e inicie el servicio:
    sudo systemctl enable myservice1 --now
  5. Ejecute el comando systemd-cgls y confirme que el servicio myservice1 se está ejecutando en 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. Cree un segmento personalizado para el servicio.

    Agregue la línea Slice=my_custom_slice.slice a la sección [Service] del archivo myservice1.service, creada en un paso anterior, como se muestra en el siguiente bloque de código:

    [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
    
    Atención

    Utilice guiones bajos en lugar de guiones para separar los términos en los nombres de los segmentos.

    En systemd, un guión en un nombre de segmento es un carácter especial: en systemd, los guiones en los nombres de segmento se utilizan para describir la ruta cgroup completa al segmento (a partir del segmento raíz).

    Por ejemplo, si especifica un nombre de segmento como "my-custom-slice.slice", en lugar de crear un segmento con ese nombre, systemd crea la siguiente ruta cgroups debajo del segmento raíz: my.slice/my-custom.slice/my-custom-slice.slice.

  7. Después de editar el archivo, asegúrese de que systemd vuelva a cargar sus archivos de configuración y, a continuación, reinicie el servicio:
    sudo systemctl daemon-reload
    sudo systemctl restart myservice1
  8. Ejecute el comando systemd-cgls y confirme que el servicio myservice1 se está ejecutando ahora en el segmento personalizado 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
     ...
    

Uso de archivos desplegables

Para utilizar un archivo desplegable para configurar recursos, realice los siguientes pasos:

  1. Cree el directorio para el archivo desplegable de servicio.
    Consejo

    El directorio "drop-in" para los archivos drop-in de un servicio está en /etc/systemd/system/service_name.service.d, donde service_name es el nombre del servicio.

    Continuando con nuestro ejemplo con el servicio myservice1, ejecutaríamos el siguiente comando:

    sudo mkdir -p /etc/systemd/system/myservice1.service.d/
  2. Cree 2 archivos desplegables denominados 00-slice.conf y 10-CPUSettings.conf en el directorio myservice1.service.d creado en el paso anterior.
    Nota

    • Se aplican varios archivos desplegables con nombres diferentes en orden lexicográfico.

    • Estos archivos desplegables tienen prioridad sobre el archivo de unidad de servicio.

  3. Agregue el siguiente contenido a 00-slice.conf
    [Service]
    Slice=my_custom_slice2.slice
    MemoryAccounting=yes
    CPUAccounting=yes
    

    El valor de segmento Slice=my_custom_slice2.slice en el archivo desplegable tiene prioridad sobre la entrada Slice=my_custom_slice.slice agregada al archivo de unidad de servicio en un paso anterior.

  4. Y agregue el siguiente contenido a 10-CPUSettings.conf
    [Service]
    CPUWeight=200
    
  5. Cree un segundo servicio (myservice2) y asígnele un CPUWeight diferente al asignado a myservice1:
    1. Cree el archivo /etc/systemd/system/myservice2.service con el siguiente contenido:
      [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. El servicio creado en el paso anterior requiere un script bash /usr/lib/systemd/generate_load2.sh. Cree el archivo con el siguiente contenido:
      #!/bin/bash
      for i in {1..4};do while : ; do : ; done & done
    3. Haga que el script se pueda ejecutar:
      sudo chmod +x /usr/lib/systemd/generate_load2.sh
    4. Cree un drop en file /etc/systemd/system/myservice2.service.d/10-CPUSettings.conf para myservice2 con el siguiente contenido:
      [Service]
      CPUWeight=400
      
  6. Asegúrese de que systemd vuelva a cargar sus archivos de configuración y reinicie myservice1, y también active e inicie myservices2:
    sudo systemctl daemon-reload
    sudo systemctl restart myservice1
    sudo systemctl enable myservice2 --now
  7. Ejecute el comando systemd-cgtop para mostrar los grupos de control ordenados por su uso de recursos. En la siguiente salida de ejemplo se puede ver cómo, además del uso de recursos de cada segmento, el comando systemd-cgtop muestra el uso de recursos dentro de cada segmento, de modo que puede utilizarlo para confirmar que el peso de la CPU se ha dividido según lo esperado.
    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        -        -
    

Uso de systemctl set-property

El comando systemctl set-property coloca los archivos de configuración en la siguiente ubicación:

/etc/systemd/system.control
Atención

No debe editar manualmente los archivos que crea el comando systemctl set-property.

Nota

El comando systemctl set-property no reconoce todas las propiedades de control de recursos utilizadas en los archivos de la unidad del sistema y de colocación que se trataron anteriormente en este tema.

El siguiente procedimiento muestra cómo puede utilizar el comando systemctl set-property para configurar la asignación de recursos:

  1. Continuando con nuestro ejemplo, cree otro archivo de servicio en la ubicación /etc/systemd/system/myservice3.service con el siguiente contenido:
    [Service]
    Type=oneshot
    ExecStart=/usr/lib/systemd/generate_load3.sh
    TimeoutSec=0
    StandardOutput=tty
    RemainAfterExit=yes
    [Install]
    WantedBy=multi-user.target
  2. Defina el segmento para que el servicio sea my_custom_slice2 (el mismo segmento utilizado por los servicios creados en pasos anteriores) agregando la siguiente línea a la sección [Service] en el archivo myservice3.service:
    Slice=my_custom_slice2.slice
    Nota

    El segmento se debe definir en el archivo service-unit porque el comando systemctl set-property no reconoce la propiedad Slice.

  3. El servicio creado en el paso anterior requiere un script bash /usr/lib/systemd/generate_load3.sh. Cree el archivo con el siguiente contenido:
    #!/bin/bash
    for i in {1..4};do while : ; do : ; done & done
  4. Haga que el script se pueda ejecutar:
    sudo chmod +x /usr/lib/systemd/generate_load3.sh
  5. Asegúrese de que systemd vuelva a cargar sus archivos de configuración y, a continuación, active e inicie el servicio:
    sudo systemctl daemon-reload
    sudo systemctl enable myservice3 --now
  6. Ejecute systemd-cgtop para confirmar que todos los 3 servicios, myservice1, myservice2 y myservice3, se están ejecutando en el mismo segmento.
  7. Utilice el comando systemctl set-property para definir CPUWeight para myservice3 en 800:
    sudo systemctl set-property myservice3.service CPUWeight=800
  8. Confirme que se ha creado un archivo desplegable en /etc/systemd/system.control/myservice3.service.d. Sin embargo, no debe editar el archivo:
    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. Asegúrese de que systemd vuelva a cargar los archivos de configuración y reinicie todos los servicios:
    sudo systemctl daemon-reload
    sudo systemctl restart myservice1
    sudo systemctl restart myservice2
    sudo systemctl restart myservice3
  10. Ejecute el comando systemd-cgtop para confirmar que el peso de la CPU se ha dividido como se esperaba:
    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        -        -