En este tutorial veremos M/Monit para monitorizar aplicaciones distribuidos en varias máquinas de forma centralizada.
Índice de contenidos
- 1. Introducción
- 2. Entorno
- 3. Prerrequisitos
- 4. Creación de las máquinas virtuales
- 5. Creación de los roles de Ansible
- 6. Creación del entorno
- 7. Exploración de la interfaz de M/Monit
- 8. Conclusiones
- 9. Referencias
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.
Y M/Monit en la url http://192.168.33.26:8080/.
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.
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).
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.
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.
Vamos a ver un ejemplo de como se ven los gráficos:
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.
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.
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.
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.
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.
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.