Red Hat Training

A Red Hat training course is available for RHEL 8

44.3.2. Establecimiento de límites de CPU a las aplicaciones mediante cgroups-v2

A veces una aplicación utiliza mucho tiempo de CPU, lo que puede afectar negativamente a la salud general de su entorno. Utilice control groups version 2 (cgroups-v2) para configurar los límites de la CPU a la aplicación, y restringir su consumo.

Requisitos previos

Procedimiento

  1. Evitar que cgroups-v1 se monte automáticamente durante el arranque del sistema:

    # grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="cgroup_no_v1=all"

    El comando añade un parámetro de línea de comandos del kernel a la entrada de arranque actual. El parámetro cgroup_no_v1=all evita que cgroups-v1 se monte automáticamente.

    Como alternativa, utilice el parámetro de línea de comandos del kernel systemd.unified_cgroup_hierarchy=1 para montar cgroups-v2 durante el arranque del sistema por defecto.

    Nota

    RHEL 8 soporta tanto cgroups-v1 como cgroups-v2. Sin embargo, cgroups-v1 está activado y montado por defecto durante el proceso de arranque.

  2. Reinicie el sistema para que los cambios surtan efecto.
  3. Opcionalmente, verifique que la funcionalidad de cgroups-v1 ha sido desactivada:

    # mount -l | grep cgroup
    tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,seclabel,mode=755)
    cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)

    Si cgroups-v1 se ha desactivado con éxito, la salida no muestra ninguna referencia "tipo cgroup", excepto las que pertenecen a systemd.

  4. Monte cgroups-v2 en cualquier lugar del sistema de archivos:

    # mount -t cgroup2 none <MOUNT_POINT>
  5. Opcionalmente, verifique que la funcionalidad de cgroups-v2 ha sido montada:

    # mount -l | grep cgroup2
    none on /cgroups-v2 type cgroup2 (rw,relatime,seclabel)

    La salida del ejemplo muestra que cgroups-v2 se ha montado en el directorio /cgroups-v2/.

  6. Opcionalmente, inspeccione el contenido del directorio /cgroups-v2/:

    # ll /cgroups-v2/
    -r—​r—​r--. 1 root root 0 Mar 13 11:57 cgroup.controllers
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 cgroup.max.depth
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 cgroup.max.descendants
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 cgroup.procs
    -r—​r—​r--. 1 root root 0 Mar 13 11:57 cgroup.stat
    -rw-r—​r--. 1 root root 0 Mar 13 11:58 cgroup.subtree_control
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 cgroup.threads
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 cpu.pressure
    -r—​r—​r--. 1 root root 0 Mar 13 11:57 cpuset.cpus.effective
    -r—​r—​r--. 1 root root 0 Mar 13 11:57 cpuset.mems.effective
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 io.pressure
    -rw-r—​r--. 1 root root 0 Mar 13 11:57 memory.pressure

    El directorio /cgroups-v2/, también llamado grupo de control raíz, contiene algunos archivos de interfaz (empezando por cgroup) y algunos archivos específicos del controlador como cpuset.cpus.effective.

  7. Identifique los ID de proceso (PID) de las aplicaciones que desea restringir en el consumo de la CPU:

    # top
    top - 15:39:52 up  3:45,  1 user,  load average: 0.79, 0.20, 0.07
    Tasks: 265 total,   3 running, 262 sleeping,   0 stopped,   0 zombie
    %Cpu(s): 74.3 us,  6.1 sy,  0.0 ni, 19.4 id,  0.0 wa,  0.2 hi,  0.0 si,  0.0 st
    MiB Mem :   1826.8 total,    243.8 free,   1102.1 used,    480.9 buff/cache
    MiB Swap:   1536.0 total,   1526.2 free,      9.8 used.    565.6 avail Mem
    
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     5473 root      20   0  228440   1740   1456 R  99.7   0.1   0:12.11 sha1sum
     5439 root      20   0  222616   3420   3052 R  60.5   0.2   0:27.08 cpu_load_generator
     2170 jdoe      20   0 3600716 209960  67548 S   0.3  11.2   1:18.50 gnome-shell
     3051 root      20   0  274424   3976   3092 R   0.3   0.2   1:01.25 top
        1 root      20   0  245448  10256   5448 S   0.0   0.5   0:02.52 systemd
    ...

    La salida de ejemplo del programa top revela que PID 5473 y 5439 (aplicación ilustrativa sha1sum y cpu_load_generator) consumen muchos recursos, concretamente la CPU. Ambas son aplicaciones de ejemplo utilizadas para demostrar la gestión de la funcionalidad de cgroups-v2.

  8. Habilitar los controladores relacionados con la CPU:

    # echo "+cpu" > /cgroups-v2/cgroup.subtree_control
    # echo "+cpuset" > /cgroups-v2/cgroup.subtree_control

    Los comandos anteriores habilitan los controladores cpu y cpuset para los grupos de subcontrol inmediatos del grupo de control raíz /cgroups-v2/.

  9. Cree un subdirectorio en el directorio /cgroups-v2/ creado anteriormente:

    # mkdir /cgroups-v2/Example/

    El directorio /cgroups-v2/Example/ representa un subgrupo de control, donde se pueden colocar procesos específicos y aplicar varios límites de CPU a los procesos. Además, el paso anterior habilitó los controladores cpu y cpuset para este grupo de subcontrol.

    En el momento de la creación de /cgroups-v2/Example/, se crearán en el directorio algunos archivos de la interfaz cgroups-v2 y archivos específicos del controlador cpu y cpuset.

  10. Opcionalmente, inspeccione el grupo de control recién creado:

    # ll /cgroups-v2/Example/
    -r—​r—​r--. 1 root root 0 Mar 13 14:48 cgroup.controllers
    -r—​r—​r--. 1 root root 0 Mar 13 14:48 cgroup.events
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.freeze
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.max.depth
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.max.descendants
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.procs
    -r—​r—​r--. 1 root root 0 Mar 13 14:48 cgroup.stat
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.subtree_control
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.threads
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cgroup.type
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpu.max
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpu.pressure
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpuset.cpus
    -r—​r—​r--. 1 root root 0 Mar 13 14:48 cpuset.cpus.effective
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpuset.cpus.partition
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpuset.mems
    -r—​r—​r--. 1 root root 0 Mar 13 14:48 cpuset.mems.effective
    -r—​r—​r--. 1 root root 0 Mar 13 14:48 cpu.stat
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpu.weight
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 cpu.weight.nice
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 io.pressure
    -rw-r—​r--. 1 root root 0 Mar 13 14:48 memory.pressure

    La salida del ejemplo muestra archivos como cpuset.cpus y cpu.max. Los archivos son específicos de los controladores cpuset y cpu que usted habilitó para los grupos de control hijos directos de la raíz (/cgroups-v2/) utilizando el archivo /cgroups-v2/cgroup.subtree_control. Además, hay archivos generales de interfaz de control cgroup como cgroup.procs o cgroup.controllers, que son comunes a todos los grupos de control, independientemente de los controladores habilitados.

    Por defecto, el grupo de subcontrol recién creado hereda el acceso a todos los recursos de la CPU del sistema sin límite.

  11. Asegúrese de que los procesos que desea limitar compiten por el tiempo de CPU en la misma CPU:

    # echo "1" > /cgroups-v2/Example/cpuset.cpus

    El comando anterior asegura los procesos que usted colocó en el grupo de subcontrol Example, compiten en la misma CPU. Esta configuración es importante para que el controlador cpu se active.

    Importante

    El controlador cpu sólo se activa si el grupo de subcontrol correspondiente tiene al menos 2 procesos, que compiten por el tiempo en una sola CPU.

  12. Configurar los límites de la CPU del grupo de control:

    # echo "200000 1000000" > /cgroups-v2/Example/cpu.max

    El primer valor es la cuota de tiempo permitida en microsegundos para que todos los procesos colectivamente en un subgrupo de control puedan ejecutarse durante un período (especificado por el segundo valor). Durante un solo periodo, cuando los procesos de un grupo de control agotan colectivamente todo el tiempo especificado por esta cuota, se estrangulan durante el resto del periodo y no se les permite ejecutarse hasta el siguiente periodo.

    El comando de ejemplo establece los límites de tiempo de la CPU para que todos los procesos colectivamente en el grupo de subcontrol Example puedan funcionar en la CPU sólo durante 0,2 segundos de cada 1 segundo.

  13. Opcionalmente, verifique los límites:

    # cat /cgroups-v2/Example/cpu.max
    200000 1000000
  14. Añada los PID de las aplicaciones al grupo de subcontrol Example:

    # echo "5473" > /cgroups-v2/Example/cgroup.procs
    # echo "5439" > /cgroups-v2/Example/cgroup.procs

    Los comandos de ejemplo garantizan que las aplicaciones deseadas se conviertan en miembros del grupo de subcontrol Example y, por tanto, no superen los límites de CPU configurados para el grupo de subcontrol Example.

  15. Compruebe que las aplicaciones se ejecutan en el grupo de control especificado:

    # cat /proc/5473/cgroup /proc/5439/cgroup
    1:name=systemd:/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service
    0::/Example
    1:name=systemd:/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service
    0::/Example

    El ejemplo anterior muestra que los procesos de las aplicaciones deseadas se ejecutan en el grupo de subcontrol Example.

  16. Inspeccione el consumo actual de la CPU de sus aplicaciones estranguladas:

    # top
    top - 15:56:27 up  4:02,  1 user,  load average: 0.03, 0.41, 0.55
    Tasks: 265 total,   4 running, 261 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  9.6 us,  0.8 sy,  0.0 ni, 89.4 id,  0.0 wa,  0.2 hi,  0.0 si,  0.0 st
    MiB Mem :   1826.8 total,    243.4 free,   1102.1 used,    481.3 buff/cache
    MiB Swap:   1536.0 total,   1526.2 free,      9.8 used.    565.5 avail Mem
    
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     5439 root      20   0  222616   3420   3052 R  10.0   0.2   6:15.83 cpu_load_generator
     5473 root      20   0  228440   1740   1456 R  10.0   0.1   9:20.65 sha1sum
     2753 jdoe      20   0  743928  35328  20608 S   0.7   1.9   0:20.36 gnome-terminal-
     2170 jdoe      20   0 3599688 208820  67552 S   0.3  11.2   1:33.06 gnome-shell
     5934 root      20   0  274428   5064   4176 R   0.3   0.3   0:00.04 top
     ...

    Obsérvese que el consumo de CPU de PID 5439 y PID 5473 ha disminuido al 10%. El subgrupo de control Example limita sus procesos al 20% del tiempo de CPU de forma colectiva. Como hay 2 procesos en el grupo de control, cada uno puede utilizar el 10% del tiempo de CPU.

Recursos adicionales