Tutorial

Alertas de disco lleno y RAM en un VPS, sin pila de supervisión

Seguridad y monitorización13 min de lectura9 pasos

Un disco se llena, la base de datos se detiene y el cliente se entera antes que usted. El coste es una intervención urgente y una confianza dañada. Una pila de supervisión completa es un segundo servidor que mantener, así que muchas agencias renuncian y no vigilan nada. Esta guía coloca seis alertas mínimas en shell en cada VPS: disco, inodos, memoria, servicios, certificados y copias. El control está vigilado a su vez por un latido externo.

Contenido· Un disco lleno no avisa a nadie1/14
  1. 01Un disco lleno no avisa a nadie
  2. 02Las seis alertas mínimas y el latido, en cada VPS
  3. 03Requisitos en cifras: casi nada
  4. 04Disco e inodos: los umbrales y lo que los desplaza
  5. 05Montar el dispositivo en una hora
  6. 06Memoria: OOM del kernel o límite de cgroup
  7. 07OnFailure: lo que cubre y lo que no
  8. 08Certificados y copias: avisar por la ausencia de éxito
  9. 09Scripts propios o pila de supervisión
  10. 10Vigile al vigilante
  11. 11Solución de problemas: los errores que vuelven
  12. 12Mensajes y síntomas con su remedio
  13. 13La documentación oficial
  14. 14Alertas sencillas, las mismas en cada VPS

Un disco lleno no avisa a nadie

El escenario se repite. Un VPS de cliente funciona desde hace meses, la base de datos escribe sus registros, las copias de seguridad se acumulan y una mañana el servicio se detiene. No salió ninguna alerta y el cliente se entera antes que usted. En PostgreSQL, un caso comunicado en la lista oficial del proyecto muestra la línea exacta: PANIC: could not write to file "pg_wal/xlogtemp.11399": No space left on device. Un PANIC no es una simple advertencia: el servidor ya no puede registrar sus escrituras, se detiene y solo reinicia correctamente cuando se libera espacio.

La dificultad no es detectar un disco lleno, sino detectarlo antes. Entre el 80 % de ocupación y la caída suelen quedar horas o días, y esa es justo la ventana que debe captar una alerta bien ajustada. Esta guía no repite la instalación de una pila de supervisión: coloca lo mínimo útil en cada VPS, en shell, sin un segundo servidor que mantener.

Las seis alertas mínimas y el latido, en cada VPS

  • Disco — dos umbrales, 80 % como aviso y 90 % como crítico, en cada punto de montaje relevante.
  • Inodos — un disco puede rechazar escrituras aunque queden bytes libres, si los inodos están agotados.
  • Memoria y OOM — detectar que el kernel mató un proceso, y no solo que la RAM está alta.
  • Servicios systemd — recibir un aviso cuando la base de datos, el servidor web o el proxy pasa al estado failed.
  • Certificados — avisar 21 días antes del vencimiento, cuando la renovación automática ha fallado en silencio.
  • Copias de seguridad — avisar por la ausencia de un éxito reciente, no solo por un error explícito.
  • El propio control — un latido externo que avisa cuando dejan de enviarse las alertas.

Requisitos en cifras: casi nada

Todo lo que sigue cabe en unas decenas de líneas de shell POSIX. Hace falta un VPS Linux con curl, cron o los timers de systemd, acceso root para escribir en /usr/local/bin y /etc, y alrededor de 1 MB de disco. El coste en memoria es el de un script que dura un segundo cada cinco minutos: despreciable, incluso en el VPS más pequeño.

Dos elementos externos completan el dispositivo: un canal de recepción (un bot de Telegram, o cualquier webhook accesible por HTTP) y un servicio de latido, que recibe un ping regular y le avisa cuando se detiene. Para este segundo punto, Healthchecks.io ofrece un plan gratuito limitado a 20 jobs y 100 entradas de registro por job, lo que cubre de sobra un parque pequeño; compruebe esos límites en la fuente antes de fiarse. Si no quiere depender de ningún servicio externo, el modo push de Uptime Kuma cumple el mismo papel en una máquina propia.

Disco e inodos: los umbrales y lo que los desplaza

El comando útil es df -h --output=pcent,target: solo muestra el porcentaje y el punto de montaje, que se lee y se procesa con facilidad. Para los inodos, la misma idea se convierte en df --output=ipcent,target. Una carpeta de sesiones o de pequeños archivos de caché puede consumir todos los inodos de un sistema de archivos ext4 mientras df -h aún muestra un 40 % de ocupación: la escritura falla igualmente con No space left on device.

Hay una segunda sutileza. En ext4, el 5 % de los bloques está reservado por defecto a los procesos privilegiados, según la página de manual de tune2fs; así los demonios del sistema pueden seguir escribiendo cuando un usuario ordinario ha llenado el disco. Consecuencia: un servicio que corre con una cuenta sin privilegios, como la base de datos, ve df marcar 100 % cuando el disco está ocupado en torno al 95 %. De ahí los umbrales elegidos: 80 % para tener tiempo de actuar, 90 % para actuar de inmediato. Esperar al 100 % es avisar después de la caída.

Montar el dispositivo en una hora

  1. Crear el canal de alerta

    Cree un bot de Telegram con BotFather, anote su token y el identificador de la conversación que debe recibir los mensajes. Todas las peticiones de la API de Bot siguen la forma https://api.telegram.org/bot<token>/METHOD_NAME, y el método de envío es sendMessage. Si prefiere un webhook (Slack, Mattermost, ntfy), solo cambia la última línea del script de envío.

  2. Escribir el archivo de entorno

    sudo mkdir -p /var/lib/alerte-vps
    sudo install -m 600 /dev/null /etc/alerte-vps.env
    Añada después cuatro líneas: TG_TOKEN=..., TG_CHAT=..., HC_URL=https://hc-ping.com/<uuid> (check cada cinco minutos) y HC_URL_JOUR=https://hc-ping.com/<otro-uuid> (check diario). El modo 600 deja el token legible solo para root.

  3. Escribir el script de envío con antirrepetición

    Guarde estas líneas en /usr/local/bin/alerte-envoi y haga el archivo ejecutable con sudo chmod 755. El archivo de bloqueo por mensaje evita que le despierten cada cinco minutos por la misma alerta: un mensaje idéntico solo se reenvía pasada una hora.
    #!/bin/sh
    . /etc/alerte-vps.env
    f=/var/lib/alerte-vps/$(echo "$1" | md5sum | cut -c1-12)
    [ -n "$(find "$f" -mmin -60 2>/dev/null)" ] && exit 0
    touch "$f"
    curl -fsS -m 10 --retry 3 "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" -d chat_id="${TG_CHAT}" --data-urlencode text="$(hostname) $1"

  4. Controlar disco e inodos

    En /usr/local/bin/alerte-rapide (shebang #!/bin/sh), añada los dos bucles siguientes. El filtro grep -v descarta los sistemas de archivos que no exponen inodos y muestran un guion.
    df --output=pcent,target -x tmpfs -x devtmpfs | tail -n +2 | while read p m; do n=${p%\%}; if [ "$n" -ge 90 ]; then alerte-envoi "CRIT disk $m"; elif [ "$n" -ge 80 ]; then alerte-envoi "WARN disk $m"; fi; done
    df --output=ipcent,target -x tmpfs -x devtmpfs | tail -n +2 | grep -v '^ *-' | while read p m; do [ "${p%\%}" -ge 90 ] && alerte-envoi "INODES $m"; done

  5. Detectar los procesos matados por el OOM killer

    El contador oom_kill de /proc/vmstat solo crece desde el arranque. Se compara con el valor anterior, guardado en un archivo; tras un reinicio el contador vuelve a cero, la comparación falla una vez y luego se restablece.
    n=$(awk '/^oom_kill/ {print $2}' /proc/vmstat)
    old=$(cat /var/lib/alerte-vps/oom 2>/dev/null || echo 0)
    [ "$n" -gt "$old" ] && alerte-envoi "OOM kill"
    echo "$n" > /var/lib/alerte-vps/oom

  6. Añadir el latido y programar

    Termine alerte-rapide con el ping. Solo se alcanza si el script ha llegado hasta el final; si cron se detiene, si el disco pasa a solo lectura o si el script falla, el ping cesa y el servicio externo le avisa. Añada después las líneas de cron en /etc/cron.d/alerte-vps.
    . /etc/alerte-vps.env; curl -fsS -m 10 --retry 5 -o /dev/null "$HC_URL"
    PATH=/usr/local/bin:/usr/bin:/bin
    */5 * * * * root /usr/local/bin/alerte-rapide
    30 7 * * * root /usr/local/bin/alerte-quotidien

  7. Controlar certificados y copias una vez al día

    En /usr/local/bin/alerte-quotidien, añada estas líneas. La opción -checkend de openssl x509 falla si el certificado caduca dentro del número de segundos indicado; 1814400 segundos equivalen a 21 días. La prueba de copia avisa cuando ningún archivo .gz no vacío es más reciente que 1560 minutos, es decir 26 horas. El script termina con su propio ping, hacia el segundo check: sin él, un control diario caído en silencio pasaría inadvertido.
    echo | openssl s_client -servername your-domain.com -connect your-domain.com:443 2>/dev/null | openssl x509 -noout -checkend 1814400 || alerte-envoi "CERT your-domain.com"
    find /var/backups/app -name '*.gz' -mmin -1560 -size +1k | grep -q . || alerte-envoi "BACKUP absent"
    . /etc/alerte-vps.env; curl -fsS -m 10 --retry 5 -o /dev/null "$HC_URL_JOUR"

  8. Conectar los servicios críticos a OnFailure

    Cree /etc/systemd/system/[email protected] con el contenido siguiente y luego sudo systemctl daemon-reload.
    [Unit]
    Description=Alerte echec de %i
    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/alerte-envoi "FAILED %i"
    Para cada servicio a vigilar, abra un drop-in con sudo systemctl edit mariadb.service y añada estas dos líneas.
    [Unit]
    OnFailure=notify-failure@%n.service

  9. Forzar una alerta de prueba y limpiar

    Una alerta que nunca se ha disparado no es una alerta. Compruebe primero el espacio libre, cree un archivo lo bastante grande para superar el umbral, ejecute el script a mano y borre el archivo. Si el mensaje no llega, el fallo está en el canal, y es mejor descubrirlo ahora.
    df -h --output=pcent,target /var/tmp
    sudo fallocate -l 2G /var/tmp/test-alerte.img
    sudo /usr/local/bin/alerte-rapide
    sudo rm /var/tmp/test-alerte.img

Memoria: OOM del kernel o límite de cgroup

Dos mecanismos matan un proceso por falta de memoria y no se leen en el mismo sitio. El primero es el OOM killer del kernel, cuando a toda la máquina le falta RAM: el registro del kernel contiene entonces un mensaje del tipo Out of memory: Killed process, que journalctl -k permite encontrar. El segundo es el límite de un cgroup. Según la documentación de systemd, cuando el uso de una unidad no puede contenerse bajo MemoryMax=, el OOM killer se invoca dentro de la unidad: el resto de la máquina puede tener memoria libre.

El contador oom_kill de /proc/vmstat cubre el primer caso a escala de máquina. Para una unidad concreta, el archivo memory.events de su cgroup expone un contador oom_kill propio, definido por la documentación del kernel como el número de procesos del cgroup matados por cualquier tipo de OOM killer. En un VPS que aloja una aplicación voraz, como la descrita en la guía de n8n y OOM en producción, este segundo contador explica las paradas que free -h nunca muestra.

OnFailure: lo que cubre y lo que no

Según la documentación de systemd, OnFailure= enumera las unidades que se activan cuando la unidad entra en el estado failed. La plantilla [email protected] recibe el nombre de la unidad defectuosa gracias al especificador %n, y el mensaje de alerta puede añadir la salida de systemctl status o de journalctl -u como contexto.

El límite es estructural: un servicio que funciona pero ya no responde nunca pasó por el estado failed, así que OnFailure= no dice nada. Un servicio relanzado por Restart= solo llega ahí cuando se alcanza el límite de arranque. Para esos casos, añada una sonda de aplicación sencilla, por ejemplo un curl a la dirección de salud de la aplicación, en el script rápido. La sintaxis de timers y cron se trata en la guía de cron y timers de systemd, y no hace falta repetirla aquí.

Certificados y copias: avisar por la ausencia de éxito

Una renovación automática de certificado puede fallar en silencio durante semanas: un registro DNS modificado, un puerto bloqueado, un complemento roto. El certificado no caduca ese día, caduca noventa días después, y nadie se acuerda. La prueba con openssl interroga lo que el visitante recibe realmente, lo cual vale más que leer un archivo del disco. En un servidor gestionado con Certbot, certbot certificates lista los certificados y su vencimiento, y certbot renew --dry-run comprueba que la próxima renovación saldrá bien.

Misma lógica para las copias de seguridad. Una alerta disparada por el fallo de un script de copia no ve el caso en que el script nunca se ejecutó. La alerta correcta se coloca sobre la ausencia: ningún archivo reciente, o un archivo de tamaño cero. Eso hace la línea find -mmin del script diario, y por eso calla cuando todo va bien y habla en cuanto la cadena de copias se detiene, sea cual sea el motivo.

Scripts propios o pila de supervisión

Desplace la tabla

CriterioScripts shell y OnFailureBeszel o Uptime Kuma
Puesta en marchaUna hora, unos pocos archivos en `/usr/local/bin`Un hub que alojar, agentes que instalar en cada VPS
Parque objetivoDe 1 a 5 VPS, hasta 10 si los umbrales son idénticosMás allá de 5 a 10 VPS, o en cuanto se necesite comparar
Historial y gráficasNinguno, solo el instante de la alertaGráficas, tendencias, comparación entre máquinas
MantenimientoNada que actualizar fuera del shellUn segundo servidor y sus actualizaciones que mantener
Servicios de aplicaciónUna sonda `curl` que escribir uno mismoSondas HTTP y TCP y página de estado listas para usar
Caída del monitorDetectada por el latido externoA vigilar aparte, el hub es a su vez una máquina
Cuándo elegirloAlertas mínimas, parque pequeño, ningún servidor extraHistorial deseado, parque en crecimiento, equipo compartido

Vigile al vigilante

La trampa de estos scripts es convertirse en un falso seguro: callan porque todo va bien, o porque están rotos, y el silencio se parece en ambos casos. El ping de latido resuelve el problema. Ajuste el periodo esperado del check un poco por encima del intervalo de cron y añada un margen de tolerancia: una alerta de silencio que llega veinte minutos tarde vale más que un falso positivo en cada reinicio. Mantenga también /etc/alerte-vps.env en modo 600 y no versione nunca el token.

Solución de problemas: los errores que vuelven

Las propias alertas fallan de manera previsible. Estos son los casos que se encuentran con más frecuencia, con el mensaje o síntoma que reconocer y el remedio. Cada uno se comprueba a mano antes de buscar más lejos.

Mensajes y síntomas con su remedio

  • PANIC: could not write to file "pg_wal/...": No space left on device — el volumen que contiene los registros de PostgreSQL está lleno. Libere primero espacio fuera de PostgreSQL (registros rotados, copias antiguas), no borre nunca a mano los archivos de pg_wal y reinicie después el servicio.
  • No space left on device mientras df -h indica espacio — los inodos están agotados. Ejecute df --output=ipcent,target, localice la carpeta con millones de archivos pequeños (sesiones, caché) y purgue.
  • Disco lleno pero du no encuentra el espacio — archivos borrados siguen abiertos por un proceso. sudo lsof +L1 los lista; reiniciar el proceso libera el espacio.
  • oom_kill aumenta, nada en journalctl -k — el registro del kernel rotó o la muerte viene de un límite MemoryMax=. Lea memory.events en el directorio del cgroup de la unidad y journalctl -u para la unidad.
  • Una unidad funciona pero ya no responde, sin alerta — es el límite de OnFailure=. Añada una sonda curl a la dirección de salud y avise según el código de retorno.
  • Ningún mensaje de Telegram, ningún error visible — cron envía la salida del script por correo local, que nadie lee. Ejecute alerte-envoi test a mano con sudo y lea la respuesta de curl.
  • El certificado se acerca al vencimiento aunque Certbot esté instalado — ejecute certbot renew --dry-run y lea el error de validación; corrija después el DNS o el puerto implicado.

La documentación oficial

Cada comportamiento descrito aquí procede de una fuente primaria. Para OnFailure=, la página de manual de systemd.unit; para MemoryMax=, systemd.resource-control; para los contadores oom y oom_kill, la documentación de cgroups v2 del kernel; para el 5 % reservado, la página de manual de tune2fs. En el envío, la API de Bot de Telegram describe la forma de las peticiones, y la documentación de la API de Healthchecks las direcciones de ping, con la página de precios para los límites del plan gratuito. Para la renovación, la documentación de Certbot. El mensaje de PostgreSQL citado procede de un hilo de la lista oficial del proyecto.

Alertas sencillas, las mismas en cada VPS

Seis alertas y un latido no sustituyen una pila de supervisión: cubren lo que realmente tumba un servidor: disco, inodos, memoria, servicios, certificados, copias. La ganancia principal es la uniformidad: mismos umbrales, mismos mensajes, mismo gesto de prueba en cada máquina del parque. Cuando el parque crece o hace falta historial, el salto a una pila se prepara en la guía de Beszel y en la guía de alertas proactivas con Beszel y Uptime Kuma, que tratan la instalación de principio a fin.

Un parque de VPS de clientes, umbrales homogéneos

En ServOrbit.com, los dominios, alojamientos y servidores de un parque de clientes se reúnen en un mismo lugar, con el mismo espacio de gestión. La opción de administración VPS existe para los clientes que no quieren administrar su servidor.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva