Creative Commons License
Excepto donde se indique otra cosa, todo el contenido de este lugar está bajo una licencia de Creative Commons.
Taquiones > sysadmin > NUT - Network UPS Tools

NUT - Network UPS Tools

Introducción

El programa NUT sirve para monitorizar UPS (sistemas de alimentación ininterrumpida) de diferentes fabricantes y con distintos sistemas de comunicación, y proporcionar un API común a todos ellos.

En el esquema más básico encontramos un ordenador alimentado por una UPS y conectado a ella para monitorizarla, por lo que tendrá funcionando sobre ella varios programas:

  • El programa controlador de la UPS (/lib/nut/newhidusb en el ejemplo de más abajo), que es el que habla con el dispositivo.
  • El demonio de comunicación entre el controlador y el exterior, /sbin/upsd, que mantiene un caché de estado para que la respuesta tenga la mínima latencia. También se encarga de comunicar las órdenes administrativas al dispositivo.
  • El monitorizador, /sbin/upsmon, y el encargado de apagar el sistema cuando se dan las condiciones adecuadas.

Si una UPS alimenta a más de un ordenador sólo uno de ellos puede comunicarse con ella directamente. Tendrá, por tanto, el demonio upsd, el controlador del dispositivo, y el programa upsmon en modo maestro (master). El resto únicamente tendrán funcionando upsmon pero en modo esclavo (slave).

Escenarios

Existen dos elementos clave:

  1. Una UPS comunicada con un ordenador.
  2. Una UPS alimentando a un ordenador.

A nivel de ordenador individual nos encontramos alguno de estos escenarios:

  • Comunicado con una UPS pero no alimentado por ella.
  • Alimentado por una UPS pero no comunicado con ella.
  • Alimentado por una UPS y comunicado con ella.

Sólo comunicado

Este es un caso un tanto especial, pero que puede darse en instalaciones grandes cuando se centraliza el software de control, ó cuando se pretende monitorizar el funcionamiento de una ó varias (vía knutclient, por ejemplo).

Alimentado y no comunicado

Bastante común cuando una UPS tiene varias salidas energéticas y una única vía de comunicación. Si una de las máquinas se comunica con ellas, las demás tendrán que conformarse con consultar remótamente el controlador.

Bastará con que tengan funcionando el programa upsmon en modo esclavo.

Alimentado y comunicado

Es normal es que exista al menos una máquina que reciba la energía de una UPS y además se comunique con ella. Tendrá que tener funcionando el controlador hardware, upsd y upsmon en modo maestro.

Maestro y esclavo

Son los dos roles bajo los que puede funcionar el programa de monitorización upsmon.

El rol maestro conviene usarlo cuando está funcionando en la misma máquina que el programa upsd; bajo esta circunstancia se encarga entonces de recibir los eventos de la UPS, de avisar a los demás del cierre forzoso, de esperar (no indefinidamente) a que los esclavos cierren sus sistemas, y de apagar la propia UPS mediante una orden concreta.

El rol esclavo, por contra, se debería emplear cuando se recibe la energía de una UPS pero no se tiene su control directo; en este caso confíamos en que el proceso que actúa como maestro nos indique cuando tenemos que cerrar, y así nos ocupamos únicamente de nuestro sistema.

Instalación del software

Hablando de la distribución estable de Debian, actualmente Debian Etch, los paquetes que se necesitan se limitan a:

  • nut que contiene tanto los controladores como los servidores de monitorización.
  • nut-usb que incluye controladores para las UPS conectables vía USB.
  • nut-cgi en el caso de que queramos monitorizar vía web.

Configuración

Los archivos de configuración se incluyen en el directorio de ejemplos del paquete, y basta con copiarlos a /etc/nut para empezar a trabajar sobre ellos. Contienen bastante documentación, ampliable gracias a las páginas de manual, y son bastante sencillos de entender.

Además el proyecto incluye abundante documentación y muchas referencias a otras fuentes, como un artículo de Carla Schroder.

El paquete Debian efectúa bastantes tareas de instalación, incluyendo la creación de un usuario y un grupo nut, que será el encargado de hacer funcionar la instalación, a excepción del usuario root que sólo se emplea para lanzar el comando de cierre de sistema cuando la ocasión lo requiere.

[!] Los siguientes archivos de configuración deben tener como propietarios a root.nut y permisos de acceso limitados a 0640, dado que contienen contraseñas de acceso a los servicios.

Definición del controlador

El archivo /etc/nut/ups.conf describe las UPS que estamos monitorizando. Una vez que hemos seleccionado el controlador adecuado para la UPS, se le abre una sección en él, incluyendo una descripción, un puerto de conexión y otros parámetros que puedan ser necesarios, y que dependen del controlador en sí.

En mi caso el archivo queda así:

[servers]
    driver = newhidups
    port   = auto
    desc   = "UPS de servidores"

Para probar su funcionamiento se emplea lo siguiente:

maginot:/etc/nut# /sbin/upsdrvctl start
Network UPS Tools - UPS driver controller 2.0.4
Network UPS Tools: New USB/HID UPS driver 0.28 (2.0.4)

Detected a UPS: American Power Conversion/Smart-UPS 1000 RM FW:616.3.I USB
FW:8.1
Using subdriver: APC/CyberPower HID 0.9
maginot:/etc/nut#

Cuando todo ha ido bien el programa pasa a segundo plano, y en caso de encontrar errores emitirá mensajes más o menos descriptivos de la situación. Puede ser necesario seleccionar otro controlador, modificando el archivo, ó verificar que tenemos permisos de acceso al dispositivo.

Para detenerlo emplearemos:

# /sbin/upsdrvctl stop
Network UPS Tools - UPS driver controller 2.0.4
Stopping UPS: servers
maginot:/etc/nut#

Configuración del interlocutor

El programa upsd sirve de pasarela de datos entre los controladores de las UPS y los clientes, incluyendo los monitores de estado (upsmon).

El control de acceso al mismo se efectúa dentro del archivo /etc/nut/upsd.conf, y consiste en crear listas de acceso ACL y permitir ó denegar acceso a las mismas.

En mi caso he creado un ACL para la red local y le he dado permiso de acceso a la UPS.

ACL all 0.0.0.0/0
ACL localhost 127.0.0.1/32
ACL localnet 192.168.0.0/24

ACCEPT localhost
ACCEPT localnet
REJECT all

Definiendo usuarios

El archivo /etc/nut/upsd.users se emplea para crear usuarios y asignarles privilegios de acceso a la UPS.

Para crear un administrador, por ejemplo, se le abre una sección como ésta:

[myadmin]
    password: XXXXXX
    allowfrom       = localnet
    actions         = SET
    instcmds        = ALL
    upsmon  master

La documentación (ver la página de manual de upsd.users) explica bastante bien las opciones; únicamente resalto aquellas que más me han interesado:

  • La claúsula allowfrom hace referencia a los ACL desde los que puede conectarse el usuario.
  • La claúsula upsmon indica si el usuario puede emplearse desde el programa de monitorización. Es conveniente en este caso definir un usuario con menos privilegios para ello que un administrador.

Verificando la instalación

Tras arrancar los demonios de control de NUT, en Debian mediante /etc/init/nut start, y no encontrar fallos en el proceso, procedemos con los siguientes comandos para verificar que funciona:

victor@maginot:~ $ upsc servers@maginot ups.status
OL

La respuesta OL significa on line y es la que indica que todo va bien; otras respuestas pueden ser OB (on battery) y LB (low battery), y eso significa que hay algo incorrecto con el controlador seleccionado. Es mejor detener el controlador con upsdrvctl stop, seleccionar otro y repetir la secuencia.

Para obtener todos los parámetros de la UPS empleamos una orden parecida:

victor@maginot:~ $ upsc servers@maginot
battery.charge: 100
battery.charge.low: 10
battery.charge.warning: 50
battery.mfr.date: 2006/08/10
battery.runtime: 600
battery.runtime.low: 120
battery.temperature: 33
battery.type: PbAc
battery.voltage: 27.3
battery.voltage.nominal: 24.0
driver.name: newhidups
driver.parameter.port: auto
driver.version: 2.0.4
driver.version.data: APC/CyberPower HID 0.9
driver.version.internal: 0.28
input.voltage: 224.6
output.voltage: 224.6
output.voltage.target.line: 230.0
ups.beeper.status: enabled
ups.delay.shutdown: -1
ups.firmware: 616.3.I
ups.firmware.aux: 8.1
ups.load: 57.2
ups.mfr: American Power Conversion
ups.mfr.date: 2006/08/10
ups.model: Smart-UPS 1000 RM
ups.serial: AS0633111517
ups.status: OL
ups.test.result: No test initiated
victor@maginot:~ $

Monitorización esclava

Si un ordenador está alimentado por la UPS, pero no se comunica con ella, debe tener al menos instalado el monitor en modo slave, de manera que pueda reaccionar frente a los sucesos que le ocurran a ésta.

Definimos a la máquina que tiene conexión directa con la UPS como maestra, y a las demás como esclavas, y efectuamos lo siguiente:

  1. En la máquina maestra creamos un acceso (usuario, contraseña y privilegios) al demonio upsd, en el archivo /etc/nut/upsd.users:

    [upsmon]
        password    = XXXXX
        allowfrom   = localnet
        upsmon      slave
    
  2. En la máquina esclava, tras instalar únicamente el paquete nut, configuramos el programa upsmon con una entrada en su archivo /etc/nut/upsmon.conf tal como esta:

    MONITOR servers@maginot 1 upsmon XXXXX slave
    

    En la que le indicamos que está siendo alimentado por la UPS llamada servers@maginot, y que debe conectarse a ella con el usuario upsmon en modo esclavo.

  3. Reiniciamos ambos servicios, tanto en la máquina maestra como en la esclava, y verificamos en los registros del sistema que todo haya ido bien:

    # tail /var/log/daemon.log
    ...
    Jul 24 11:16:07 alejandria upsmon[3249]: Startup successful
    ...
    

[!] upsd escucha por defecto en el puerto 3493/tcp, así que si existen cortafuegos activos será necesario retocarlos para permitir este tipo de conexiones.

Apagado del sistema

Fallo en la alimentación eléctrica

La secuencia de hechos ante un fallo de alimentación es la siguiente:

  1. La UPS comienza a alimentar desde la batería.
  2. La batería se descarga hasta que alcanza el nivel crítico.
  3. El programa upsmon maestro recibe el evento desde el demonio upsd y activa el indicador FSD (forced shutdown ó cierre forzoso) en la UPS para indicar a todos los monitorizadores en modo esclavo que en breve se perderá la energía.
  4. Los monitorizadores esclavos verán dicho indicador y harán lo siguiente:
    1. Generan un evento NOTIFY_SHUTDOWN.
    2. Esperan los segundos indicados por la variable FINALDELAY (generalmente 5).
    3. Ejecutan el programa de cierre indicado en la variable SHUTDOWNCMD.
    4. Se desconectan de la UPS (del demonio upsd) cuando el proceso init les envía la señal de cierre.
  5. El monitorizador maestro espera unos segundos (indicados en la variable HOSTSYNC que suele contener 15) a que todos los monitorizadores esclavos se desconecten de la UPS. Si pasado este tiempo quedan algunos conectados upsmon continúa con el cierre del sistema y los ignora.
  6. El proceso de cierre en el sistema maestro lo realiza el programa upsmon y es el siguiente:
    1. Genera el evento NOTIFY_SHUTDOWN.
    2. Espera los segundos indicados por la variable FINALDELAY (generalmente 5).
    3. Crea el archivo indicador contenido en la variable POWERDOWNFLAG (normalmente es /etc/killpower).
    4. Ejecuta el programa de cierre indicado en la variable SHUTDOWNCMD.
  7. En la mayor parte de los sistemas el proceso init debe tomar el control en esta parte, matar a los procesos, sincronizar y desmontar los sistemas de archivos y montar algunos como sólo lectura.
  8. Si se configura adecuadamente init debería en este punto invocar a nuestro programa especial de cierre, el cuál comprobará la existencia del archivo indicador y enviará la orden de cierre a la propia UPS, posiblemente empleando el programa upsdrvctl.
  9. La UPS corta la alimentación y el tiempo transcurre.
  10. La energía eléctrica vuelve y la UPS se enciende de nuevo.
  11. Las máquinas reciben alimentación y reinician.

[!] Estos dos últimos pasos son algo más comlicados de efectuar, y en mis sistemas aún no he conseguido que sea así, dadas las diferentes BIOS de que disponen.

Disposiciones

Esta es la parte más importante de todas; sin ella las UPS sólo retrasarán unos minutos la caída y el fallo de las máquinas que alimentan.

Una vez tengamos en marcha el monitorizador maestro (upsmon) y los esclavos, el controlador de la UPS y el interlocutor de datos (upsd), procedemos con lo siguiente:

  1. En las máquinas bajo monitorización podemos definir un archivo a modo de indicador que será creado por upsmon en caso de cierre forzoso. Dicho archivo debería estar en un sistema de archivos montado cuando los programas de cierre del sistema estén funcionando, o no servirá de nada.

    La directiva que debe añadirse al archivo /etc/nut/upsmon.conf es:

    POWERDOWNFLAG   /etc/killpower
    
  2. Modificamos los programas de cierre de sistema de manera que tengan en cuenta este archivo, y de esta forma sepan distinguir entre un cierre normal y uno provocado por las prisas del inminente corte de energía.

    Un ejemplo podría incluír el apagado hardware de la UPS empleando el programa /usr/bin/upsdrvctl:

    if [ -f /etc/killpower ]; then
        /usr/bin/upsdrvctl shutdown
    fi
    

No es necesario borrar este archivo durante el arranque del sistema. upsmon se encargará de ello en cuanto tenga oportunidad.

Testeo

Probar el cierre ordenado de un sistema es un tanto complicado, y no existen demasiadas ayudas para ello.

El programa upsdrvctl ofrece una opción que puede ayudar un poco; se trata del parámetro -t y da el siguiente resultado cuando se le invoca:

    maginot:~# upsdrvctl -t shutdown
    Network UPS Tools - UPS driver controller 2.0.4
    *** Testing mode: not calling exec/kill
    exec: /lib/nut/newhidups -a servers -k

Situaciones especiales

Carreras

¿ Qué ocurre cuando vuelve la energía y aún estamos en la fase de cierre de sistemas ? Esto es lo que el autor de NUT llama enery race y da algunas indicaciones en la documentación sobre cómo las encara.

PENDIENTE DE COMPLETAR

Funcionando dentro de un chroot

El punto débil de NUT son los controladores, los programas que se comunican con las UPS; deben estar actualizados para impedir fallos de comunicación, como los que se puede encontrar en la rama '2.0' con los dispositivos USB, que echen abajo el sistema al completo, dado que si no sabemos nada del dispositivo todo lo demás sobra.

Mis servidores funcionan con la rama estable de Debian y no me gusta emplear versiones backport si puedo evitarlo, así que hace poco me he encontrado con un problema grave que he resuelto empleando un entorno cerrado (chroot), y algunos programas que he escrito a propósito.

La versión de NUT en Debian Etch era la 2.0.4 y para gestionar una UPS APC Back-UPS RS 1000 tenía que emplear el controlador newhidups, el cual moría una decena de veces al día por un fallo de segmentación, lo que me obligaba a reiniciarlo manualmente por un lado, y a suprimir cualquier mensaje alarmista por otro dadas las quejas de los usuarios, que no sabían a qué atenerse con ello.

La primera medida que tomé fue cederle el control de ejecución a monit, y todo funcionó más o menos bien durante unas semanas hasta que empecé a ver un mensaje como este

usb 1-8: usbfs: process 4312 (newhidups) did not claim interface 0 before use

inundando los registros del sistema. Y lo peor era que el proceso se multiplicaba en memoria y monit no era capaz de gestionar nada.

Viendo que en la versión inestable de Debian el problema de los fallos de segmentación se solucionaba, y que intentar emplear una versión backport no era práctica, pues se necesitaban versiones muy superiores de librerías básicas del sistema, me decidí a emplearla.

Para ello he completado los siguientes pasos:

  1. Construir un entorno cerrado con schroot.
  2. Instalar el software base de una rama Debian Sid, entrar en sesión, instalar el paquete nut y salir del chroot.
  3. Montar algunos directorios especiales como /var/run/nut y /proc/bus/usb.
  4. Copiar la configuración de NUT en el chroot.
  5. Arrancar los programas en el entorno Debian Sid desde el entorno Debian Etch:

    # chroot -c sid /etc/init.d/nut start
    

Pero dado que es bastante engorroso hacerlo a mano lo he automatizado con un par de programas.

  • nut-chroot-setup es el encargado de preparar el entorno.
  • nut-chroot-ctl invoca al programa /etc/init.d/nut dentro del chroot, y es muy útil para emplearlo con monit sin más cambios que las opciones que definen los programas que inician y terminan el servicio.

Hasta ahora no he tenido problemas con el controlador, se le puede llamar desde el cliente con versión 2.0 sin inconvenientes y el resto de la red no ha notado nada más que una mayor información desde la UPS.