Creative Commons License
Excepto donde se indique otra cosa, todo el contenido de este lugar está bajo una licencia de Creative Commons.
Taquiones > sysadmin > Monitorizando servicios: monit

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 lectura read-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 orden D, C, B y A.
  • Si todos los servidores están en marcha y se intentan detener todos, monit lo hará en el orden A, B, C y D. Algo que también sucederá en el caso de querer detener el D dado que los demás dependen de él.
  • Si A no está funcionando monit lo pondrá en marcha.
  • Si B no está funcionando, primero se detendrá A, después se pondrán en marcha B y A.
  • Si C está parado, primero se detendrán A y B, y se iniciarán C, B y A.
  • Si es D el detenido primero se pararán A, B y C y luego se pondrán en marcha D, C, B y A.

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

PENDIENTE DE COMPLETAR

Efectuando tests

PENDIENTE DE COMPLETAR

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:

  1. Iniciar los servicios críticos directamente desde monit, eliminándolos de la secuencia de arranque habitual del sistema.
  2. Hacer que init espere a que el servicio esté disponible usándo la acción wait de la entrada en inittab.
  3. 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á a monit 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.

  1. 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 es python) y la opción -P 1 recupera aquellos que son hijos directos de init (que tiene el PID 1).

  2. Cambiamos la configuración de monit para que llame a este programa en lugar del programa original del paquete.

  3. 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