Qué son los cgroups y para qué sirven

Namespaces en Linux

En el post anterior vimos los namespaces, que sirven para aislar diferentes aspectos del sistema, como los procesos, la red y los puntos de montaje, creando entornos independientes para cada grupo de procesos. En este post, exploraremos los cgroups, que permiten controlar cuánto de los recursos del sistema, como CPU, memoria y disco, puede usar cada grupo de procesos. Ambas tecnologías se complementan: los namespaces proporcionan el aislamiento necesario, mientras que los cgroups gestionan y limitan los recursos que esos entornos aislados pueden consumir.

¿Qué son los cgroups?

Los cgroups (control groups) son una funcionalidad del kernel Linux que permite agrupar procesos y controlar de manera granular los recursos del sistema que consumen, como CPU, memoria, I/O, y otros. Se incorporaron en 2008 en el kernel de Linux 2.6.24, los cgroups permiten a los administradores de sistemas gestionar el uso de recursos por grupos de procesos de forma eficiente, garantizando una distribución justa y controlada.

Los cgroups crean una jerarquía de control donde es posible asignar límites a recursos específicos para un conjunto de procesos, de manera que el sistema operativo pueda monitorear, limitar, priorizar o aislar estos procesos según sea necesario. Esta capacidad es clave para garantizar que los sistemas multitarea, servidores, y contenedores funcionen de manera eficiente.

¿Para qué sirven los cgroups?

Los cgroups sirven para:

  • Limitar el uso de recursos

  • Priorizar procesos

  • Aislar procesos

  • Monitorear el consumo de recursos

  • Controlar procesos en contenedores (Docker, podman,etc.)

Un pantallazo de los cgroups

Dentro del propio directorio /proc podemos encontrar información sobre los cgroups:

 cat /proc/cgroups 
#subsys_name    hierarchy       num_cgroups     enabled
cpuset  0       241     1
cpu     0       241     1
cpuacct 0       241     1
blkio   0       241     1
memory  0       241     1
devices 0       241     1
freezer 0       241     1
net_cls 0       241     1
perf_event      0       241     1
net_prio        0       241     1
hugetlb 0       241     1
pids    0       241     1
rdma    0       241     1
misc    0       241     1

Este archivo muestra 4 columnas

Campo Significado
subsys_name Componente del kernel que controlar un recurso específico un aspecto del sistema.
hierarchy La columna hierarchy indica el ID de jerarquía asignado a cada subsistema. En este caso, todas las jerarquías tienen el valor 0, lo que indica que todos los subsistemas listados están utilizando una jerarquía unificada, común en sistemas que usan cgroups v2. En cgroups v2, todos los controladores utilizan una única jerarquía para gestionar los recursos de manera más eficiente, a diferencia de cgroups v1, donde cada subsistema podía tener su propia jerarquía.
num_cgroups Muestra el número de cgroups activos o instancias creadas bajo cada controlador. Estos cgroups pueden pertenecer a procesos que están ejecutándose actualmente en el sistema, como servicios, contenedores, o procesos individuales.
enabled Esta columna muestra si el subsistema está habilitado o no. El valor 1 indica que el controlador está habilitado y activo, mientras que un valor de 0 indicaría que está deshabilitado.

Evolución de los cgroups:

  1. cgroups v1: En la versión original, cada tipo de recurso (CPU, memoria, etc.) tenía su propia jerarquía de control, lo que permitía una gestión separada pero a veces compleja. Aunque era útil, la administración independiente de subsistemas podía resultar difícil de manejar en entornos complejos.

  2. cgroups v2 (2016): Para mejorar la gestión de recursos, se introdujo cgroups v2 en el kernel de Linux 4.x, que unificó los diferentes controladores bajo una jerarquía única. Esta versión simplificó el control de recursos y mejoró la eficiencia, permitiendo que todos los subsistemas trabajaran de manera más coordinada y con configuraciones más claras.

Cómo crear un cgroup y limitar el uso de CPU en cgroups v2

En este ejemplo, limitaremos el uso de CPU de un proceso utilizando cgroups v2 en un entorno moderno.

Paso 1: Crear un directorio para el cgroup

En cgroups v2, se gestiona todo bajo una jerarquía unificada. Primero, crea un nuevo directorio en /sys/fs/cgroup:

sudo mkdir /sys/fs/cgroup/mi_cgroup
Paso 2: Establecer un límite de CPU

En cgroups v2, puedes establecer límites en el uso de CPU mediante el archivo cpu.max. Este archivo recibe dos valores: el primero es el límite de uso de CPU en microsegundos por cada período de 100 milisegundos, y el segundo es la duración del período en microsegundos.

Para limitar el uso de CPU al 50%, puedes hacer lo siguiente:

echo "50000 100000" | sudo tee /sys/fs/cgroup/mi_cgroup/cpu.max

Este comando establece que los procesos en este cgroup pueden usar un máximo de 50.000 microsegundos de CPU en un período de 100.000 microsegundos (100 ms), lo que equivale al 50% de un núcleo de CPU.

Paso 3: Añadir un proceso al cgroup

Para añadir un proceso existente al cgroup, escribe su PID (ID del proceso) en el archivo cgroup.procs de ese cgroup. Supongamos que el PID del proceso es 78435:

echo 78435| sudo tee /sys/fs/cgroup/mi_cgroup/cgroup.procs

Esto moverá el proceso con PID 78435 al cgroup mi_cgroup, aplicando las restricciones de CPU configuradas.

Ejemplo de uso de cgroups para limitar el uso de CPU

En cgroups v1, los recursos se gestionan usando archivos como cpu.shares para establecer prioridades relativas de CPU, y tasks para asignar procesos a un cgroup. En cambio, en cgroups v2, el control de CPU se realiza a través de cpu.max, donde se puede establecer un límite absoluto en el uso de CPU (como un porcentaje). Además, en v1 cada subsistema tiene su propio directorio (como cpu/, memory/), mientras que en v2 todo se gestiona dentro de una única jerarquía unificada bajo /sys/fs/cgroup/.

Conclusión

Hoy en día, los cgroups son una herramienta crítica en la gestión moderna de servidores. RHEL8 usa de manera predeterminada la versión 1, pero es posible usar la versión 2, dependiendo del software que utilicemos. En definitiva, los cgroups son fundamentales para la operación de tecnologías como contenedores (Docker, Podman), orquestadores como Kubernetes, y cualquier sistema que necesite control granular de recursos. La capacidad de aislar, priorizar y monitorear el uso de recursos en servidores es clave para garantizar la estabilidad y el rendimiento en entornos de alta demanda.

Fuentes y más información

Comentarios

Comments powered by Disqus