Monitorización centralizada con M/Monit y Ansible

0
4248

En este tutorial veremos M/Monit para monitorizar aplicaciones distribuidos en varias máquinas de forma centralizada.

Índice de contenidos

1. Introducción

Ya hemos hablado en el tutorial sobre Monit como watchdog configurado con Ansible de la monitorización de las aplicaciones con un watchdog como Monit, que era capaz de informarnos si un servicio estaba disponible, y en caso de que lo no estuviera podía ejecutar acciones de forma autónoma.

Monit nos sirve para monitorizar una máquina, pero ¿qué pasaría si nuestro sistema se compone de dos aplicaciones (A y B) que se ejecutan en dos máquinas diferentes (M1 y M2 respectivamente)? Tendríamos la monitorización de A en M1, y la monitorización de B en M2. Además, tiene la desventaja de que no podemos ver las dos cosas a la vez, y de que en cada máquina configuramos un servidor web para proteger la vista de la monitorización que suele ser útil para el equipo de desarrollo.

Siguiendo este ejemplo, lo que podríamos hacer es tener una tercera máquina (M3) donde instalaríamos M/Monit, que usaría el Monit de las máquinas M1 y M2 como clientes que envían datos a esta última máquina, por lo que el servidor web no tiene que exponer el dashboard de cada aplicación. Además, conseguimos separar la monitorización de las propias aplicaciones, por lo que cada máquina está dedicándose solo a una única cosa (M1 a gestionar la aplicación A, M2 a gestionar la aplicación B y M3 a monitorizar las aplicaciones de ambas).

Una vez entendido el ejemplo, vamos a realizar uno más sencillo para el cual solo necesitamos dos máquinas virtuales:

  • La primera máquina virtual será como en el primer tutorial de Monit: tendrá un Nginx y un Monit que se encarga de monitorizarlo y de arrancar el servicio de forma automática cuando se para.
  • La segunda máquina virtual tendrá M/Monit que recibirá los datos del Monit que está en la primera máquina virtual.

NOTA: Se recomienda encarecidamente leer el tutorial anterior ya que gran parte de los playbook puestos a continuación se explican en el mismo.

NOTA2: En este caso, no haría falta el fichero de configuración que mapea la ruta localhost:8888/monit a localhost:2812 (acceso a la interfaz gráfica de Monit) ya que es justo para eso para lo que creamos la otra máquina, pero lo dejamos para que el paso entre tutoriales sea más cómodo.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro Retina 15′ (2.5 Ghz Intel Core I7, 16GB DDR3).
  • Sistema Operativo: Mac OS El Capitán 10.11.16
  • Vagrant 1.8.1
  • Virtual Box 5.0.14
  • Ansible 2.1.0.0
  • Monit 5.6
  • Nginx 1.4.1

3. Instalación de Vagrant, Virtual Box y Ansible

Antes de ponernos manos a la obra, necesitamos tener Vagrant, Virtual Box y Ansible instalado. En este tutorial explico cómo se instalan estas herramientas. A partir de aquí suponemos que ya tienes esas herramientas instaladas y funcionando actualmente.

4. Creación de las máquinas virtuales

Para definir las reglas de la creación de nuestras máquinas virtuales lo haremos usando Vagrant. Para ello, en el directorio de nuestra elección crearemos el fichero Vagrantfile con la siguiente configuración:

Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|
    config.vm.box = "ubuntu/trusty64"

    config.vm.define "monit" do |monit|
        monit.vm.hostname = "monit"

        monit.vm.network :forwarded_port, host:  2222, guest: 22, id: "ssh"
        monit.vm.network :forwarded_port, host:  8888, guest: 80, id: "nginx"

        monit.vm.network :private_network, ip: "192.168.33.25"
    end

    config.vm.define "mmonit" do |mmonit|
        mmonit.vm.hostname = "mmonit"

        mmonit.vm.network :forwarded_port, host:  2223, guest: 22, id: "ssh"

        mmonit.vm.network :private_network, ip: "192.168.33.26"
    end

    config.vm.provision "ansible" do |ansible|
        ansible.verbose = 'vvv'
        ansible.playbook = "ansible/watchdog_nginx.yml"
    end
end

Como se ve, definimos dos host, monit y mmonit cada uno con una ip privada diferente dentro de la misma red (para que Monit y M/Monit puedan comunicarse) y vemos como tienen redirección de puertos hacia el puerto 22 en las dos máquinas (para aprovisionarlas con Ansible) y en el 80 en la máquina de monit para el Nginx.

Por último tenemos el aprovisionamiento de cada una de las máquinas con Ansible, donde le decimos que nos ejecute el playbook watchdog_nginx.yml.

5. Creación de los roles de Ansible

A continuación nos queda crear los roles de Ansible que vamos a ejecutar cuando se cree la máquina. Para ello dentro del directorio donde tenemos nuestro Vagrantfile y, siendo fieles a la propiedad que hemos establecido en el mismo donde indicábamos el playbook (ansible.playbook = «ansible/watchdog_nginx.yml»), creamos el directorio «ansible» donde guardaremos todos nuestros archivos de Ansible.

5.1. Playbook

El playbook que vamos a ejecutar tiene el siguiente formato:

ansible/watchdog_nginx.yml
---
# file: watchdog_nginx.yml

- hosts: monit
  become: yes
  gather_facts: no
  roles:
      - nginx
      - monit

- hosts: mmonit
  become: yes
  gather_facts: no
  roles:
      - m_monit

Es básicamente igual al del tutorial anterior, salvo que le añadimos otra cláusula con el host de mmonit y le decimos que ejecute el rol m_monit.

5.2. Rol de Nginx

El rol de Nginx es exactamente igual al de el anterior tutorial, donde ya lo hemos explicado.

5.3. Rol de Monit

En cuanto al rol de monit la manera de instalarlo sigue exactamente igual que en el anterior tutorial, solo que en el fichero ansible/roles/monit/templates/monitrc se ha de añadir la configuración específica para que Monit actúe como cliente y envíe la información a M/Monit. La configuración adicional que hay que añadir es:

ansible/roles/monit/templates/monitrc
# Set the URL to be used by Monit for sending messages to M/Monit
set mmonit http://{{ monit_mmonit_user }}:{{ monit_mmonit_password }}@{{ monit_mmonit_host }}:8080/collector

Aquí vemos como lo que hacemos es especificar un endpoint al API rest de M/Monit para lo cual necesitamos las credenciales de acceso (por defecto viene con dos usuarios: monit//monit y admin/swordfish siendo el segundo administrador) y el host de M/Monit (definido previamente en el Vagrantfile).

Como hemos añadido nuevas variables (monit_mmonit_user, monit_mmonit_password y monit_mmonit_host), debemos añadirlas a nuestro fichero de variables ubicado en ansible/roles/monit/defaults/main.yml

main.yml
---
# file: roles/monit/defaults/main.yml

monit_mmonit_user: monit
monit_mmonit_password: monit
monit_mmonit_host: 192.168.33.26

monit_check_services_intervals: "5"

monit_process_to_check:
    - name: nginx
      pid: /var/run/nginx.pid
      start_command: /etc/init.d/nginx start
      stop_command: /etc/init.d/nginx stop
      timeout: 10
      terms:
          - if failed port 80 for 2 cycles then restart

monit_sender_account_email: "email@gmail.com"
monit_sender_account_password: "email-password"

monit_alert_recipients:
    - email@gmail.com

5.4. Rol de M/Monit

Por último creamos el rol de M/Monit, que va a ser el encargado de instalar y configurar M/Monit.

La instalación por defecto viene con una base de datos SQLite, de forma que si queremos tener pocos datos, como es nuestro caso, es suficiente. Si la cantidad de datos a manejar es mayor, M/Monit te ofrece la posibilidad de cambiar la base de datos a un MySQL o PostgreSQL. En este enlace os dejo información sobre como hacerlo.

Vamos a comprobar las tareas que componen este rol 😀

main.yml
---
# file: /roles/m_monit/tasks/main.yml

- name: download M/Monit
  get_url:
      url: "{{ m_monit_donwload_url }}"
      dest: "/tmp/{{ m_monit_dir_tar_gz }}"

- name: create file
  file:
      path: /opt/mmonit-3.5.1
      state: directory

# environment clause it´s necessary because of a bug with the unarchive module
- name: extract mmonit
  unarchive:
      src: "/tmp/{{ m_monit_dir_tar_gz }}"
      dest: "{{ m_monit_base_dir }}"
      copy: no
  environment:
      LANG: C
      LC_ALL: C
      LC_MESSAGES: C

- name: Add mmonit links for management version
  file:
      src: "{{ m_monit_base_dir }}/{{ m_monit_dirname }}"
      dest: "{{ m_monit_base_dir }}/mmonit"
      state: link
      force: yes

- name: Enable mmonit for management as a service
  template:
      src: mmonit_init
      dest: "/etc/init.d/mmonit"
      owner: root
      group: root
      mode: "0755"
      force: yes

- name: Remove unextracted mmonit
  file:
      path: "{{ m_monit_base_dir }}/{{ m_monit_dir_tar_gz }}"
      state: absent

- name: ensure mmonit is running and enabled as service
  service:
      name: "mmonit"
      state: started
      enabled: yes

Como vemos los pasos son autoexplicativos:

  • Primero nos descargamos en un directorio temporal.
  • Luego lo extraemos y creamos un enlace simbólico para usar Monit abstrayéndonos de la versión y que sea más sencillo el usar múltiples versiones o elegir la de nuestra elección.
  • Configuramos M/Monit para arrancarlo como servicio con un script.
  • Borramos los datos que no necesitamos y nos aseguramos de que el servicio está habilitado.

A continuación mostramos el script que hace que M/Monit actúe como servicio, que está localizado en ansible/roles/m_monit/templates/mmonit_init:

mmonit_init
#!/bin/sh

#
# Sample init script for M/Monit to be placed in /etc/init.d/ and linked to run levels
#


DESC="mmonit"
NAME=mmonit
DAEMON={{ m_monit_base_dir }}/{{ m_monit_dirname }}/bin/$NAME
SCRIPTNAME=/etc/init.d/$NAME
PIDFILE=/var/run/mmonit.pid

# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0

d_start() {
        $DAEMON -p /var/run/ || echo -en "\n already running"
}

d_stop() {
        kill -QUIT `cat $PIDFILE` || echo -en "\n not running"
}

d_reload() {
        kill -HUP `cat $PIDFILE` || echo -en "\n can't reload"
}

case "$1" in
        start)
                echo -n "Starting $DESC: $NAME"
                d_start
                echo "."
                ;;
        stop)
                echo -n "Stopping $DESC: $NAME"
                d_stop
                echo "."
                ;;
        reload)
                echo -n "Reloading $DESC configuration..."
                d_reload
                echo "."
                ;;
        restart)
                echo -n "Restarting $DESC: $NAME"
                d_stop
                sleep 5
                d_start
                echo "."
                ;;
        *)
                echo "Usage: $SCRIPTNAME {start|stop|restart|reload}" >&2
                exit 3
                ;;
esac

exit 0

En este script lo que cambiamos indicamos como operar con el servicio de M/Monit.

Por último nos queda definir todas las variables usadas en este playbook. Eso lo hacemos en el fichero ansible/roles/m_monit/defaults/main.yml

ansible/roles/m_monit/defaults/main.yml
---
# file: roles/m_monit/defaults/main.yml

m_monit_donwload_url: "https://mmonit.com/dist/mmonit-3.5.1-linux-x64.tar.gz"

m_monit_base_dir: /opt

m_monit_dirname: "mmonit-3.5.1"
m_monit_dir_tar_gz: "{{ m_monit_dirname }}.tar.gz"

Con esto ya tendríamos preparada la configuración de la máquina virtual y el aprovisionamiento de las máquinas.

6. Creación del entorno

Ahora que tenemos la configuración preparada, vamos a crear el entorno y ver qué nos ofrece la interfaz de M/Monit. Para crear el entorno basta con ejecutar el comando:

Terminal
vagrant up

Una vez haya terminado, vas a tener Nginx funcionando en la url localhost:8888.

Nginx default image

Y M/Monit en la url http://192.168.33.26:8080/.

M/Monit login page

7. Exploración de la interfaz de M/Monit

Por último vamos a navegar por la interfaz de M/Monit para ver qué nos ofrece. Para ello hacemos login con el usuario admin y la contraseña swordfish (Usuario administrador por defecto) y accedemos al dashboard.

Monit Dashboard

En este panel comprobamos el 100% de nuestros hosts (el único que envía datos está bien). Esto quiere decir que Monit está enviando información sobre el estado del servicio que monitoriza (Nginx), que ya hemos comprobado que funciona. A la derecha tenemos un panel de eventos en las últimas 24 horas, donde vemos el primer evento que es el envío de información del cliente al servidor.

Ahora accedemos a la pestaña status, donde tenemos un listado de todos los host que están enviando información al servidor. Como vemos solo tenemos el host «monit», nombre que le pusimos en el Vagrantfile cuando lo creamos. También nos indica el consumo de cpu y de memoria, así como los eventos que se han producido en este host y su estado. En este caso, los dos servicios están disponibles (¿dos? exacto, el propio Monit y Nginx).

Monit Status

Si hacemos click en el host, veremos la información del host más detallada, y además podremos interactuar con los servicios que se monitorizan pudiendo pararlos, arrancarlos y reiniciarlos, monitorizarlos o dejar de hacerlo sin tener que entrar directamente.

Monit Status Detail

Ahora accedemos al apartado de reports donde podemos ver las analíticas y podemos jugar con ellas, parecido a las gráficas que te generas en Kibana.

Monit Report

Vamos a ver un ejemplo de como se ven los gráficos:

Monit Host Analytics

Ahora accedemos a el panel de administración general donde podemos ver la información general de Monit, las sesiones activas, la localización de los logs, y un pequeño apartado de preferencias en el cual podemos decir con qué frecuencia se borran los eventos.

Si ponemos el ratón sobre la pestaña admin, nos salen más opciones que podemos explorar. Vamos a ir viéndolas en orden descendente.

Monit admin options

En la pestaña hosts vemos las máquinas que tienen agentes de Monit instalados y comunicándose con M/Monit. Si hacemos click en el nombre de la máquina nos lleva al detalle que ya habíamos visto previamente.

Monit admin hosts

En la pestaña groups podemos definir una serie de máquinas agrupadas por tipo de instancia, contenido o un motivo de organización. De esta forma, también puedes crear reglas que apliquen a todo el grupo.

Monit admin groups

En la pestaña users es donde podemos crear usuarios para acceder a M/Monit. Yo os recomiendo como mínimo tener dos usuarios (con credenciales diferentes de las de por defecto, claro): uno que es el que usarán los agentes de Monit y otro para que podáis acceder a este panel.

Monit admin users

Por último tenemos las alertas, donde podemos definir avisos sobre eventos que le hayan sucedido a los servicios monitorizados de una máquina, grupos de hosts, y el método de aviso, que puede ser desde notificar con un correo electrónico (como tenemos configurado Monit), hasta que envíe mensajes por Slack. El grado de personalización de las alertas es muy amplio.

Monit admin alerts

8. Conclusiones

Al igual que Monit es muy sencillo y nos permite monitorizar el estado de nuestras aplicaciones o servicios y tomar decisiones respecto a su estado, M/Monit es una herramienta que nos ayuda a centralizar toda esta información que explotamos de los agentes.

Sin duda, si estás comenzando con el campo de monitorización de tus aplicaciones, o te preocupa que el servicio de las mismas pueda caerse cuando no estás disponible, es un primer paso para hacer que tu sistema sea más fiable.

El código completo (también el rol de Nginx y de Monit que no se han mostrado) están en mi repositorio de GitHub, de forma que solo hay que bajárselo y seguir las instrucciones desde el punto 6. Creación del entorno.

9. Referencias

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad