- Monitorizando servicios: monit
- Configuración
- Opciones generales
- Control de acceso
- Servicios a controlar
- Directivas de los servicios
- pidfile
- path
- group
- start
- stop
- pid, ppid
- uid, gid
- host
- port
- type
- certmd5
- proto(col)
- request
- send/expect
- unix(socket)
- URL
- content
- timeout N seconds
- timeout
- alert
- noalert
- restart, stop, unmonitor, start, exec
- mail-format
- checksum
- expect
- timestamp
- changed
- every
- mode
- cpu
- mem
- loadavg
- children
- totalmem
- space
- inode(s)
- perm(ission)
- size
- depends (on)
- Agrupando servicios
- Estableciendo dependencias
- Configuración de alertas
- Efectuando tests
- Uso y disfrute
- Enlaces
- Configuración
Monitorizando servicios: monit
El programa monit sirve para efectuar un control sobre el funcionamiento de los servicios en una máquina.
Una vez configurado y puesto en marcha se encarga de efectuar periódicamente chequeos sobre dichos servicios y, si encuentra que no están activos, los intenta poner en marcha, es decir, puede actuar de varias formas para resolver la situación e informar sobre ello al administrador con un formato muy flexible en cualquier caso.
Además de procesos, monit puede también controlar:
- Características de procesos: consumo de memoria, ciclos de cpu y estados especiales como el zombie.
- Archivos, directorios y dispositivos en la máquina local, con verificaciones sobre los cambios en las marcas de tiempo, el contenido (mediante checksums) y/ó el tamaño.
- Verificar que máquinas remotas (como servidores de bases de datos ó de aplicaciones) están vivos y responden.
- En sentido general, también controla el consumo total de cpu, memoria y carga de trabajo de todo el sistema.
Una desventaja de este comportamiento es que si deseamos detener un servicio
bajo su control, utilizando el clásico /etc/init.d/servicio stop
nos
encontraremos con que un tiempo después el servicio vuelve a estar activo. O
bien paramos al controlador, ó bien le indicamos que deje el servicio en paz.
Para hacer esto último tenemos dos posibilidades:
- Acceder al servidor web que proporciona
monit
y detener la monitorización a golpe de ratón. - Usarlo desde la consola.
Configuración
En Debian el archivo principal se encuentra en /etc/monit/monitrc
y
dentro de él podemos diferenciar varias partes concretas.
El archivo sigue la habitual síntaxis tan propia de GNU/Linux en la que los
comentarios comienzan con un carácter almohadilla (#
), las líneas están en
formato libre y está completamente orientado a tokens sintácticos. Entre
éstos se encuentran las cadenas de caracteres, que pueden ir encerradas
entre dobles comillas (y contener espacios en blanco), ó directamente
inscritas hasta el siguiente espacio en blanco.
Existe una lista de palabras inglesas que pueden utilizarse dentro de las estrofas de configuración, con objeto de hacerlas más legibles, pero que son ignoradas por completo por el programa. Estas son:
is, as, are, on(ly), with(in), and, has, using, use, the, sum, program(s),
than, for, usage, was, but
Opciones generales
Las opciones generales comienzan por la palabra set
seguida del elemento a
definir.
set daemon
Establece el intervalo de muestreo en segundos para el segundo plano (background).
set init
Indica que monit
va a funcionar desde el programa init
y que no debe
convertirse en demonio.
set logfile
Define el archivo sobre el cual registrar los errores y eventos durante su
funcionamiento. La palabra syslog
activa el uso del
registro del sistema.
set mailserver
Nombre del servidor de correo a través del cual enviar las notificaciones. En
caso de ausencia se intentará con la máquina local (localhost
), y es posible
definir más de uno como secundarios en caso de fallo.
set mail-format
Define el formato global para todos los mensajes de alerta enviados por el programa.
set pidfile
Define el archivo donde se registrará su identificador de proceso.
set statefile
Define el archivo donde monit
guardará su estado. Si no se incluye se
utilizará $HOME/.monit.state
.
include
Define una expresión de nombres de archivo de configuración que serán cargados y analizados.
Control de acceso
Una vez puesto en marcha como demonio monit
tiene un servidor web interno
que permite controlarlo y/ó comprobar el estado de los servicios.
También se accede a este servidor cuando se usa el programa en modo manual, es decir, desde la consola, por lo que el control de acceso es aplicable en este caso.
monit
proporciona dos esquemas de control de acceso que pueden usarse
juntos ó por separado, pero es obligatorio definir al menos uno, y como es
posible añadir una capa SSL se puede contar como un tercero.
Ante cualquier fallo en los métodos de control de acceso se crea un registro con la información de acceso habitual.
Lista de máquinas y redes
En el caso de máquinas (hosts) monit
admite tanto direcciones IP como
nombres de red, siempre que éstos resuelvan correctamente. En el caso de redes
se usan direcciones de red junto a una máscara.
Autentificación básica
Este esquema es propio del protocolo HTTP y está descrito en el 2617, por lo que no hay nada especial en él. El servidor solicita al cliente
que envíe un nombre de usuario y una contraseña que utiliza para validar el
acceso. Ambos valores son enviados como texto en claro, por lo que se sugiere
una conexión segura con monit
antes de usarla.
Se puede ...
- Especificar archivos en formato htpasswd].
- Especificar pares usuario-contraseña directamente.
- Marcar usuarios como sólo lectura.
Y se debe tener en cuenta que ...
- Si
monit
se utiliza desde la consola es obligatorio definir al menos un par usuario-contraseña en el archivo de configuración; mejor si es el primero. - El cliente
monit
usará el primer par usuario-contraseña que encuentre definido en la configuración, por lo que es importante que no sea de sólo lectura si se pretende cambiar algo.
set httpd port
Activa el servidor web en el puerto indicado (port).
ssl enable
Habilita el soporte SSL
en el servidor web.
ssl disable
Quita el soporte SSL
en el servidor web, y es equivalente a no incluir la
directiva anterior.
pemfile
Define el certificado SSL
que utilizará el servidor.
clientpemfile
Define el certificado a utilizar con el cliente cuando se deba verificar.
address
Esta directiva permite especificar la dirección IP en la cual debe escuchar el
servidor web de monit
.
allow
Esta claúsula, que puede aparecer varias veces, define una condición para tener acceso al servidor. El orden es importante, aunque no vital.
Puede incluir ...
Un par
usuario:contraseña
seguido por un indicador opcional de sólo lecturaread-only
.allow victor:passwd
Un archivo en formato htpasswd] con los usuarios y sus contraseñas de acceso. Si está cifrado es obligatorio indicar antes el algoritmo utilizado (
cleartext
,crypt
,md5
). A continuación se pueden decir qué usuarios de dicho archivo están autorizados.allow md5 /etc/http/passwd victor juan
Servicios a controlar
Los servicios se definen mediante la palabra check
y se dispone de seis
tipos distintos, más un tipo especial que referencia a todo el sistema.
Si el test de cualquiera de ellos falla, monit
intentará resolverlo
ejecutando el contenido de la claúsula start
si existe. En caso contrario ó
si monit
está funcionando en modo pasivo se limitará a avisar del hecho;
si se diese el caso de estar funcionando en modo activo y no tener una
claúsula start
ó no poder cumplirla, se desactivará la monitorización sobre
el servicio.
Programas
check process <nombre_único> pidfile <ruta_al_archivo_pid>
El servicio se considerará cáido si el archivo PID indicado no existe ó no contiene un identificador de proceso correcto.
Archivos
check file <nombre_único> path <ruta_al_archivo>
La ruta al archivo debe ser absoluta. Si no existe ó desaparece se ejecutará la acción de start
, y si no apunta a un archivo regular se desactivará su monitorización.
Tuberías
check fifo <nombre_único> path <ruta_al_archivo_tubería>
Igual que para el control de archivos, pero tratándose de una tubería (pipe).
Dispositivos
check device <nombre_único> path <ruta_al_dispositivo>
La ruta señala a un dispositivo de bloques, un punto de montaje ó un archivo ó directorio dentro del mismo. Es recomendable utilizar un dispositivo, porque basta con que exista el punto de montaje (aunque no haya nada montado) para que el test sea positivo.
Directorios
check directory <nombre_único> path <ruta_al_directorio>
Igual que para los archivos pero tratándose de un directorio.
Máquinas en red (hosts)
check host <nombre_único> address <dirección_de_red>
La dirección de red puede indicarse con un nombre completamente cualificado ó una dirección IP estándar.
El sistema sobre el que funciona
check system <nombre_único>
Ideado para controlar parámetros globales del sistema en el que está funcionando.
Configuración para programas concretos
Tengo reunida una colección de servicios para monit, a emplear en un sistema Debian, y agrupados en servicios concretos que pueden emplearse como punto de partida para una configuración normal.
La otra fuente importante de archivos de ejemplo está dentro del wiki de monit.
Directivas de los servicios
Dentro de las definiciones de servicios existen bastantes parámetros que son
los que proporcionan versatilidad a monit
.
pidfile
Especifica la ruta del archivo PID que todo proceso controlado por monit
debe tener. Sólo debería utilizarse con check process ...
.
path
Especifica la ruta del archivo, directorio, tubería ó dispositivo que hay que controlar.
group
Etiqueta el servicio dentro de un grupo (por nombre).
start
Determina el programa (ruta absoluta) a utilizar para levantar el servicio ó crear el recurso. En el caso de indicar un script éste debe comenzar por #!
y seguir por un intérprete para ejecutarlo.
Es posible indicar una línea shell concreta usando algo como
start="/bin/bash -c 'echo $$ > pidfile; exec program'"
stop
Idem que start
pero sirve para detener el servicio.
pid, ppid
These keywords may be used as standalone statements in a process service entry to override the alert action for change of process pid and ppid.
uid, gid
These keywords are either 1) an optional part of a start, stop or exec statement. They may be used to specify a user id and a group id the program (process) should switch to upon start. This feature can only be used if the superuser is running monit. 2) uid and gid may also be used as standalone statements in a file service entry to test a file's uid and gid attributes.
host
Nombre ó dirección IP de la máquina del servicio a controlar; se usa junto a
port
y su valor predeterminado es localhost
.
port
Número de puerto TCP/IP en el cual escucha el servicio que estamos
controlando. Si no va precedido por un host
se usará localhost
.
type
Determina el tipo de conexión (socket type) a utilizar cuando verifique la conectividad en un puerto. El valor predeterminado es tcp
y puede contener los valores udp
, tcp
y tcpssl
.
certmd5
La suma comprobatoria (md5
) del certificado que un servidor SSL
tiene que despachar.
proto(col)
Tipo de servicio que vamos a encontrar en el puerto. monit
actualmente
sabe cómo hablar los siguientes dialectos: HTTP
, SMTP
, FTP
, POP
,
IMAP
, MYSQL
, NNTP SSH
, DWP
, LDAP2
, LDAP3
, RDATE
, NTP3
, DNS
,
POSTFIX-POLICY
, APACHE-STATUS
, TNS
, PGSQL
y RSYNC
.
Si no se especifica el protocolo se utilizará un test simple que suele ser suficientemente bueno para determinar si el servicio está o no vivo.
request
Especifica una petición a efectuar al servidor y debe aparecer tras la cláusula anterior. Por el momento sólo contempla según el servicio:
HTTP
: una URL y un texto opcional a usar como parámetros de consulta.
send/expect
Incompatibles con la claúsula protocol
, especifica una cadena a enviar y
otra a recibir (ambas opcionales y usando expresiones regulares) en la
conexión con el servicio a comprobar.
unix(socket)
Especifica un conector unix (unix socket) a utilizar para verificar el servicio. Se utiliza de manera análoga a port
.
URL
monit
empleará su valor para testear la conexión con el servicio.
content
Indica una expresión regular a testear con el contenido devuelto por el servicio, usando la claúsula anterior URL
.
timeout N seconds
Especifica el tiempo límite (en segundos) de espera en la apertura y lectura de la conexión. El valor predeterminado es 5 segundos, y si no consigue la conexión en ese tiempo da el test por fallido.
timeout
Define el tiempo límite para un servicio utilizando dos dígitos: el primero es el número máximo de reinicios para el servicio, mientras que el segundo es el intervalo entre comprobaciones de reinicio.
alert
Determina la dirección de correo electrónico a la cual enviar alertas.
noalert
Especifica una dirección de correo electrónico que no quiere recibir ninguna alerta. Util si queremos excluir a un destinatario en un servicio concreto, ó ante un fallo determinado.
restart, stop, unmonitor, start, exec
Acciones a efectuar cuando un test se cumple en un servicio. La acción exec
es especial porque require un parámetro adicional con el programa a ejecutar,
y opcionalmente puede ir con una claúsula para definir el usuario (uid
) y/ó
el grupo (gid
) con el que ejecutarlo.
mail-format
Define un formato con el que construir el mensaje de alerta. Es parte opcional
de la claúsula alert
.
checksum
Indica que monit
debería calcular y comprobar una suma de comprobación
(md5
ó sha1
) del contenido de un archivo, por lo que sólo es válida en
este tipo de recursos.
expect
Indica el valor de la suma de comprobación que debería esperarse al controlar un archivo con la claúsula anterior.
timestamp
Indica la marca de tiempo para un archivo ó un directorio. Pueden incluirse varias claúsulas de este tipo.
changed
Es parte de la claúsula anterior y sirve para efectuar comprobaciones sobre cuánto tiempo hace del cambio en el archivo ó directorio.
every
mode
cpu
mem
loadavg
children
totalmem
space
inode(s)
perm(ission)
size
depends (on)
Agrupando servicios
Los servicios pueden ser agrupados bajo un nombre común y, de esta forma, arrancados y detenidos en una sola operación.
En las entradas de definición de servicios incluímos una claúsula como
GROUP nombre_del_grupo
(en mayúsculas, ojo) para indicar que el servicio pertenece al grupo.
Cuando queremos manipular un grupo directamente añadimos el parámetro -g
nombre_de_grupo
a la llamada a monit
:
# monit -g nombre_del_grupo start
# monit -g nombre_del_grupo stop
Estableciendo dependencias
monit
puede efectuar un chequeo de dependencias antes de iniciar ó detener
un servicio ó su monitorización. Para declararlas existe una claúsula especial
que puede indicarse dentro de cada definición de servicio:
DEPENDS ON servicio [, servicio ...]
siendo servicio el nombre de la entrada que lo define (de libre elección mientras sea único).
En el caso de actuar sobre un servicio, si éste tiene dependencias de otros, se efectuará primero sobre ellos antes que sobre el primero, de tal manera que si en algún punto de la cadena de dependencias se produce una acción, ésta será transmitida hacia arriba hasta el primero.
Tenemos por ejemplo la siguiente definición
check process apache
with pidfile "....."
...
depends on httpd
check file httpd with path "...."
if failed checksum then unmonitor
que hará que si queremos iniciar el servicio con monit start apache
,
primero se comprobará el servicio httpd
y si falla la suma de
comprobación del contenido (porque ha sido modificada), se desactivará la
monitorización de éste y luego del servicio apache
, puesto que se propaga
hacia arriba del árbol de dependencias. La única excepción a esto es la acción
exec
.
La documentación incluye un ejemplo muy educativo; se asume una instalación típica en la cual exista el siguiente árbol de dependencias:
Servidor-Web --> Servidor-de-aplicaciones --> Base-de-datos --> Archivos
(A) (B) (C) (D)
en el cual podemos ver que antes de levantar el servidor web debemos tener en marcha el servidor de aplicaciones, y antes que éste el servidor de bases de datos , el cual depende de un sistema de archivos.
monit
seguirá el siguiente algoritmo para tratar con ello:
- Si no hay ningún servidor funcionando
monit
los pondrá en marcha en el ordenD
,C
,B
yA
. - Si todos los servidores están en marcha y se intentan detener todos,
monit
lo hará en el ordenA
,B
,C
yD
. Algo que también sucederá en el caso de querer detener elD
dado que los demás dependen de él. - Si
A
no está funcionandomonit
lo pondrá en marcha. - Si
B
no está funcionando, primero se detendráA
, después se pondrán en marchaB
yA
. - Si
C
está parado, primero se detendránA
yB
, y se iniciaránC
,B
yA
. - Si es
D
el detenido primero se pararánA
,B
yC
y luego se pondrán en marchaD
,C
,B
yA
.
monit
emitirá un error y terminará su ejecución si encuentra una
dependencia recursiva (como A --> B
y B --> A
) ó si se hace referencia a
un servicio que no está definido.
Configuración de alertas
Efectuando tests
Uso y disfrute
Funcionando desde init
El hecho de que sea el proceso init
el que ponga en marcha a monit
es la
opción más segura (por lo probado del sistema) para tenerle funcionando en un
sistema.
Conviene tomar algunas precauciones antes de decidirse por esta opción:
- El archivo de configuración no debe tener errores sintácticos ó lógicos de ningún tipo.
- Los programas de arranque del sistema no deben poner en marcha de nuevo a
monit
.
Se debe usar la opción de configuración set init
ó el parámetro de llamada
-I
e incluir una línea al estilo de
# Run monit in standard run-levels
mo:2345:respawn:/usr/bin/monit -Ic /etc/monitrc
en el archivo /etc/inittab
y reiniciar init
(con algo como telinit q
).
Si monit
se emplea en controlar servicios que también son iniciados
durante el arranque normal del sistema puede ocurrir una condición de
carrera entre los
mismos; por ejemplo, si un servicio es de arranque lento, monit
puede
pensar que no está funcionando e intentar ponerlo en marcha él mismo, a pesar
de que es posible que ya está funcionando ó en su secuencia inicial, con el
consiguiente aviso al administrador y la confusión resultante.
La FAQ explica que hay algunas técnicas para prevenir estas situaciones:
- Iniciar los servicios críticos directamente desde
monit
, eliminándolos de la secuencia de arranque habitual del sistema. - Hacer que
init
espere a que el servicio esté disponible usándo la acciónwait
de la entrada eninittab
. Habilitar la monitorización manual del servicio desde el propio
monit
, con un truco un tanto extraño pero que puede funcionar:check file myprocess.pid with path /var/run/myprocess.pid if timestamp > 5 minutes then exec "/bin/bash -c ' /usr/bin/monit -c /etc/monitrc monitor myprocess; /usr/bin/monit -c /etc/monitrc unmonitor myprocess.pid '" check process myprocess with pidfile /var/run/myprocess.pid start program = "/etc/init.d/myprocess start" stop program = "/etc/init.d/myprocess stop" alert foo@bar.baz mode manual
es decir, se crea un servicio que controla un archivo y se establece que hasta que no pasen cinco minutos desde su última actualización (
timestamp
) no se le indicará amonit
que comienced a monitorizar el servicio real, y que se olvide de controlar el fichero.Para ello se ha tenido que indicar en la entrada del servicio que éste es de tipo manual.
Acceso desde consola
Si se recibe el siguiente mensaje de error cuando se invoca a monit
desde la
consola
Cleattext credentials needed for basic authorization!
es debido al tipo de acceso configurado al servidor web.
Una vez logrado el susodicho acceso se pueden hacer muchas cosas con los servicios, tales como solicitar un sumario general
# monit summary
The monit daemon 4.8.1 uptime: 4m
Process 'apache' running
Process 'sshd' running
Process 'named' running
Process 'exim4' not monitored
Process 'clamavd' Execution failed
Process 'slapd' running
Process 'fail2ban' Execution failed
Process 'dovecot' running
System 'daga.taquiones.net' running
#
ó pedir un listado completo del estado de cada uno de los servicios controlados:
# monit status
The monit daemon 4.8.1 uptime: 4m
Process 'apache'
status running
monitoring status monitored
pid 5419
parent pid 1
uptime 18h 5m
childrens 10
memory kilobytes 2320
memory kilobytes total 49628
memory percent 0.9%
memory percent total 20.9%
cpu percent 0.0%
cpu percent total 0.0%
port response time 0.003s to 127.0.0.1:80 [HTTP via TCP]
data collected Wed Jul 11 09:31:04 2007
...
System 'daga.taquiones.net'
status running
monitoring status monitored
load average [0.12] [0.41] [0.26]
cpu 21.0%us 1.5%sy 0.0%wa
memory usage 62020 kB [26.1%]
data collected Wed Jul 11 09:31:06 2007
#
Y si necesitamos alterar su funcionamiento sin reiniciarlo, utlizando la siguiente llamada
# monit stop exim4
#
conseguimos detener el servicio de correo y la monitorización sobre él (por
ejemplo). Esto afecta también a aquellos servicios que hemos definido como
dependientes de exim4
.
Sí sólo deseamos parar la vigilancia sobre el servicio, sin detenerlo, debemos emplear
# monit unmonitor exim4
#
que hace lo mismo pero sin pararlo.
Y además tenemos la posibilidad de actuar sobre grupos de servicios, de
verificar la configuración (monit validate
), de releerla (monit reload
) ó
de matar al proceso demonio (monit kill
).
Si no tenemos archivo PID
El programa monit
exige que todos los servicios a controlar (procesos
tendríamos que decir) dispongan de un archivo PID
real, es decir, con el
identificador del proceso dentro.
Si uno de nuestros servicios no crea un archivo de este tipo, como es el caso de fail2ban en Debian Etch, tendremos que ingeniárnoslas para que disponga de uno.
Creamos un archivo de inicio nuevo como
/etc/init.d/fail2ban-pid
con el siguiente contenido (es un ejemplo, real, pero ejemplo):#!/bin/sh PIDFILE=/var/run/fail2ban.pid case $1 in start) /etc/init.d/fail2ban start /usr/bin/pgrep -f -P 1 fail2ban-server > $PIDFILE ;; *) /etc/init.d/fail2ban $1 ;; esac
Es de destacar el uso del programa
pgrep
del paquete procps para encontrar el proceso adecuado. La opción-f
hace que se busque en toda la línea de llamada (el proceso en realidad espython
) y la opción-P 1
recupera aquellos que son hijos directos deinit
(que tiene el PID 1).Cambiamos la configuración de
monit
para que llame a este programa en lugar del programa original del paquete.Suprimimos el arranque del programa
/etc/init.d/fail2ban
de la secuencia de arranque (a pesar de que el servidor lleva más de un año sin reiniciar).daga:~# update-rc.d -f fail2ban remove Removing any system startup links for /etc/init.d/fail2ban ... /etc/rc0.d/K99fail2ban /etc/rc1.d/K99fail2ban /etc/rc2.d/S99fail2ban /etc/rc3.d/S99fail2ban /etc/rc4.d/S99fail2ban /etc/rc5.d/S99fail2ban /etc/rc6.d/K99fail2ban daga:~#
No es necesario disponer en el arranque que llame al programa envoltorio porque de eso ya se encarga
monit
.
Enlaces
- Documentación de monit
- Monitor Debian servers with monit en el excelente sitio de Steve Kemp.
- Ejemplo de uso con una aplicación concreta
- Archivos de configuración para servicios