Dentro del mundo de la seguridad física, mantener los sistemas protegidos ante desastres naturales, picos de tensión producidos por una señal de corriente poco limpia o porque cae un rayo cerca (oye, que son cosas que pueden pasar…) puede generar que nuestros equipos, tanto los que dan un servicio como los nuestros de casa, sufran graves consecuencias.
Por otra parte, una pérdida repentina de corriente eléctrica, puede derivar en una pérdida de datos, tanto por no haber salvado convenientemente el trabajo, como por una corrupción de datos en los sistemas de ficheros que, repentinamente dejan de disponer de su energía vital.
Para evitarlo, lo mejor a pequeña y gran escala, es utilizar servicios de alimentación ininterrumpida, más conocidos como SAI en español o UPS (Uninterruptible Power System) en inglés.
Por supuesto no es lo mismo provisionar un SAI para suministrar energía de forma secundaria a un datacenter completo, que para un hogar o una pequeña oficina. Para los primeros se suelen disponer de generadores de electricidad usando gas-oil por ejemplo, como de sistemas especiales para limpiar de ruidos la señal eléctrica y proveer de una tensión estable a todos los equipos durante el rato que dure el "apagón". Para el segundo caso, hay alternativas más asequibles y menos aparatosas, que nos permitan dar unos minutos más de vida en caso de apagón.
En mi caso, el SAI que disponía para un servidor y un PC con mi FreeNAS, funcionando 24x7, me dio la sorpresa de pasar a mejor vida la semana pasada. Así pues me tuve que poner a la busca y captura de un nuevo SAI que evite los picos de tensión de la instalación de mi casa que puedan derivar en males mayores, como roturas de fuentes de alimentación y otros componentes enchufados.
Gracias al consejo de mi amigo Juanjo, me decidí por un SAI del fabricante Eaton. En este caso, y ya que va a tener que suministrar corriente al menos a dos máquinas, el que adquirí es de 1200 VA (Voltiamperios). Cuanto mayor sea este valor, mayor cantidad de tiempo y a mayor número de dispositivos, será capaz de suministrar corriente el SAI. El anterior, un Belkin, era de 600VA, lo que normalmente suele ser suficiente para un único PC. El Eaton permite además enchufar cuantas cosas se desee al disponer de enchufes normales y corrientes, por lo que aproveché a enchufar otros cacharros que no afectarán en demasía el consumo de la batería.
Después de una primera carga de 12 horas sin tener nada enchufado en el SAI, me dispuse a averiguar qué capacidades de monitorización ofrecía. Mediante el cable USB suministrado, venía un software propio llamado Eaton-IPP que permite, de forma web, analizar y configurar el equipo. Asimismo permite establecer alarmas, ejecutar comandos, etc,… Bonito es, pero… no todo lo personalizable que a mí me gustaría.
Me puse a investigar en uno de mis sitios favoritos, http://search.cpan.org, qué modulitos Perl existen para poder trastear con un SAI.
En general, el esquema de componentes se intuye sencillo: Tiene que haber un módulo que es capaz de "hablar" con el SAI a través del cable USB. A partir de ahí, alguna herramienta cliente que permita preguntarle cosas al SAI y tomar decisiones según mi propio criterio. Navegando, dí con una página albergada por Eaton con diversas opciones, entre ellas NUT, compatible, al menos en principio, con el módulo Perl UPS-NUT que encontré en CPAN.
Después de pegarme un rato con temas variopintos para hacer que NUT detecte el SAI (importante instalar el paquete nut-hal que es el que incorpora el driver usbhid-ups en /usr/libexec/hald-addon-usbhid-ups), logré hacer que funcionase KNut y upsc, herramienta cliente que es capaz de devolvernos información suficiente sobre cómo está el SAI:
[root@Carmen tmp]# upsc mge@localhost battery.charge: 100 battery.charge.low: 20 battery.runtime: 2102 battery.type: PbAc device.mfr: EATON device.model: Ellipse ECO 1200 device.serial: 000000000 device.type: ups driver.name: usbhid-ups driver.parameter.pollfreq: 30 driver.parameter.pollinterval: 2 driver.parameter.port: auto driver.parameter.vendorid: 0463 driver.version: 2.4.3 driver.version.data: MGE HID 1.18 driver.version.internal: 0.34 input.transfer.high: 264 input.transfer.low: 184 outlet.1.desc: PowerShare Outlet 1 outlet.1.id: 2 outlet.1.status: on outlet.1.switchable: no outlet.2.desc: PowerShare Outlet 2 outlet.2.id: 3 outlet.2.status: on outlet.2.switchable: no outlet.desc: Main Outlet outlet.id: 1 outlet.switchable: no output.frequency.nominal: 50 output.voltage: 230.0 output.voltage.nominal: 230 ups.beeper.status: enabled ups.delay.shutdown: 20 ups.delay.start: 30 ups.firmware: 01 ups.load: 12 ups.mfr: EATON ups.model: Ellipse ECO 1200 ups.power.nominal: 1200 ups.productid: ffff ups.serial: 000000000 ups.status: OL CHRG ups.timer.shutdown: 0 ups.timer.start: 0 ups.vendorid: 0463
El servicio "upsd" se configura para escuchar en el puerto 3493
[root @Carmen tmp]# netstat -tanp |grep -i upsd|grep -v cups tcp 0 0 127.0.0.1:3493 0.0.0.0:* LISTEN 4465/upsd
Contando con el módulo perl UPS-NUT, en mi cabeza sonaba divertido poder monitorizar la carga del SAI para poder actuar como yo considere necesario si éste se descarga completamente. Es decir, para un corte puntual de un breve espacio de tiempo, el SAI es capaz de soportar perfectamente los requerimientos de energía. Sin embargo, si el corte de corriente es de más tiempo, hay que actuar para evitar que existan corrupciones de datos de las aplicaciones más críticas o que utilicen sistemas de ficheros del NAS, por ejemplo.
Además, dado lo que viajo, el hacer que los servidores se apaguen de forma ordenada está muy bien, pero, cuando la energía vuelva, no siempre hay alguien en casa para darle al botón de encendido. Las BIOS de ambos servidores, disponen de una opción que permite, al detectar una fuente de energía, que recuperen el estado anterior. Es decir, que si se han apagado de forma controlada, no se encenderán, y si se han apagado de forma repentina, sí que lo harán, por lo que entonces interesa que se apaguen de golpe, pero mitigando las pérdidas de datos.
Además, dado lo que viajo, el hacer que los servidores se apaguen de forma ordenada está muy bien, pero, cuando la energía vuelva, no siempre hay alguien en casa para darle al botón de encendido. Las BIOS de ambos servidores, disponen de una opción que permite, al detectar una fuente de energía, que recuperen el estado anterior. Es decir, que si se han apagado de forma controlada, no se encenderán, y si se han apagado de forma repentina, sí que lo harán, por lo que entonces interesa que se apaguen de golpe, pero mitigando las pérdidas de datos.
Así, necesitaba que en mi rutina de "apagado", cuando no quede más vida en el SAI, se deshabiliten servicios que utilicen sistemas de ficheros remotos del NAS, máquinas virtuales, etc, etc,… de manera que, aunque se apague solo el servidor, exista el menor número de servicios corriendo y sistemas de ficheros remotos montados para evitar corrupciones de datos.
Sin embargo, imaginemos que, en el impás de tiempo en el que hemos dejado el servidor con lo mínimo esperando a que se apague solo, se restablece el suministro de corriente eléctrica: El SAI empieza a cargar las baterías de nuevo y nos quedamos con el servidor pletórico de vitalidad, pero muerto en cuanto a funcionalidad.
Sin embargo, imaginemos que, en el impás de tiempo en el que hemos dejado el servidor con lo mínimo esperando a que se apague solo, se restablece el suministro de corriente eléctrica: El SAI empieza a cargar las baterías de nuevo y nos quedamos con el servidor pletórico de vitalidad, pero muerto en cuanto a funcionalidad.
Para haceros la historia corta, no he logrado hacer un programa que funcione de forma correcta con el módulo perl UPS-NUT. No me devuelve ni un solo valor…
Menos mal que el comando anterior upsc permite pedir diferentes valores al SAI en modo línea de comandos.
Menos mal que el comando anterior upsc permite pedir diferentes valores al SAI en modo línea de comandos.
[root@Carmen tmp]# upsc mge@localhost ups.status OL CHRG [root@Carmen tmp]# upsc mge@localhost battery.charge 100 [root@Carmen tmp]# upsc mge@localhost ups.load 12
Finalmente me hice mi propio monitor de SAI como otro script más en perl,… total uno más corriendo en el servidor, no se va a notar.
Entre otras cosas, además monitorizo la relación entre el voltaje saliente actual y el nominal, de manera que me notifique en el caso que haya una sobretensión o una caída de tensión... No vale para mucho si no estás cerca, pero puede permitir la detección de alguna anomalía en el SAI. Una lástima que este equipo no permita monitorizar la temperatura de las baterías puesto que en verano suelen recalentarse y es interesante saber si hay que ir pensando en llamar al 112 o no.
Aquí comparto el script con vosotros, lectores, por si os es de alguna utilidad:
Entre otras cosas, además monitorizo la relación entre el voltaje saliente actual y el nominal, de manera que me notifique en el caso que haya una sobretensión o una caída de tensión... No vale para mucho si no estás cerca, pero puede permitir la detección de alguna anomalía en el SAI. Una lástima que este equipo no permita monitorizar la temperatura de las baterías puesto que en verano suelen recalentarse y es interesante saber si hay que ir pensando en llamar al 112 o no.
Aquí comparto el script con vosotros, lectores, por si os es de alguna utilidad:
[root@Carmen tmp]# more /usr/local/bin/sai_monitor.pl #!/usr/bin/perl #Monitorizando mi SAI my $minutes=10; #num minutos umbral de aguante my $freq_check=60; #num segundos para cada poll my $umbral_load=50; #Umbral de carga de suministro del SAI my $umbral_batt=10; #Umbral de carga de bateria (no retorno) sub agonizando {#Pre-apagado de la máquina cuando el SAI ya no aguanta más #Tiro servicios que dependen de sitios remotos system "/etc/init.d/mldonkey stop"; #Apago el emule #Apago maquinas virtuales de forma ordenada system "/usr/bin/VBoxManage controlvm WXP poweroff"; system "/usr/bin/VBoxManage controlvm pinsafe poweroff"; #Apago servicios en los que requiero integridad system "killall -9 httpd"; #Apago servidor web publico system "/etc/init.d/httpd stop"; #Apago servidor web interno system "/etc/init.d/syslog-ng stop"; #Apago syslog-ng system "/etc/init.d/mysql_chroot stop"; #Apago mysql publico system "/etc/init.d/mysqld stop"; #Apago mysql privado #Desmonto sistema de ficheros remoto NFS para emule almacenado en NAS system "/bin/umount /var/mlnet/temp"; #Desmonto sistema de ficheros Samba almacenados en NAS system "/bin/umount /mnt/samba_remote"; system "/bin/umount /var/backup"; #Apago servicios necesarios para montaje remoto via NFS system "/etc/init.d/rpcidmapd stop"; system "/etc/init.d/rpcgssd stop"; system "/etc/init.d/rpcbind stop"; my $TTL = $minutes * 60; #Calculo segundos a esperar sleep $TTL; #Espero X minutos -> Si aguanta el SAI y no vuelve el suministro de corriente,... #TO DO: Sync en NAS. Aseguro que no hay "clientes" usando ficheros remotos system "reboot"; # Si después de X minutos sigue viva, es que la corriente volvió y la máquina no se apagó sola, así que fuerzo el reinicio para que los servicios de la máquina y sistemas de ficheros vuelvan a la vida de forma limpia y ordenada } #MAIN for (;;) {#bucle infinito my $ups_status = `upsc mge@localhost ups.status`; #print "STATUS ES: $ups_status\n"; if ($ups_status =~ /OB/) {#Significa que estamos con Bateria my $ups_carga = `upsc mge@localhost battery.charge`; #Veamos con cuanta #print "CARGA DE BATERIA ES: $ups_carga\n"; if ($ups_carga < $umbral_batt) {#Hay que actuar #Notifico con alta prioridad system ("/usr/local/bin/notifier.pl 3 \"SAI agonizando. Autodestrucción en 3,2,1. Carga $ups_carga\""); agonizando; #Ejecuto rutina 'agonizando' } } elsif ($ups_status =~ /OL/) {#Significa que está con corriente if ($curr_status != $ups_status) {#Si antes estaba en baterías y ahora con corriente es q se ha recuperado #Notifico nada más con prioridad 2 system ("/usr/local/bin/notifier.pl 2 \"SAI se ha recuperado\""); } } $curr_status=$ups_status; #Guardo estado nuevo de ups my $ups_load = `upsc mge@localhost ups.load`; #print "CARGA DE SUMINISTRO DE SAI ES: $ups_load\n"; #comprobamos carga de suministro del SAI if ($ups_load > $umbral_load) {#Si la carga de suministro del SAI es mayor que lo definido, notificamos system ("/usr/local/bin/notifier.pl 3 \"Carga del SAI es $ups_load\""); } my $ups_current_voltage=`upsc mge@localhost output.voltage`; #voltaje actual my $ups_nominal=`upsc mge@localhost output.voltage.nominal`; #voltaje nominal chomp ($ups_current_voltage); chomp ($ups_nominal); #Calculamos relacion entre voltaje saliente actual y el nominal my $voltaje = ($ups_current_voltage/$ups_nominal) * 100; if ($voltaje > 109) {#Más de 110% entre voltaje actual y nominal: Se detecta sobretensión, notifico system ("/usr/local/bin/notifier.pl 3 \"Sobretensión en el SAI $voltaje%\""); } elsif (($voltaje > 79) && ($voltaje < 86)) {#Si la relacion entre voltaje actual y nominal está entre 80% y 85%, se detecta caída de tensión. Notifico system ("/usr/local/bin/notifier.pl 3 \"Caída de tensión en el SAI $voltaje%\""); } sleep ($freq_check); }
3 comments :
#Apago servicios en los que requiero integridad system "killall -9 httpd"; #Apago servidor web publicoUn poco hardcore ese kill, ¿no? xD
Un poco sí. Pero sin embargo, todo tiene su explicación ;D
Créeme, es correcto y funciona de momento bien así
a mí lo que me ha hecho gracia es ver a alguien usando todavía el mldonkey :D
Publicar un comentario