¿Cómo integrar métricas de aplicaciones externas en la monitorización avanzada de la Onesait Platform?

Hoy vamos a ver cómo se puede configurar una aplicación externa para que sus métricas de ejecución se almacenen y visualicen con la herramienta de monitorización que usa la Onesait Platform.

Como requisito para poder utilizar las funcionalidades descritas en esta guía, necesitamos tener el módulo de monitorización de la Plataforma desplegado y correctamente configurado.

En caso de que no contéis con una Plataforma de tipo Enterprise, podéis seguir esta guía haciendo uso de la versión Comunidad de la Onesait Platform, la cual podéis descargar de manera completamente gratis desde nuestro repositorio de GitHub.

Qué herramientas utilizamos

La monitorización de la Onesait Platform se basa en dos tecnologías principalmente, Prometheus y Grafana.

Prometheus es una base de datos de timeseries muy utilizada para la monitorización de métricas.

Por otro lado, Grafana es una herramienta que nos permite crear cuadros de mando por configuración y que, de la misma forma que Prometheus, es muy usada en la monitorización de sistemas y software por lo que cuenta con una buena base de cuadros de mando listos para usarse creados por su comunidad.

Además, dado que la Onesait Platform se despliega con Kubernetes, se utilizan Prometheus y Grafana Operator que facilitan el despliegue y la configuración de Prometheus y Grafana en Kubernetes.

Hay que tener en cuenta que el propósito de esta herramienta de monitorización es contar con métricas del software desplegado en el clúster de Kubernetes; por defecto, las métricas de los módulos de Onesait Platform, y como veremos en este artículo, también las métricas de otras aplicaciones. Esto no sustituye la monitorización hardware o de red que haya en una instalación.

Configuración de la aplicación

En esta entrada vamos a ver un caso típico de configuración para aplicaciones externas. En concreto, veremos cómo almacenar las métricas en Prometheus y cómo visualizarlas en Grafana considerando que se está usando el módulo de monitorización de la Onesait Platform que hace que dichos servicios estén disponibles y configurados.

Prometheus obtiene las métricas de las aplicaciones directamente, por lo que las aplicaciones deben habilitar una URL donde poder consultar las métricas. Esta acción se conoce como «scrape» en Prometheus. Si una aplicación de terceros no habilita las métricas en un formato que Prometheus pueda utilizar, existen varias alternativas para poder incorporarlas. La más sencilla es desplegar un agente, que en terminología Prometheus se llama «exporter», que transforma las métricas desde el formato que utilice la aplicación a un formato accesible para Prometheus.

En este caso vamos a hacer un ejemplo con una aplicación Spring Boot. En concreto. vamos a utilizar la aplicación de ejemplo Petclinic que cualquiera puede obtener del repositorio de proyectos de Spring.

En el caso de Spring Boot, sí soporta de forma nativa habilitar un «actuator» con las métricas generadas para Prometheus. Por defecto este proyecto ya tiene configurados los actuator. En Spring Boot, los actuator habilitan endpoints con información y comandos para la operación de las aplicaciones.

En caso de no tenerlos habilitados hay que añadir la siguiente dependencia al fichero «pom.xml» del proyecto:

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

En Spring Boot 2.x, sólo con esta dependencia no es suficiente para tener métricas en el formato que espera Prometheus, ya que el actuator para Prometheus no forma parte de los actuator habilitados por defecto y requiere de una dependencia adicional.

<dependency>
     <groupId>io.micrometer</groupId>
     <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

Una vez añadidos estos cambios, basta con arrancar la aplicación y probar que se ha creado el actuator de Spring Boot correctamente. Suponiendo que la aplicación se está ejecutando en el equipo local, y sobre el puerto 8080, podemos probar el servicio fácilmente haciendo una petición HTTP GET a la URL:

http://localhost:8080/actuator/prometheus

Se puede usar tanto un navegador como una herramienta tipo curl o Postman, y el resultado será algo similar al siguiente texto:

# HELP application_started_time_seconds Time taken (ms) to start the application
# TYPE application_started_time_seconds gauge
application_started_time_seconds{main_application_class="org.springframework.samples.petclinic.PetClinicApplication",} 6.177
# HELP logback_events_total Number of events that made it to the logs
# TYPE logback_events_total counter
logback_events_total{level="warn",} 0.0
logback_events_total{level="debug",} 0.0
logback_events_total{level="error",} 0.0
logback_events_total{level="trace",} 0.0
logback_events_total{level="info",} 18.0
...

Para el caso de las métricas, es recomendable no configurar seguridad y limitar el acceso por red para que la obtención de las métricas tenga el mínimo impacto posible en el rendimiento de la aplicación. En el caso de Kubernentes, lo normal es que sólo estén accesibles desde dentro del clúster y, si hiciese falta limitar aún más el acceso, se pueden usar «Network Policies».

Crear una imagen Docker de nuestro proyecto

Para este ejemplo, vamos a empaquetar nuestra aplicación de ejemplo en un contenedor Docker que utilizaremos para desplegar en Kubernentes. Cada proyecto utilizará sus propias configuraciones para empaquetar el código. En esta parte, vamos a crear una configuración básica para que se pueda seguir el ejemplo con el proyecto Petclinic.

En primer lugar, nos clonaremos el código fuente de la aplicación desde el repo correspondiente:

git clone https://github.com/spring-projects/spring-petclinic.git

Hecho esto, tendremos que generar el JAR con la aplicación. Para hacer esto, nos iremos a la raíz del proyecto y ejecutaremos lo siguiente:

mvn clean package

Esto nos debería haber creado el archivo JAR en el directorio del proyecto.

Seguidamente, para crear la imagen Docker utilizaremos el siguiente fichero Dockerfile creado en la raíz del proyecto:

FROM openjdk:11.0.1-jre-slim-stretch
EXPOSE 8080
ARG JAR=spring-petclinic-*.jar
COPY target/$JAR /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

Para facilitar el seguimiento de este tutorial, podemos usar la imagen Docker «onesaitplatform/example-monitoring-spring-boot:v1.0» que se encuentra alojada en DockerHub.

Configuración de Prometheus

Una vez que nuestra aplicación está correctamente configurada para exportar las métricas, vamos a configurar Prometheus para que obtenga dichas métricas.

Dado que se está utilizando Prometheus Operator, toda la configuración se realiza con ficheros «yalm», como cualquier otro recurso del clúster de Kubernetes, lo que facilita que esta configuración se incluya en cualquier proceso automatizado de despliegue o en un chart de Helm.

Hay varias formas de indicar a Prometheus dónde tiene que ir a buscar las métricas, pero en la mayoría de los casos bastará con configurar un elemento llamado «ServiceMonitor». Con este componente se le indicará a Prometheus la información necesaria para obtener las métricas.

A continuación se muestra el ServiceMonitor para nuestra aplicación de ejemplo:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: example-monitoring
  namespace: examples
spec:
  endpoints:
  - path: /actuator/prometheus
    targetPort: 8080
  namespaceSelector:
    matchNames:
    - examples
  selector:
    matchLabels:
      application: app-for-monitoring
  targetLabels:
  - application

En este caso, estamos configurando un Service Monitor en el namespace de «examples», que es donde hemos desplegado la aplicación de ejemplo, para agrupar los recursos en el mismo namespace.

Lo siguiente que vamos a configurar es el endpoint donde Prometheus pueda obtener las métricas, que en este caso es en la ruta «/actuator/prometheus» y en el puerto 8080, que es en el que estamos exponiendo dentro del clúster en el servicio de nuestra aplicación de ejemplo.

Para identificar el servicio del que obtener métricas, estamos filtrando por namespace («examples» en este caso), y por labels. Hay que tener en cuenta que estamos seleccionando un servicio, por lo que las labels deben estar configuradas en el servicio y no hace falta que estén en los deployments. Prometheus obtendrá las métricas de todos los pods a los que apunte dicho servicio sin necesidad de configuración adicional.

Para desplegar un Service Monitor en Rancher, se hace desde el menú Clúster Explorer > Monitoring (la monitorización debe estar previamente configurada):

Seguidamente, elegiremos la opción «Service Monitors» y crearemos un nuevo «Service Monitor» usando el fichero «yaml».

Una vez creado este componente, y transcurrido uno o dos minutos, podremos comprobar si Prometheus ha sido capaz de obtener métricas de nuestra aplicación. El primer lugar a revisar serán los «Targets» de Prometheus. Estos se pueden ver en Cluster Explorer > Monitoring > Overview > Prometheus Targets.

En la lista de servicios conectados podremos ver el que acabamos de crear y su estado.

Una vez está en estado «UP», Prometheus ya estará recogiendo métricas de nuestro programa. Éstas las podremos consultar usando una query desde la opción Cluster Explorer > Monitoring > Overview > Prometheus Graph.

Por defecto, Prometheus recogerá métricas cada minuto y se retendrán en Prometheus por un tiempo limitado que depende de cómo se haya configurado la monitorización en el entorno concreto. Obviamente, mayor tiempo de retención implica mayor cantidad de espacio de disco.

Configuración de Grafana

Bueno, pues una vez que tenemos las métricas almacenadas, vamos a ver cómo podemos visualizarlas. Aunque se pueden ver mediante consultas directamente a Prometheus, lo normal es definir cuadros de mando que nos muestren las métricas más relevantes en las que estés interesado.

Grafana se configura por defecto sin persistencia, de forma que toda la configuración se encuentra en «ConfigMaps» de Kubernetes. Esto tiene varias ventajas, pero la principal es que la configuración de los propios cuadros de mando se puede realizar en el mismo despliegue de la aplicación al usar, por ejemplo, Helm.

En el caso de Spring Boot ya existe un cuadro de mando que muestra las métricas para dichas aplicaciones:

Si lo que queremos es crear un nuevo cuadro de mando, lo podemos hacer de forma muy sencilla creando un nuevo dashboard de forma normal en Grafana, ya sea desde cero o importando uno existente. Una vez que tengamos el cuadro de mando listo, bastará con exportarlo como formato JSON y crear un «yml» para crear un «ConfigMap» utilizando el JSON:

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    grafana_dashboard: "1"
  name: name-of-your-dashboard
  namespace: cattle-dashboards # Change if using a non-default namespace
data:
  name-of-your-dashboard.json: |-
    {
    ...
    }

Con esto, Grafana creará automáticamente el cuadro de mando sin necesidad de reiniciar nada. Es importante que indiquemos el label «grafana_dashboard» con valor 1 y que el namespace sea el que tenga configurado Grafana Operator. En el caso de Rancher, este namespace es «cattle-dashboards».

Imagen de cabecera: Campaign Creators en Unsplash

Deja una respuesta

Tu dirección de correo electrónico no será publicada.