Inicio
» LINUX
»
Cómo limitar el uso de CPU y RAM de un proceso con Cgroups en Ubuntu
Cómo limitar el uso de CPU y RAM de un proceso con Cgroups en Ubuntu
En Ubuntu, la forma más segura de limitar la carga de trabajo con cgroups es permitir que systemd cree y administre su grupo de control. Úselo systemd-runpara un comando que esté iniciando ahora, o configure un servicio de systemd cuando el límite deba mantenerse después de los reinicios. Establezca CPUQuota=un límite máximo de tiempo de CPU y elija entre MemoryHigh=para la presión y MemoryMax=para un límite de memoria estricto. Estos límites se aplican a la unidad y sus procesos secundarios en conjunto.
Un cgroup (grupo de control) es un mecanismo del kernel de Linux que organiza los procesos para que el sistema pueda contabilizar y controlar su uso de recursos. El sistema systemd de Ubuntu ya coloca los servicios en cgroups, por lo que la mayoría de los usuarios no necesitan crear directorios /sys/fs/cgroupmanualmente. Los ejemplos que se muestran a continuación utilizan la interfaz resource-control de systemd y deben compararse con la versión de systemd instalada en su distribución de Ubuntu.
Maqueta ilustrativa de terminal para comprobar systemd y el montaje de cgroup v2. La versión y la salida mostradas son ejemplos, no resultados de una prueba.
Elija el control que se ajuste al problema.
Método
Lo que controla
Mejor ajuste
Principal compensación
systemd-runalcance transitorio
Cuota de CPU y límites de memoria para un comando recién lanzado y sus descendientes.
Un trabajo de compilación, script, importación o procesamiento por lotes único.
El alcance es temporal y finaliza con la carga de trabajo; no se adjunta a un proceso arbitrario que ya esté en ejecución.
Configuración del servicio systemd
Recursos para el cgroup del servicio, incluidos los procesos secundarios.
Un demonio o aplicación que debería mantener los mismos límites después del reinicio.
Requiere configuración del servicio y, normalmente, un reinicio para aplicar los nuevos ajustes.
Archivos cgroup v2 directos
Controladores a nivel de kernel como cpu.maxymemory.max
Entornos de ejecución de contenedores, administradores de cgroup delegados o administración especializada
Es un proceso más manual; systemd controla gran parte de la jerarquía de Ubuntu, y escribir en su árbol administrado puede entrar en conflicto con systemd o fallar debido a permisos y delegación.
niceoCPUWeight=
Prioridad relativa de la CPU cuando los grupos compiten
Mantener las tareas en segundo plano con menor prioridad, permitiéndoles usar la CPU inactiva.
Esto no supone un límite estricto para la CPU y no limita la memoria.
Para la mayoría de las máquinas Ubuntu interactivas, un ámbito transitorio es la opción reversible más rápida. Para un servicio de producción, utilice la unidad de servicio para que la política quede documentada y se restaure al arrancar. Utilice archivos cgroup directos solo cuando gestione deliberadamente una jerarquía delegada o cree un flujo de trabajo de contenedor/tiempo de ejecución.
Compruebe el sistema Ubuntu antes de establecer límites.
Primero, compruebe que systemd esté disponible y si el sistema de archivos cgroup es unified v2:
systemctl --version
stat -fc %T /sys/fs/cgroup
El resultado cgroup2fsdel segundo comando indica que se trata del sistema de archivos cgroup v2 unificado. Las versiones de Ubuntu y los sistemas personalizados pueden variar, por lo que no asuma que todas las máquinas tienen la misma jerarquía o las mismas características de systemd. También puede consultar la versión actual de systemd con el primer comando. Si el montaje de cgroup no es v2, algunas propiedades de los recursos o el comportamiento del controlador pueden diferir; consulte la página del manual de Ubuntu para la versión instalada antes de copiar una configuración.
Seleccione los valores tras medir la carga de trabajo. Deje margen para el resto del sistema y recuerde que los límites establecidos en un servicio de usuario también están sujetos a los límites de su segmento principal. Un cgroup hijo no puede recibir más recursos de los que permite su antecesor.
Limita un comando que estás a punto de iniciar
Para un comando en tu propia sesión de usuario, ejecútalo en un ámbito transitorio con systemd-run --user --scope. Por ejemplo:
Maqueta ilustrativa de terminal de un comando systemd-run único con una cuota de CPU, un umbral de presión de memoria y un límite máximo de memoria.
Reemplaza el comando de Python con el programa que realmente necesitas ejecutar. Este ejemplo le da al cgroup un ancho de banda máximo de CPU equivalente a la mitad de una CPU, comienza a manejar la presión de memoria alrededor de 700 MiB y establece un máximo de memoria de 900 MiB. Los valores de memoria usan unidades base 1024 de systemd. Una cuota 100%representa hasta el tiempo de una CPU; 200%puede usar hasta el tiempo de dos CPU cuando estén disponibles. No significa un porcentaje de todos los núcleos de la computadora.
El comando se ejecuta en primer plano porque se trata de un ámbito. Al finalizar, la unidad transitoria desaparece. Elimínela --usersolo si tiene previsto utilizar el administrador del sistema y dispone de los privilegios necesarios; para una unidad transitoria de todo el sistema, ejecute el comando con sudolas opciones de comando adecuadas. Es posible que se rechacen los ajustes de recursos si el administrador o el controlador de cgroup no los admiten.
Establecer límites en un servicio persistente de systemd
Para un servicio como este worker.service, cree un archivo de inserción en lugar de editar el archivo de unidad del proveedor. Ejecute sudo systemctl edit worker.servicey agregue:
Ejemplo de configuración del servicio systemd con controles persistentes de CPU y memoria. Utilice el nombre real del servicio y los valores adecuados para su carga de trabajo.
Guarda el archivo drop-in, luego recarga las definiciones de unidades de systemd y reinicia el servicio para que el proceso se inicie bajo la política revisada:
Utilice un límite de memoria prudente. Si el servicio no puede recuperar suficiente memoria por debajo de este MemoryMaxlímite, el kernel podría activar el mecanismo de eliminación de procesos por falta de memoria dentro de ese grupo de control. Esto puede terminar uno o más procesos en el grupo de servicio e interrumpir su funcionamiento. Una estrategia más segura suele ser establecer este límite MemoryHighen un nivel donde la recuperación y la limitación de memoria sean aceptables, y luego establecer MemoryMaxun límite superior como límite final. Realice pruebas con cargas máximas realistas antes de implementar límites estrictos.
Verifique la unidad y observe su comportamiento.
Para el alcance transitorio, compruebe su estado utilizando el nombre de la unidad que proporcionó:
Vista ilustrativa del estado y del monitor de cgroup. Las cifras de CPU y memoria que se muestran aquí no corresponden a mediciones de una ejecución real.
systemctl --user status worker-capped.scope
systemd-cgtop
Para un servicio del sistema, omítalo --useren el comando status. La vista de estado confirma que la unidad existe y está activa; systemd-cgtopmuestra el uso de recursos en tiempo real por grupo de control. Para inspeccionar las propiedades configuradas, consulte la unidad directamente, por ejemplo:
La memoria reportada para un cgroup no necesariamente coincide con la cifra del conjunto residente de un proceso: representa la memoria asignada al grupo y puede incluir a los descendientes de la carga de trabajo. Considere el monitoreo como evidencia del comportamiento de esta carga de trabajo a lo largo del tiempo, no como un único valor para optimizar indiscriminadamente.
¿Qué ocurre si el proceso ya está en marcha?
systemd-runInicia un nuevo comando dentro de una nueva unidad; no toma un PID existente arbitrario y lo mueve a ese ámbito. Si el proceso pertenece a un servicio systemd, aplique la configuración a ese servicio con un drop-in o, para un cambio temporal, use sudo systemctl set-property --runtime worker.service CPUQuota=50% MemoryHigh=700M MemoryMax=900M. El --runtimeformato es temporal y no reemplaza una configuración de servicio persistente.
Si el proceso es un programa normal en su sesión de escritorio, el método seguro y sencillo suele ser detenerlo y reiniciarlo systemd-run. Aplicar una propiedad a una porción más amplia, como toda su porción de usuario, puede afectar a muchas aplicaciones no relacionadas. Mover un proceso escribiendo su PID en un archivo cgroup requiere control de la jerarquía delegada correspondiente y debe respetar las reglas de ubicación de procesos de cgroup v2; no escriba en directorios administrados por systemd al azar.
Cómo elegir una política de CPU y memoria
¿Necesitas un límite máximo de CPU? Elige CPUQuota=. Los valores más bajos reducen el consumo máximo de CPU, pero pueden ralentizar la finalización y aumentar el tiempo de espera.
¿Necesitas solo prioridad baja? Considera CPUWeight=usar una cuota. El peso comparte la CPU relativamente bajo contención; no reserva un porcentaje fijo ni impide el uso de la CPU inactiva.
¿Necesitas gestionar la presión de la memoria sin que se produzca un bloqueo inmediato? Establécelo MemoryHigh=como umbral de presión principal y observa la latencia y el comportamiento de recuperación.
¿Necesitas un límite de contención final? Añade MemoryMax=suficiente margen para los picos normales. Prepárate para un comportamiento de falta de memoria (OOM) cuando no se pueda respetar el límite.
¿Ya utilizas un contenedor? Opta por las opciones de CPU y memoria compatibles con el gestor de contenedores, que configuran los cgroups para ese contenedor y se ajustan a su ciclo de vida.
No existe un límite ideal único para cada carga de trabajo. Un proceso por lotes de escritorio puede tolerar una cuota baja y un límite de memoria moderado; un servicio sensible a la latencia puede necesitar mayor capacidad de CPU y un límite más alto MemoryHighpara evitar pausas relacionadas con la recuperación de memoria. Comience con una configuración conservadora, supervise el equipo durante un pico representativo y ajuste un parámetro a la vez.