Ulimit (limits.conf) configuración de problemas comunes en Linux

Ulimit (limits.conf) configuración de problemas comunes en Linux. Miscelánea

ulimit: restricciones del proceso actual, por ejemplo, el número de archivos abiertos simultáneamente. Referencia: man limits.conf. El archivo de configuración se encuentra en /etc/security/limits.conf.

Establecer límites usando ulimit puede prevenir desastres en tus sistemas Linux, pero debes anticipar dónde tienen sentido las restricciones y dónde causarán problemas.

Para ver los límites asociados con tu inicio de sesión, usa el comando ulimit -a. Si estás usando una cuenta de usuario normal, lo más probable es que veas algo como esto:

~$ ulimit -a
core file size              (blocks, -c) 0
data seg size               (kbytes, -d) unlimited
scheduling priority                 (-e) 0
file size                   (blocks, -f) unlimited
pending signals                     (-i) 7728
max locked memory           (kbytes, -l) 65536
max memory size             (kbytes, -m) unlimited
open files                          (-n) 1024
pipe size                (512 bytes, -p) 8
POSIX message queues         (bytes, -q) 819200
real-time priority                  (-r) 0
stack size                  (kbytes, -s) 8192
cpu time                   (seconds, -t) unlimited
max user processes                  (-u) 7728
virtual memory              (kbytes, -v) unlimited
file locks                          (-x) unlimited

Llama inmediatamente la atención que no puedes crear volcados de memoria (core dumps) porque el tamaño máximo del archivo core es 0. Mientras el tamaño del archivo core sea cero, no se permiten los volcados de memoria. Esto tiene sentido para la mayoría de los usuarios, ya que probablemente no harán nada con un volcado de memoria más que eliminarlo, pero si necesitas un volcado de memoria para depurar los problemas de tu aplicación, puedes ajustar el tamaño del archivo core a ilimitado (unlimited).

Puedes cambiar los límites en el archivo de configuración, que normalmente es /etc/security/limits.conf, o mediante la línea de comandos. Recuerda que cuando cambias los límites a través de la línea de comandos, tus cambios no persistirán después de un reinicio del sistema operativo. Por ejemplo, para cambiar el número máximo de procesos de usuario (max user processes), usa el modificador -u (de la lista de salida del comando ulimit -a):

ulimit -u 8000

En limits.conf, los límites se pueden establecer para cada usuario o grupo. Cada límite se especifica en una línea separada. Por ejemplo, para el grupo de desarrolladores, configuremos los límites para abrir archivos, donde «hard» define estrictamente el número máximo, y al alcanzar el valor del límite inferior «soft», los usuarios recibirán advertencias:

@developers     soft    nofile      2048
@developers     hard    nofile      8192

Leer también: ProcFS el sistema de archivos para procesos (/proc)

¿No sabes qué parámetros establecer? ¡Establécelos como se indica a continuación!

El límite blando (soft limit) generalmente se establece en un nivel inferior y actúa como una advertencia para el usuario. Este no es el límite final, pero cuando se alcanza, el sistema puede advertir al usuario que los recursos se están agotando. El valor recomendado para soft nofile puede variar, pero a menudo se establece en el rango de 1024 a 4096.

El límite estricto (hard limit) establece un máximo absoluto que no se puede exceder bajo ninguna circunstancia. Este límite sirve para proteger el sistema contra sobrecargas. El valor recomendado para hard nofile suele ser significativamente más alto y se puede establecer entre 4096 y 65535, dependiendo de los requisitos del sistema y de la aplicación.

Por ejemplo, una línea en limits.conf podría verse así:

* soft nofile 4096
* hard nofile 65535

Esto significa que para todos los usuarios, el límite blando en el número de archivos abiertos se establece en 4096, y el límite estricto se establece en 65535.

Too many open files (Demasiados archivos abiertos)

Asterisk IP-PBX: Features, Requirements, and Configuration rtp.c: Unable to allocate RTP socket: Too many open files res_timing_timerfd.c: Read error: Bad file descriptor

El error «Too many open files» significa que el servidor se está quedando sin recursos para el límite máximo de archivos abiertos (max open file limit).

Necesitas aumentar el límite en el número de archivos abiertos simultáneamente en el archivo limits.conf. Para empezar, verifiquemos qué límite está configurado en el sistema operativo, utilizando datos del sistema de archivos ProcFS. Y verificaremos el parámetro que especifica el número de archivos abiertos simultáneamente:

# cat /proc/sys/fs/file-max
348651

Establezcámoslo para el usuario asterisk:

# nano /etc/security/limits.conf
...
asterisk        soft    nofile          65535
asterisk        hard    nofile          65535
...

Verifiquemos ulimit -a:

core file size              (blocks, -c) 0
data seg size               (kbytes, -d) unlimited
scheduling priority                 (-e) 20
file size                   (blocks, -f) unlimited
pending signals                     (-i) 16382
max locked memory           (kbytes, -l) 64
max memory size             (kbytes, -m) unlimited
open files                          (-n) 65536
pipe size                (512 bytes, -p) 8
POSIX message queues         (bytes, -q) 819200
real-time priority                  (-r) 0
stack size                  (kbytes, -s) 8192
cpu time                   (seconds, -t) unlimited
max user processes                  (-u) unlimited
virtual memory              (kbytes, -v) unlimited
file locks                          (-x) unlimited

ulimit tamaños de archivo

Principalmente cuando trabajamos en un sistema UNIX, asumimos que sus recursos son ilimitados. Por ejemplo, no nos importa si un archivo creado resulta ser «demasiado grande», lo cual no es tan raro en computadoras personales con disquetes. Si estamos involucrados en el mantenimiento y la administración de un sistema UNIX, entonces debemos estar preparados para lidiar con situaciones donde se exceden varios límites del sistema. Siempre es mejor investigar estos problemas con anticipación en situaciones no críticas, así que echemos un vistazo a los límites de tamaño de archivo y su significado.

Algunos parámetros están «hardcoded» (codificados de forma rígida) en el núcleo del sistema durante su generación. Uno de esos valores es el tamaño máximo de archivo. Determina el número más grande de bloques que un archivo puede ocupar. Este parámetro está estrechamente relacionado con el método UNIX de usar descriptores de índice de archivos (inodes). Estos son conjuntos de punteros, entre los cuales los primeros diez apuntan a bloques de datos, los siguientes apuntan a otra tabla, los siguientes apuntan a una tabla que apunta a una tabla, etc.

Hay otra limitación de tamaño de archivo definida para cada usuario mientras trabaja en el sistema: el número ulimit (límite de usuario). Este valor se establece al momento de iniciar sesión en el sistema y representa el número de bloques de 512 bytes que puedes escribir en cualquier archivo dado. Hay un comando ulimit en la shell que, cuando se llama sin argumentos, muestra este número. Este mismo comando te permite disminuir tu valor de ulimit. Solo el superusuario (root) puede AUMENTAR los valores de ulimit.

Un efecto secundario de disminuir el valor de ulimit es que no puedes volver a aumentarlo al valor de registro. El valor de ulimit permanece igual durante toda la duración de tu sesión de shell, por lo que para restaurar el valor de registro, necesitas cerrar sesión en el sistema y luego volver a iniciar sesión.

Otro punto interesante es que si estableces tu valor de ulimit en 0, ¡no podrás crear ningún archivo! El tamaño máximo permitido de archivo en este caso es cero, por lo que no se puede crear ningún archivo. Esto parece bastante lógico, sin embargo, hay situaciones donde PUEDE existir un archivo de tamaño cero. Nuevamente, para restaurar tu valor normal de ulimit, necesitas cerrar sesión en el sistema y luego iniciar sesión de nuevo.

Como se mencionó anteriormente, solo el superusuario puede aumentar el valor de ulimit. Este procedimiento es bastante simple. Primero, necesitas aumentar el valor de ulimit con el comando ulimit, y luego iniciar una shell. Esta nueva shell tiene el nuevo valor de ulimit. Si queremos que el sistema arranque con una shell que tenga un valor de ulimit más alto, podemos configurar un programa en inittab (tabla de inicialización del sistema) para que esta operación se realice automáticamente.

Nginx número de sockets abiertos, archivos (descriptores de archivos)

In Nginx, se requieren descriptores de archivos para cada conexión con un cliente y para devolver un archivo estático desde la caché. El número de descriptores requeridos puede crecer rápidamente. Sin embargo, el número total de descriptores está limitado por el sistema operativo. Límite en el número de sockets abiertos simultáneamente: Normalmente, la mayoría de los sistemas *nix limitan el número de sockets a 1024.

Asumimos que los procesos del servidor Nginx se están ejecutando bajo el usuario nginx. Para comodidad de ver los límites del sistema operativo para el usuario nginx, iniciemos sesión con él. El lanzamiento estándar de su no ayudará (obtendremos el error: Esta cuenta no está disponible actualmente) ya que el usuario es un usuario del sistema, por lo que necesitamos usar modificadores:

# su -l nginx -s /bin/bash
$ whoami
nginx

O simplemente ejecuta el comando en nombre de nginx:

# su nginx -s /bin/bash -c 'ulimit -a'

Reunamos los valores actuales.

Límite actual (Límite blando) de archivos abiertos por proceso para el usuario actual:

su nginx -s /bin/bash -c 'ulimit -Sn'
1024

Límite máximo (Límite estricto) de archivos abiertos por proceso para el usuario actual:

su nginx -s /bin/bash -c 'ulimit -Hn'
4096

Cuenta el número de archivos abiertos por todos los procesos:

# lsof | wc -l
9973

Cuenta el número de archivos abiertos por todos los procesos, según los datos del núcleo de Linux. Veremos 3 números (el número de archivos abiertos actualmente; el número de archivos abiertos pero sin usar; el número máximo de archivos abiertos):

# cat /proc/sys/fs/file-nr
2112    0       94547

Límite máximo de archivos abiertos para todo el sistema:

# cat /proc/sys/fs/file-max
94547

Basado en los números obtenidos anteriormente, el número mínimo recomendado para el ulimit de Nginx resultó ser el siguiente. Agreguémoslos al archivo /etc/security/limits.conf:

nginx soft nofile 4096
nginx hard nofile 10240

Ahora cambiamos los límites en nginx; para hacer esto, al principio del archivo /etc/nginx/nginx.conf, aproximadamente después de las líneas:

user nginx;

escribimos
worker_rlimit_nofile 10240;

La directiva worker_rlimit_nofile cambia el límite en el número de archivos abiertos por un proceso de node de trabajo (worker process).

Conclusión o Recomendación

No establezcas el número de límite por encima de 65535. En el caso de las conexiones entrantes, no hay un límite obvio de 65535 conexiones, lo más probable es que alcances el límite en los descriptores de archivos (sockets), ya que se necesita un socket para cada conexión. Al mismo tiempo, los límites pueden estar en el nivel de límite de usuario (y se debe tener en cuenta que se aplican límites separados a los servicios iniciados a través de systemd, y no a los especificados en limits.conf). Por lo general, por defecto, los límites de descriptores están alrededor de 1024-4096, significativamente inferiores a 65535. Para una cantidad muy grande de sockets, también será necesario cambiar sysctl para el número máximo de archivos abiertos y, posiblemente, reconstruir el núcleo para eludir las restricciones superiores codificadas de forma rígida.

Redacción
Rate author
El blog del informático
Añadir un comentario