Monitorizando Haproxy 2.0 mediante Prometheus y Grafana

Cloud, Tecnología de sistemas

Trevenque Group » Blog » Soluciones Empresariales » Monitorizando Haproxy 2.0 mediante Prometheus y Grafana

En anteriores posts hemos estado hablado sobre Haproxy como herramienta esencial para proteger y controlar el acceso y el buen funcionamiento de nuestras arquitecturas. Pero cómo tenerlo controlado y de qué manera podemos monitorizar su funcionamiento era una pequeña espina que me quedaba para completar esta serie de posts relacionados con Haproxy.

Una de las características incluidas en las nuevas versiones 2.x de Haproxy es la capacidad de monitorizar el funcionamiento de esta herramienta mediante Prometheus al traer integrado en su código un exportador de métricas compatible con la arquitectura Prometheus.

Prometheus es un sistema open-source de monitorización y alertas inicialmente desarrollado por SoundCloud y que actualmente forma parte como proyecto de la Cloud Native Computing Foundation. De hecho, es el segundo proyecto hospedado en esta fundación después de Kubernetes.

La mayoría de componentes de Prometheus están desarrollados en el lenguaje Go, lo que hace fácil crear binarios estáticos que podamos integrar con nuestras aplicaciones.

Sobre la integración de Haproxy y Prometheus, con la inestimable ayuda de Grafana, hablaremos hoy en este post.

Comencemos.

Desplegando Haproxy

La instalación de Haproxy es bastante fácil, basta agregar los repositorios necesarios para nuestra distribución e instalar el paquete. En caso de utilizar distribuciones basadas en Debian/Ubuntu, como es nuestro caso, el proceso se simplifica accediendo a la url <https://haproxy.debian.net> y seleccionando nuestra distribución y versión de la misma.

Hacemos esto porque las versiones incluidas en Debian/Ubuntu como paquete oficial aún están en la versión 1.8.x y nosotros queremos probar la flamante 2.x que incluye el exportador de métricas de Prometheus.

Siguiendo las instrucciones provistas en la url anterior, tendremos que hacer lo siguiente en consola:

# Agregamos la llave pública del repositorio haproxy.debian.net
curl https://haproxy.debian.net/bernat.debian.org.gpg | \
apt-key add -

# Agregamos una nueva fuente o repositorio a nuestra configuración apt
echo deb http://haproxy.debian.net buster-backports-2.0 main | \
tee /etc/apt/sources.list.d/haproxy.list

# Actualizamos la lista de paquetes incluyendo el nuevo repositorio
apt-get update

# Instalamos la versión 2.0.x incluída en el repositorio para nuestra distribución
apt-get install haproxy=2.0.\*

Esto nos dejará instalado el paquete Haproxy 2.0.12 en una Debian 10 que utilizaremos como máquina para este post.

Configurando Haproxy para habilitar el exportador de métricas de Prometheus

Como hablábamos anteriormente, el código de Haproxy en sus versiones 2.x ya trae integrado el exportador de métricas como servicio, así que simplemente tendremos que editar nuestro `haproxy.cfg` para habilitarlo.

Podemos comprobar si nuestra versión trae integrado el exportador de la siguiente forma:

root@haproxy:~# haproxy -vv |grep Prometheus
Built with the Prometheus exporter as a service

Y para habilitarlo tenemos que agregar un nuevo `frontend` a nuestra configuración, como ejemplo:

frontend stats
bind *:8404
option http-use-htx
http-request use-service prometheus-exporter if { path /metrics }
stats enable
stats uri /stats
stats refresh 10s

Esto habilitará en el puerto definido (`*:8404`) y en el path `/metrics` nuestro conjunto de métricas de la aplicación. También configurará el path `/stats` las métricas habituales de Haproxy. Aunque no son objeto de explicación de este post, son también una buena fuente de información acerca del funcionamiento de Haproxy.

Una vez hecho esto, sólo tenemos que consultar la url de nuestro haproxy en ese puerto y los distintos paths expuestos para obtener estadísticas de uso de Haproxy, aunque nuestra fuente de información será ese `/metrics` que vamos a aprovechar con Prometheus y Grafana.

Pasemos a configurar ambos paquetes.

Desplegando Prometheus y Node exporter

Desplegaremos Prometheus y Grafana en la misma máquina virtual donde está instalado Haproxy en este post. Aunque lo ideal es colocar este conjunto de herramientas en una máquina virtual aparte.

Vamos a desplegar también `Node Exporter`, que es el agente compatible con Prometheus para métricas básicas del sistema (cpu/disco/memoria/etc) y nos permitirá tener información genérica del funcionamiento tanto de la instalación de Haproxy como la del propio host que hospeda la solución Prometheus/Grafana.

Desplegando Node Exporter

Desplegaremos primero Node Exporter de la siguiente forma:

# Creamos los usuarios para prometheus y node exporter
useradd --no-create-home --shell /usr/bin/nologin prometheus
useradd --no-create-home --shell /bin/false node_exporter

# Creamos directorios de trabajo
mkdir /etc/prometheus
mkdir /var/lib/prometheus

# Cambiamos permisos
chown prometheus:prometheus /etc/prometheus
chown prometheus:prometheus /var/lib/prometheus

# Descargamos Node Exporter 
wget https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_exporter-0.18.1.linux-amd64.tar.gz

# Descomprimimos, movemos a directorio y ajustamos permisos de Node Exporter
tar zxvf node_exporter-0.18.1.linux-amd64.tar.gz

cp node_exporter-0.18.1.linux-amd64/node_expoter /usr/local/bin
chown node_exporter:node_exporter /usr/local/bin/node_exporter

# Creamos una nueva Unit de SystemD para ejecutar Node Exporter como servicio
vim /etc/systemd/system/node_exporter.service

# Agregamos la definición de la unidad

Description=Node Exporter
Wants=network-online.target
After=network-online.target


User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter


WantedBy=multi-user.target

# Recargamos las definiciones de SystemD
systemctl daemon-reload

# Arrancamos Node Exporter
systemctl start node_exporter

# Y por último verificamos que funciona correctamente y habilitamos el demonio para que arranque con el sistema
systemctl status node_exporter
● node_exporter.service - Node Exporter
Loaded: loaded (/etc/systemd/system/node_exporter.service; disabled; vendor preset: enabled)
Active: active (running) since Wed 2019-12-25 22:41:23 CET; 5s ago
Main PID: 7049 (node_exporter)
Tasks: 5 (limit: 1148)
Memory: 6.5M
CGroup: /system.slice/node_exporter.service
└─7049 /usr/local/bin/node_exporter

systemctl enable node_exporter

Desplegando Prometheus

Continuamos con la instalación de Prometheus:

# Descargamos el paquete Prometheus
wget https://github.com/prometheus/prometheus/releases/download/v2.15.1/prometheus-2.15.1.linux-amd64.tar.gz

# Descomprimimos 
tar zxvf prometheus-2.15.1.linux-amd64.tar.gz
cd prometheus-2.15.1.linux-amd64

# Copiamos la consola de Prometheus y el binario del mismo Prometheus al path
cp ./prometheus /usr/local/bin/
cp ./promtool /usr/local/bin/
cp -r ./consoles /etc/prometheus
cp -r ./console_libraries /etc/prometheus

# Ajustamos permisos
chown prometheus:prometheus /usr/local/bin/prometheus
chown prometheus:prometheus /usr/local/bin/promtool
chown -R prometheus:prometheus /etc/prometheus/consoles
chown -R prometheus:prometheus /etc/prometheus/console_libraries

Y pasamos a cambiar la configuración de Prometheus que reside en `/etc/prometheus/prometheus.yml`:

global:
scrape_interval: 15s
evaluation_interval: 15s

rule_files:

scrape_configs:
- job_name: 'prometheus'
scrape_interval: 5s
static_configs:
- targets: 
- job_name: 'node_exporter'
scrape_interval: 5s
static_configs:
- targets: 

Hemos agregado dos `jobs` de Prometheus, uno que chequeará el puerto en el que corre Prometheus (`:9090`) y otro para el Node Exporter (`:9100`). Estos dos `jobs` se chequearán cada 5 segundos. Esa será nuestra resolución de monitorización.

Por último, ajustamos los permisos del fichero mediante el comando: `chown prometheus:prometheus /etc/prometheus/prometheus.yml`.

Es hora de arrancar Prometheus y comprobar su funcionamiento:

sudo -u prometheus /usr/local/bin/prometheus --config.file /etc/prometheus/prometheus.yml --storage.tsdb.path /var/lib/prometheus/ --web.console.templates=/etc/prometheus/consoles --web.console.libraries=/etc/prometheus/console_libraries

level=info ts=2019-12-25T22:04:51.754Z caller=main.go:294 msg="no time or size retention was set so using the default time retention" duration=15d
level=info ts=2019-12-25T22:04:51.754Z caller=main.go:330 msg="Starting Prometheus" version="(version=2.15.1, branch=HEAD, revision=8744510c6391d3ef46d8294a7e1f46e57407ab13)"
level=info ts=2019-12-25T22:04:51.754Z caller=main.go:331 build_context="(go=go1.13.5, user=root@4b1e33c71b9d, date=20191225-01:04:15)"
level=info ts=2019-12-25T22:04:51.754Z caller=main.go:332 host_details="(Linux 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u2 (2019-11-11) x86_64 haproxy (none))"
level=info ts=2019-12-25T22:04:51.754Z caller=main.go:333 fd_limits="(soft=1024, hard=1048576)"
level=info ts=2019-12-25T22:04:51.754Z caller=main.go:334 vm_limits="(soft=unlimited, hard=unlimited)"
level=info ts=2019-12-25T22:04:51.758Z caller=main.go:648 msg="Starting TSDB ..."
level=info ts=2019-12-25T22:04:51.769Z caller=web.go:506 component=web msg="Start listening for connections" address=0.0.0.0:9090
level=info ts=2019-12-25T22:04:51.770Z caller=head.go:584 component=tsdb msg="replaying WAL, this may take awhile"
level=info ts=2019-12-25T22:04:51.771Z caller=head.go:632 component=tsdb msg="WAL segment loaded" segment=0 maxSegment=0
level=info ts=2019-12-25T22:04:51.772Z caller=main.go:663 fs_type=EXT4_SUPER_MAGIC
level=info ts=2019-12-25T22:04:51.773Z caller=main.go:664 msg="TSDB started"
level=info ts=2019-12-25T22:04:51.773Z caller=main.go:734 msg="Loading configuration file" filename=/etc/prometheus/prometheus.yml
level=info ts=2019-12-25T22:04:51.776Z caller=main.go:762 msg="Completed loading of configuration file" filename=/etc/prometheus/prometheus.yml
level=info ts=2019-12-25T22:04:51.776Z caller=main.go:617 msg="Server is ready to receive web requests."

Ahí tenemos nuestro `Server is ready to receive web request` que esperábamos. Lo que significa que, si visitamos con el navegador la url de nuestro Prometheus (`http://172.26.13.251:9090`, en nuestro caso), debemos ver su interfaz web.

Interfaz de Prometheus
Interfaz de Prometheus

Ahora tenemos que configurar una `Unit` de SystemD para que Prometheus arranque con el sistema:

# Editamos el fichero del servicio de Prometheus
vim /etc/systemd/system/prometheus.service

# Agregamos la definición del servicio

Description=Prometheus Monitoring
Wants=network-online.target
After=network-online.target


User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
--config.file /etc/prometheus/prometheus.yml \
--storage.tsdb.path /var/lib/prometheus/ \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries
ExecReload=/bin/kill -HUP $MAINPID


WantedBy=multi-user.target

# Recargamos la definición de servicios de SystemD
systemclt daemon-reload

# Habilitamos el servicio
systemctl enable prometheus

# Iniciamos el servicio
systemctl start prometheus

# Y comprobamos que está funcionando correctamente
systemctl status prometheus
● prometheus.service - Prometheus Monitoring
Loaded: loaded (/etc/systemd/system/prometheus.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2019-12-25 23:12:25 CET; 3s ago
Main PID: 7373 (prometheus)
Tasks: 7 (limit: 1148)
Memory: 25.9M
CGroup: /system.slice/prometheus.service
└─7373 /usr/local/bin/prometheus --config.file /etc/prometheus/prometheus.yml --storage.tsdb.path /var/lib/prometheus/ --web.cons

Desplegando Grafana

Grafana es la herramienta de facto para analizar y monitorizar que usaremos junto a Prometheus (almacenaje y recolección de métricas) y así completar nuestro stack de Monitorización.

Para desplegarlo, nos descargaremos el paquete para la distribución Debian de la siguiente forma:

# Instalamos paquetes necesarios
apt-get install fontconfig-config fonts-dejavu-core libfontconfig1

# Descargamos la última versión de Grafana e instalamos
wget https://dl.grafana.com/oss/release/grafana_6.5.2_amd64.deb
dpkg -i grafana_6.5.2_amd64.deb

# Habilitamos el servicio y lo ejecutamos
systemctl daemon-reload && systemctl enable grafana-server && systemctl start grafana-server

Ya tenemos disponible Grafana corriendo en el puerto `:3000` de nuestro host Prometheus. Una vez disponible, nos conectaremos con las credenciales por defecto `user: admin` y `password: admin` y cambiaremos la contraseña por una más compleja.

Configurando Prometheus como fuente de datos de Grafana

Nos queda configurar Grafana para que consulte la base de datos de Prometheus en busca de métricas.

Lo haremos agregando un Data Source de tipo Prometheus ubicado en la url `http://localhost:9090`.

Configurando Prometheus como fuente de datos de Grafana
Configurando Prometheus como fuente de datos de Grafana

Configurando Prometheus como fuente de datos de Grafana (data source)
Configurando Prometheus como fuente de datos de Grafana (data source)

Configurando Prometheus como fuente de datos de Grafana
Configurando Prometheus como fuente de datos de Grafana

Configurando Prometheus como fuente de datos de Grafana
Configurando Prometheus como fuente de datos de Grafana

Agregando Dashboards a nuestro Grafana

Para terminar de completar la instalación de Grafana vamos a agregar un Dashboard con las métricas del propio host que hospeda Prometheus y Grafana. Buscaremos en la web de Grafana Dashboards y el dashboard con id:1860 será el que elegiremos.

Puedes ver cómo queda en nuestra instalación aquí:

Instalación de Node Exporter
Instalación de Node Exporter

Configurando Prometheus para que recoja las métricas de nuestro Haproxy

Todavía no tenemos el trabajo de Prometheus definido que se encargará de ir a por las métricas de Haproxy. Para realizar esta tarea tenemos que modificar el fichero de configuración de Prometheus alojado en `/etc/prometheus/prometheus.yml` de la siguiente forma:

# Editamos el fichero
vim /etc/prometheus/prometheus.yml

# Agregamos lo siguiente con cuidado de respetar la sintaxis del fichero YAML
- job_name: 'haproxy_exporter'
scrape_interval: 5s
static_configs:
- targets: 

# Recargamos la configuración
systemctl restart prometheus

Y procedemos a agregar el Dashboard relacionado con Haproxy de la web de Grafana Dashboards (o a construir el nuestro propio, según la necesidad que tengamos). El id del dashboard que vamos a utilizar es el 10225.

Para ello nos vamos al Grafana en el icono de «Dashboards» -> «Manage» -> «Import» y ahí colocaremos el ID del dashboard que vamos a usar. También podemos organizarlos por carpetas según nuestra organización.

Podemos ver cómo queda dicho dashboard en la siguiente imagen:

Dashboard de Grafana
Dashboard de Grafana

Como podéis ver en la captura, nos está mostrando el número de `frontends` que están en estado activo y un montón de métricas más que podremos explorar dentro de nuestro Dashboard.

De esta manera podemos explorar todas las métricas que expone nuestro Haproxy.

Queda para otros posts la gestión de alertas mediante `AlertManager` o la creación de dashboards personalizados mediante PromQL, el lenguaje de consultas que utiliza internamente Prometheus.

¿Te ha gustado? ¡Compártelo!

Logo Trevenque

trevenque group

Ofrecemos un conjunto de servicios completos para que puedas desarrollar tu negocio, gestionar tus datos de manera inteligente y tomar decisiones rentables.

Deja un comentario

Artículos similares

Sigue de cerca la actualidad de Grupo Trevenque y las últimas tendencias tecnológicas y de Business Intelligence.

Ver todas las noticias