La dupla que conforman Prometheus y Grafana es ampliamente utilizada en las arquitecturas modernas por la gran compenetración de ambas herramientas. Por un lado, Prometheus se encarga de recolectar y almacenar las métricas en forma de time-series para, posteriormente, gestionarlas. Por otra parte, Grafana ofrece la posibilidad de visualizar estos datos mediante una potente UI.
En este artículo, veremos cómo se despliega un entorno de Grafana con Prometheus con un nodo exporter de Linux, una combinación de lo más útil y usual de esta arquitectura.
Caso de uso: Prometheus, Grafana y Linux exporter
A continuación, desarrollaremos un caso de uso y monitorización de un nodo Linux que podría extrapolarse a diferentes exportadores y aplicaciones. En este ejemplo, se está usando docker-compose con el objetivo de que puedas replicarlo en tu máquina y explorar las alternativas de configuración de Grafana con Prometheus.
Configuración básica
En primer lugar, debemos establecer un sistema de archivos con la siguiente forma y jerarquía:
├── docker-compose.yml
├── grafana
│ └── datasources
│ └── datasources.yml
└── prometheus
├── data
└── prometheus.yml
El path “prometheus/data” se usará como punto de persistencia del dato generado por Prometheus. Por lo tanto, los permisos que tendrá esa carpeta deberán conceder al usuario de docker la posibilidad de trabajar adecuadamente. La forma de solucionarlo dependerá de cada usuario y de su política y gestión de permisos y usuarios. No obstante, existe la posibilidad de dar permisos abiertos a esta carpeta ya que estamos en modo prueba de concepto.
Seguidamente, mostramos el docker-compose.yaml que tendrá la siguiente estructura:
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
volumes:
- ./prometheus/data:/prometheus/data
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
command:
- "--config.file=/etc/prometheus/prometheus.yml"
networks:
- monitoring
grafana:
image: grafana/grafana:latest
container_name: grafana
volumes:
- ./grafana/datasources:/etc/grafana/provisioning/datasources
ports:
- "3000:3000"
depends_on:
- prometheus
networks:
- monitoring
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
ports:
- "9100:9100"
networks:
- monitoring
networks:
monitoring:
driver: bridge
Este docker-compose desplegará tres contenedores de Docker, Prometheus, Grafana y el Linux Exporter. La forma de conectividad entre Prometheus y el Nodo a observar será mediante la configuración del archivo “prometheus.yml”.
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node_exporter'
static_configs:
- targets: ['node-exporter:9100']
Por último, será necesario configurar Grafana mediante el archivo “datasources.yaml” para indicar la conectividad con Prometheus a través del puerto 9090. Este driver utiliza el sistema de PromQL para el lanzamiento de consultas contra Prometheus y la devolución de resultados y series temporales.
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
Llegados a este punto, ya tenemos la configuración básica para conectar los tres componentes.
Opciones avanzadas de configuración
Ahora bien, en un entorno de estas características, podemos tener en cuenta que es posible gestionar toda la configuración interna mediante el campo jsonData dentro de la definición del DataSource. Veamos una configuración más avanzada para ver qué tipo de opciones interesantes podemos encontrar:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
jsonData:
httpMethod: POST
manageAlerts: true
prometheusType: Prometheus
cacheLevel: 'High'
Campos de configuración importantes:
- httpMethod. Parámetro que permite configurar cómo se realizarán las queries a Prometheus, ya que este acepta tanto peticiones GET como POST. En configuraciones avanzadas, el uso de el método POST permite enviar datos en el cuerpo de la petición.
- manageAlerts. Determina si Grafana gestionará las alertas en base a la configuración de alertas establecidas en Prometheus.
- prometheusType. Permite establecer el tipo de distribución de Prometheus con la que se va integrar Grafana.
- cacheLevel. Posibilita que se puedan almacenar por más tiempo los resultados de las consultas a Prometheus.
Escalabilidad de Prometheus con Thanos
En entornos donde existe un alto volumen de métricas provenientes de todas las aplicaciones y sistemas de la organización, Prometheus puede experimentar problemas de rendimiento. ¿En qué escenarios surgen estos problemas? Se dan en aquellas configuraciones de Prometheus que cuentan con múltiples instancias, que se despliegan en diferentes regiones o en un cluster y que tienen como desafíos la gestión de replicación de datos o la retención de datos masivos a largo plazo. Prometheus por sí solo no está diseñado para resolver estos desafíos.
Thanos permite solventar diferentes problemáticas, todas ellas orientadas a la escalabilidad. Al ser de código abierto, permite extender las capacidades de Prometheus, aportando alta disponibilidad al proyecto y mayor escalabilidad.
Componentes esenciales de Thanos
Thanos incorpora un un componente llamado Thanos Sidecar. Este elemento permite que el almacenamiento de las series temporales que normalmente Prometheus guardaría en local, pase a estar alojado de forma externa en la nube en AWS S3 o Google Cloud Storage. Este enfoque es perfecto para almacenar métricas que ya no se consultan de manera tan reiterada, pero que no se quieren perder.
Respecto a la alta disponibilidad, Thanos permite la ejecución de instancias Prometheus en paralelo, replicando los datos de las métricas en diferentes zonas geográficas. Thanos Query, hace posible la realización de consultas federadas sobre las instancias, asegurando que siempre se pueda acceder a los datos de métricas, incluso si alguna instancia no estuviera disponible.
Thanos Compact se encarga de comprimir los datos para mejorar la eficiencia de almacenamiento, un componente muy útil en el caso de almacenamiento a largo plazo.
En el proceso de despliegue debemos configurar tanto el componente de Thanos Sidecar como Thanos Query. Cuando Grafana trate de conectarse, debemos de cambiar la configuración para que apunte el al puerto de Thanos Query, ya que éste gestionará todas las peticiones contra Prometheus.

Conclusión
Prometheus se ayuda de Grafana para cubrir aspectos muy importantes de la visualización de datos que por sí solo no puede abordar. El stack de Grafana está totalmente adaptado para integrarse con Prometheus, lo cual hace que la configuración sea muy sencilla. Sin embargo, hemos visto que existen ciertas limitaciones en esta arquitectura y cómo en entornos productivos con gran volumen de datos el uso de Thanos puede suplir esas carencias de escalabilidad y alta disponibilidad.