Monitorizando Liferay Portal/DXP en Kubernetes

 

Check english version here

Una de las necesidades más comunes a las que nos enfrentamos en instalaciones de Liferay Portal/DXP es la motorización, así como el sistema de alertas que nos avisa si algo no funciona como debe (o como se espera)

Ya sea un servicio web administrado en la nube,  una máquina virtual, o un cluster  de Kubernetes,  tenemos la necesidad de monitorizar en tiempo real toda la infraestructura e incluso de disponer de un histórico. Con el fin de mitigar esta necesidad, se desarrolló Grafana.

Grafana es un software libre basado en licencia de Apache 2.0, ​ que permite la visualización y el formato de métricas. Con él podremos crear dashboards y gráficos a partir de múltiples fuentes. Uno de esos tipos de fuentes es Prometheus.

Prometheus es un software de código abierto que permite la recolección de métricas mediante pull HTTP. Para la extracción de estas métricas es necesario disponer de exportadores que realizarán la extracción de las métricas desde el punto deseado. Por ejemplo, para las métricas del cluster de Kubernetes podríamos utilizar kube-static-metrics. En nuestro caso, queremos monitorizar Liferay Portal/DXP, lo cual en una instalación on-premise lo haríamos mediante protocolo JMX utilizando herramientas como JConsole, VisualVM para realizarlo en caliente o bien utilizando un APM que extraiga y persista esta información con el fin de disponer de un histórico del comportamiento de la plataforma. En  este caso utilizaremos JMX Exporter, mediante el cual extraeremos los mBeans de la JVM de Liferay Portal/DXP para que seguidamente Grafana pueda leerlos, almacenarlos y con ellos crear nuestros dashboards y alertas. 
Además  usaremos el container Advisor (cAdvisor) de Kubernetes para obtener las métricas que el cluster expone acerca de nuestros contenedores.

 

Requisitos

  1. Un cluster de Kubernetes 

  2. Liferay Portal/DXP desplegado en Kubernetes. Si no dispones de ello, puedes seguir el siguiente blog que realicé unos meses atrás para desplegar Liferay Portal/DXP en Kubernetes.
     

¡ Comenzamos !

Configurando Exporter JMX para Tomcat

Lo primero que haremos será extraer las métricas por JMX desde el Tomcat de nuestro Liferay Portal/DXP. Para ello utilizaremos el exporter de JMX. Este exporter lo ejecutaremos como un javaagent dentro de las JVM Opts de nuestro Liferay Portal/DXP.

  1. Haciendo uso de nuestro Liferay Workspace, añadimos el folder jmx y en él incluimos el .jar del javaagent y el fichero yaml para configurar el exporter. En este fichero yaml estamos incluyendo algunos patrones para extraer los mBeans como métricas: contadores para monitorizar las solicitudes de tomcat, sobre la sesión, servlets, threadpool, database pool (hikari) y las estadísticas de ehcache. Estos patrones son totalmente adaptables y extensibles para las necesidades que puedan surgir.
    Seguidamente necesitaremos construir nuestra imagen Docker y pushearla a nuestro registry para actualizar nuestro deployment de Liferay Portal/DXP con nuestra última imagen, o bien configurar nuestra imagen de Liferay Portal/DXP con un configMap y volumen para añadir esta configuración.

  2. Mediante la variable de entorno LIFERAY_JVM_OPTS disponible en la imagen Docker de Liferay Portal/DXP, incluiremos el flag necesario para ejecutar el javaagent. Siguiendo la documentación del exporter de JMX necesitaremos indicar el puerto en el cual expondremos las métricas y el fichero de configuración con nuestros patrones de exportación de mBeans. En mi caso, he incluido esta variable de entorno utilizando un configMap donde agrupo todo este tipo de variables de entorno, pero podría ser insertada directamente en el deployment de Liferay Portal/DXP:




    Abriremos el puerto 8081 al contenedor, llamándolo “monitoring” e incluiremos la anotación necesaria para que Prometheus enganche las métricas a los pods que ejecuten este tipo de contenedores, así como indicarle el puerto sobre el cual extraerá las métricas para que Prometheus enganche únicamente con este puerto:





    Con esta configuración, ya podremos arrancar nuestro primer pod de Liferay Portal/DXP y en el puerto 8081 tendremos un endpoint “/metrics” donde se están exponiendo las métricas configuradas. Si quisiéramos consultarlo, podríamos abrir un nodePort al puerto 8081 para acceder a ello, pero no es necesario.

     

 

Instalando Prometheus

Ahora instalaremos Prometheus en nuestro cluster:

  1. Primero de todo necesitaremos crear el namespace donde implementaremos Prometheus. Lo llamaremos “monitoring”.
    Seguidamente, incluiremos los recursos del cluster a monitorizar. Necesitaremos aplicar el siguiente manifesto yaml, con el que crearemos el role “prometheus” y lo asociará al namespace “monitoring”. Esto aplicará los permisos “get”, “list” y “watch” a los recursos del cluster listados en “resources”. En nuestro caso, añadiremos los pods y los nodos de k8s. Los pods para acceder al endpoint /metrics donde está exponiendo métricas nuestro JMX exporter y los nodos para poder acceder a la CPU y Memoria solicitada por nuestros contenedores de Liferay Portal/DXP:



     
  2. Necesitaremos crear el siguiente configMap para configurar nuestro Prometheus. En él indicaremos la configuración del job que realizará el scrape de las métricas que el Exporter JMX está generando en cada pod de Liferay Portal/DXP además del job que extraerá las métricas del container Advisor de Kubernetes, con el fin de monitorizar CPU y Memoria de los contenedores. En él, además indicamos que el intervalo para leer estas métricas es de 5s:


     
  3. Ahora desplegaremos Prometheus en nuestro namespace monitoring. Primero crearemos el PVC donde Prometheus almacenará su información y seguidamente aplicaremos el manifesto yaml con el deployment de Prometheus. En él incluimos la configuración previa realizada en el paso 2 y abrimos el puerto 9090 al contenedor.
     
  4. Seguidamente crearemos el Servicio que expondrá nuestra instancia de Prometheus para acceder a él. En este caso utilizaremos un nodePort para acceder al puerto destino:


     
  5. Y una vez desplegado… si accedemos a la ip de nuestro cluster y al nodePort 30000 veremos Prometheus:


     
  6. Accediendo a targets (http://<ip>:30000/targets) veremos el estado de nuestros pods configurados para exportar métricas. En nuestro caso, un único pod con Liferay Portal/DXP:


     
  7. Desde la página principal de Prometheus, podremos insertar las queries para extraer las métricas deseadas. Estas queries deben ser en formato PromQL. Para aprender un poco más acerca de este Query Language, puedes leer los conceptos básicos desde la página oficial de Prometheus y coger algunos ejemplos:



    Si nos fijamos en la salida de la consulta, podemos ver, además del valor de salida de la misma, la procedencia de la métrica: el pod name, namespace, ip, release name ( en el caso de que usemos HELM para su despliegue, etc)
    Además podremos consultar la salida de la métrica en forma de gráfico:



     

 

Instalando y configurando Grafana

Grafana es la plataforma de análisis de métricas que nos permite consultar y crear alertas sobre los datos obtenidos desde un origen de métricas, como es nuestro Prometheus. El punto fuerte de Grafana es la creación de dashboards muy potentes totalmente a medida y persistentes en el tiempo, los cuales además pueden ser compartidos. La generación de alertas por medio de muchos canales como email, slack, sms, etc es también un punto muy potente. 

Al igual que hemos hecho con Prometheus, necesitaremos instalar Grafana en nuestro Cluster de k8s. Realizaremos el despliegue de Grafana en el mismo namespace monitoring.

  1. Crearemos en el namespace "monitoring" el siguiente configMap que nos servirá para aplicarle a Grafana la configuración necesaria para enganchar con Prometheus. Básicamente lo que hacemos en él es crear un datasource cuyo endpoint es el servicio de Prometheus creado anteriormente: prometheus-service.monitoring.svc:8080

  2. Crearemos el PVC donde Grafana almacenará la información com el siguiente manifesto yaml

  3. Crearemos el deployment de Grafana en "monitoring" aplicando el siguiente manifesto. En él abrimos el puerto 3000 al contenedor.

  4. Crearemos el servicio que expondrá Grafana y el puerto 3000 lo abrimos por un nodePort al 32000 de nuestro cluster:


     

  5. Ahora ya podremos acceder a nuestra instancia de Grafana:


     

  6. Accediendo con el usuario administrador por defecto (admin y password admin) podremos empezar a crear nuestros dashboards:




     

  7. Grafana es muy potente y muy adaptable, por lo que los gráficos que se deseen crear requerirán de un tiempo de trabajo para dejarlos al gusto del usuario que los quiera explotar. En el caso de una instalación de Liferay Portal/DXP en k8s, estoy monitorizando la memoria del contenedor, uso de cpu del contenedor, uso de la memoria de la JVM y tiempo de la Garbage Collector, pools de base de datos y pool de conexiones HTTP, además de un dashboard para monitorizar el porcentaje de cache misses sobre las caches de Liferay Portal/DXP:




     

  8. Es posible configurar alertas para cuando algún dashboard alcance algún threshold deseado. Por ejemplo, cuando el porcentaje de cache misses sea superior al 90% durante 5m, configuraremos la siguiente alerta:



    Podremos monitorizar el histórico de las alertas para el dashboard y obtener información exacta del momento en el que se alcanzó el umbral para analizar el problema.


Conclusión

Monitorizar nuestra instalación de Liferay Portal/DXP en Kubernetes, de manera totalmente a medida, es posible gracias a Prometheus y Grafana. Además no sólo dispondremos de una monitorización en caliente de la plataforma, si no que dispondremos de un histórico que nos ayudará a analizar el comportamiento de la misma ante situaciones problemáticas.