Inicio
» Cómo
»
Limita el uso de CPU y memoria de un comando con cgroups de Ubuntu.
Limita el uso de CPU y memoria de un comando con cgroups de Ubuntu.
Si un comando ralentiza tu escritorio Ubuntu o provoca que un servidor se quede sin memoria, coloca el comando y sus procesos secundarios en un cgroup gestionado por systemd con una cuota de CPU y un límite de memoria. En las versiones actuales de Ubuntu, systemd-run --scopeesta es la ruta práctica más corta: inicia el comando en un ámbito temporal y systemd aplica los límites mediante controles de cgroup.
El ejemplo que se muestra a continuación limita la carga de trabajo a la mitad de la capacidad de una CPU y 1 GiB de memoria. Estos límites se aplican a todo el ámbito, incluidos los procesos secundarios; no garantizan que el programa se ejecute a una velocidad determinada.
Por qué un proceso necesita un límite de cgroup
Un proceso con mucha actividad puede competir con aplicaciones interactivas, mientras que un proceso que consume mucha memoria puede provocar que la máquina se quede sin memoria o se bloquee. Un cgroup agrupa un proceso con sus descendientes para que el kernel pueda gestionar y controlar dicho grupo. El sistema systemd de Ubuntu proporciona una interfaz práctica para estos controles.
La configuración de la CPU y la memoria se comporta de manera diferente. CPUQuota=50%Limita el tiempo de CPU a la mitad de la capacidad de una CPU, promediado durante un período de planificación. Un valor de 200%representa hasta el tiempo de dos CPU cuando estén disponibles. Este es un límite máximo, no una prioridad de CPU ni una reserva. MemoryMax=1GEstablece un límite máximo estricto para la memoria asignada al cgroup; si la carga de trabajo no puede mantenerse por debajo de él, el kernel puede reclamar memoria o invocar una terminación por falta de memoria para un proceso en ese cgroup. Elija un límite con margen para la aplicación y sus procesos hijos.
1. Compruebe que Ubuntu esté utilizando cgroup v2.
Los sistemas Ubuntu que utilizan systemd suelen usar la jerarquía unificada de cgroup v2. Confirme la configuración activa antes de confiar en las rutas que se muestran más adelante:
stat -fc %T /sys/fs/cgroup
systemctl --version | head -n 1
El primer comando debería informar cgroup2fs. Si informa otro tipo de sistema de archivos, las rutas de archivo de cgroup v2 de este artículo no se aplican tal como están escritas. Es posible que las propiedades de systemd aún sean compatibles con una jerarquía diferente, pero utilice la documentación de la distribución correspondiente en lugar de copiar las rutas v2.
Compruebe también la versión exacta de systemd si se rechaza una propiedad. La documentación de Noble de Ubuntu describe CPUQuota=y MemoryMax=como ajustes de control de recursos; las versiones anteriores de Ubuntu pueden incluir versiones diferentes de systemd.
2. Iniciar la carga de trabajo dentro de un alcance limitado.
Ejecute el programa a través de systemd-run, sustituyendo su ejecutable y argumentos reales. Para un comando en el directorio actual, use ./y pase todos los argumentos después de --:
Ejecuta un comando dentro de un ámbito transitorio de systemd con límites de CPU y memoria.
Para un comando propiedad del usuario, intente esto sudoprimero sin permisos de administrador. Si systemd informa que un controlador o propiedad solicitada no está disponible, es posible que el administrador del usuario no tenga permiso para delegarla; reintentar como root puede ser apropiado para una carga de trabajo a nivel de sistema, pero cambia el contexto de seguridad del comando. No ejecute un programa no confiable como root sin más. Si es necesario usar el administrador del sistema como root, úselo sudo systemd-run --scope ...solo después de considerar ese cambio.
La terminal permanece conectada al ámbito mientras se ejecuta el comando. Al pulsar la tecla Ctrl+CIntro, se interrumpe la operación en primer plano. El ámbito es transitorio y normalmente desaparece tras la finalización de los procesos. Es una forma práctica de iniciar un comando con ciertas limitaciones, en lugar de una política persistente para futuras ejecuciones.
3. Determinar el alcance e inspeccionar sus límites.
systemd-runImprime el nombre de la unidad que crea, normalmente algo como run-….scope. Mientras el comando aún se está ejecutando, lista el árbol de cgroup:
systemd-cgls
Localiza el ámbito transitorio y confirma que el programa objetivo y sus programas secundarios aparecen dentro de él. Esto es importante porque un programa secundario que se ejecute fuera de dicho ámbito no estará cubierto por el mismo límite de cgroup.
Utilice el árbol cgroup para confirmar que el programa y sus procesos secundarios están agrupados bajo el ámbito transitorio.
Utilice el nombre del ámbito impreso en el siguiente comando. Reemplace run-abc.scopecon el nombre real:
systemctl show run-abc.scope \
-p ControlGroup -p CPUQuotaPerSecUSec -p MemoryMax
CPUQuotaPerSecUSec=50000es consistente con una cuota del 50% cuando el período de cuota de systemd es de 100 ms; MemoryMax=1073741824es 1 GiB en bytes. Los valores en tiempo real son más útiles que asumir que cada host aceptará cada solicitud sin cambios, ya que los cgroups principales y los controladores disponibles pueden limitar el resultado efectivo.
Verifique el grupo de control informado por el alcance y los límites de CPU y memoria configurados.
4. Verifique los archivos cgroup del kernel y ajústelos de forma segura.
La ControlGrouppropiedad proporciona la ruta del cgroup relativa a /sys/fs/cgroup. Guárdela en una variable de shell para que los comandos sigan la ruta asignada realmente en su máquina:
En cgroup v2, cpu.maxcontiene una cuota y un período en microsegundos. Por ejemplo, 50000 100000significa 50 ms de tiempo de CPU en cada período de 100 ms. memory.maxMuestra el límite de memoria en bytes. Si faltan los archivos, confirme que el ámbito sigue activo y que el kernel está utilizando cgroup v2.
Lea los archivos cgroup v2 del kernel para verificar la cuota y el límite de memoria configurados.
Si inició una unidad de larga duración con nombre y necesita ajustar sus límites, systemd admite el cambio de propiedades de recursos en una unidad activa, por ejemplo sudo systemctl set-property --runtime my-worker.service CPUQuota=50% MemoryMax=1G. Esto se aplica al cgroup de ese servicio y requiere los privilegios adecuados. No adjunta un proceso arbitrario que ya se esté ejecutando solo porque se conozca su PID; para un proceso único, deténgalo limpiamente y reinícielo dentro del ámbito limitado. Para un servicio persistente, configure las propiedades en la unidad de servicio o en un archivo de configuración de systemd y reinícielo durante una ventana de mantenimiento apropiada.
Comprueba el resultado
Mantén la carga de trabajo activa mientras la inspeccionas. Confirma que systemd-cglsel proceso y sus procesos secundarios se encuentran dentro del ámbito previsto, que systemctl showse informan las propiedades solicitadas y que existen los archivos correspondientes cpu.maxcon memory.maxvalores finitos. Cuando el proceso finaliza, se elimina el ámbito transitorio, por lo que sus archivos cgroup pueden desaparecer.
Una cuota limita el tiempo de CPU, pero no garantiza un porcentaje fijo en un monitor de escritorio, y un límite de memoria estricto puede causar fallos si la aplicación necesita más de lo permitido. Si la carga de trabajo se vuelve inestable, deténgala y aumente el límite a un valor seguro medido o utilice un MemoryHigh=umbral de presión más flexible junto con uno más alto MemoryMax=. Para conocer el comportamiento exacto, consulte la documentación de systemd y del kernel instalada; las referencias autorizadas son el manual de ejecución de systemd de Ubuntu , el manual de control de recursos de systemd de Ubuntu y la documentación de cgroup v2 del kernel de Linux .