¿Qué es Prometheus?
Prometheus es un software que sirve para monitorizar el rendimiento de uno o más sistemas informáticos remotos (consumo de CPU, memoria, disco, bases de datos, servidores WEB, aplicaciones Java… hay cientos de métricas) a través de unos agentes (Exporters) que se instalan en cada sistema remoto y envían la información a un servidor centralizador.
Accederemos a las gráficas de rendimiento a través de una URL que se alimenta de los datos enviados por los Exporters y almacenados en una base de datos. Lo veremos más adelante en este artículo.
Prometheus es una aplicación 100% de código abierto e impulsado por la comunidad. Sus componentes están disponibles gratuitamente bajo la licencia Apache 2 en GitHub. Es un proyecto graduado de la Cloud Native Computing Foundation. También está registrado como marca registrada de la Fundación Linux.
Enlace oficial de Prometheus: https://prometheus.io/
Por ejemplo, podemos recolectar métricas sobre el consumo de CPU, memoria, rendimiento del disco tanto del sistema operativo como de contenedores con kubernetes, rendimiento de un servidor WEB, de bases de datos MySQL, y muchísimas métricas de todo tipo para luego visualizarlas en una gráfica que provee el propio Prometheus o por medio de otras herramientas como Grafana.
Instalación de Prometheus
Para hacer esta prueba voy a instalar la aplicación en un Linux CentOS 7.6.
Creación de directorios y descarga de software
mkdir /opt/Prometheus /etc/prometheus /var/lib/prometheus
cd /opt/Prometheus
wget https://github.com/prometheus/prometheus/releases/download/v2.10.0/prometheus-2.10.0.linux-amd64.tar.gz
tar xvzf prometheus-2.10.0.linux-amd64.tar.gz
[root@prometheus Prometheus]# pwd
/opt/Prometheus
[root@prometheus Prometheus]# ll
total 117908
drwxr-xr-x. 2 3434 3434 38 May 25 13:54 console_libraries
drwxr-xr-x. 2 3434 3434 173 May 25 13:54 consoles
-rw-r--r--. 1 3434 3434 11357 May 25 13:54 LICENSE
-rw-r--r--. 1 3434 3434 2770 May 25 13:54 NOTICE
-rwxr-xr-x. 1 3434 3434 74561203 May 25 12:29 prometheus
-rw-r--r--. 1 3434 3434 926 May 25 13:54 prometheus.yml
-rwxr-xr-x. 1 3434 3434 46152675 May 25 12:31 promtool
[root@prometheus Prometheus]#
Creación del usuario de aplicación
[root@prometheus Prometheus]# useradd --shell /bin/false prometheus
[root@prometheus Prometheus]# id prometheus
uid=1001(prometheus) gid=1001(prometheus) groups=1001(prometheus)
[root@prometheus Prometheus]#
Fichero de configuración del servidor de Prometheus
Definimos la IP y el puerto de escucha del servidor de Prometheus. En este caso, por cualquier IP local del servidor y el puerto 9090:
[root@prometheus ~]# cat /etc/prometheus/prometheus.yml
global:
scrape_interval: 10s
scrape_configs:
- job_name: 'prometheus_master'
scrape_interval: 5s
static_configs:
- targets: ['*:9090']
[root@prometheus ~]#
Configuración del servicio de sistema
Lo que queremos es que Prometheus arranque automáticamente con el boot del sistema operativo:
[root@prometheus ~]# cat /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target
[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/opt/Prometheus/prometheus \
--config.file /etc/prometheus/prometheus.yml \
--storage.tsdb.path /var/lib/prometheus/ \
--web.console.templates=/opt/Prometheus/consoles \
--web.console.libraries=/opt/Prometheus/console_libraries
[Install]
WantedBy=multi-user.target
[root@prometheus ~]#
[root@prometheus ~]# chown -R prometheus:prometheus /opt/Prometheus /etc/prometheus /var/lib/prometheus
[root@prometheus ~]#
[root@prometheus ~]# systemctl daemon-reload
[root@prometheus ~]# systemctl enable prometheus
Created symlink from /etc/systemd/system/multi-user.target.wants/prometheus.service to /etc/systemd/system/prometheus.service.
[root@prometheus ~]# systemctl start Prometheus
[root@prometheus ~]# systemctl status prometheus
● prometheus.service - Prometheus
Loaded: loaded (/etc/systemd/system/prometheus.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2019-06-12 10:25:47 UTC; 4s ago
Main PID: 4168 (prometheus)
CGroup: /system.slice/prometheus.service
└─4168 /opt/Prometheus/prometheus --config.file /etc/prometheus/prometheus.yml --storage.tsdb.path /var/lib/prometheus/ --web.console.templates=/opt/Prometheus/consoles --web.console....
Jun 12 10:25:47 prometheus prometheus[4168]: level=info ts=2019-06-12T10:25:47.080Z caller=main.go:324 host_details="(Linux 3.10.0-957.21.2.el7.x86_64 #1 SMP Wed Jun 5 14:26:44 UTC ...heus (none))"
Jun 12 10:25:47 prometheus prometheus[4168]: level=info ts=2019-06-12T10:25:47.080Z caller=main.go:325 fd_limits="(soft=1024, hard=4096)"
Jun 12 10:25:47 prometheus prometheus[4168]: level=info ts=2019-06-12T10:25:47.080Z caller=main.go:326 vm_limits="(soft=unlimited, hard=unlimited)"
Jun 12 10:25:47 prometheus prometheus[4168]: level=info ts=2019-06-12T10:25:47.086Z caller=main.go:645 msg="Starting TSDB ..."
Jun 12 10:25:47 prometheus prometheus[4168]: level=info ts=2019-06-12T10:25:47.094Z caller=main.go:660 fs_type=XFS_SUPER_MAGIC
Jun 12 10:25:47 prometheus prometheus[4168]: level=info ts=2019-06-12T10:25:47.094Z caller=main.go:661 msg="TSDB started"
Jun 12 10:25:47 prometheus prometheus[4168]: level=info ts=2019-06-12T10:25:47.094Z caller=main.go:730 msg="Loading configuration file" filename=/etc/prometheus/prometheus.yml
Jun 12 10:25:47 prometheus prometheus[4168]: level=info ts=2019-06-12T10:25:47.096Z caller=web.go:417 component=web msg="Start listening for connections" address=0.0.0.0:9090
Jun 12 10:25:47 prometheus prometheus[4168]: level=info ts=2019-06-12T10:25:47.187Z caller=main.go:758 msg="Completed loading of configuration file" filename=/etc/prometheus/prometheus.yml
Jun 12 10:25:47 prometheus prometheus[4168]: level=info ts=2019-06-12T10:25:47.187Z caller=main.go:614 msg="Server is ready to receive web requests."
Hint: Some lines were ellipsized, use -l to show in full.
[root@prometheus ~]#
[root@prometheus ~]# lsof -i:9090
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
prometheu 4214 prometheus 6u IPv6 30070 0t0 TCP *:websm (LISTEN)
prometheu 4214 prometheus 8u IPv4 30073 0t0 TCP localhost:53314->localhost:websm (ESTABLISHED)
prometheu 4214 prometheus 10u IPv6 30075 0t0 TCP localhost:websm->localhost:53314 (ESTABLISHED)
[root@prometheus ~]#
Acceso a la URL de servicio
Una vez que el servicio de Prometheus ya está arrancado, podemos acceder a la URL donde consultar las métricas de rendimiento. En nuestro caso http://localhost:9090.
Exporters
Prometheus es capaz de recoger métricas desde servidores remotos donde instalamos un módulo llamado node_exporter.
Existen muchos módulos o exporters diferentes para monitorizar servicios remotos. Por ejemplo, para monitorizar una base de datos MySQL, un servicio HA Proxy, un memcache, etc. Por lo tanto, si quisiéramos monitorizar una base de datos MySQL, nos descargaríamos el exporter correspondiente desde https://prometheus.io/download/ y habilitaríamos el servicio para poder recoger las métricas desde el servidor.
Ejemplo de uso de un Exporter (MySQL)
A modo de ejemplo, si quisiéramos configurar el exporter o monitor de MySQL, seguiríamos las siguientes instrucciones:
- Creamos el usuario y movemos los archivos del módulo a la ubicación que queramos:
useradd -rs /bin/false mysqld_exporter
mv mysqld_exporter-0.11.0.linux-amd64/mysqld_exporter /usr/bin
chown mysqld_exporter:mysqld_exporter /usr/bin/mysqld_exporter
- Creamos el directorio del exporter de MySQL
mkdir -p /etc/mysql_exporter
- Creamos una contraseña de acceso:
vi /etc/mysql_exporter/.my.cnf
[client]
user=mysqlexporter
password=contraseña_secreta
chown -R mysqld_exporter:mysqld_exporter /etc/mysql_exporter
chmod 600 /etc/mysql_exporter/.my.cnf
- Creamos el servicio que arrancará con el sistema:
vi /etc/systemd/system/mysql_exporter.service
[Unit]
Description=MySQL Server fosslinux
After=network.target
[Service]
User=mysqld_exporter
Group=mysqld_exporter
Type=simple
ExecStart=/usr/bin/mysqld_exporter \
--config.my-cnf="/etc/mysql_exporter/.my.cnf"
Restart=always
[Install]
WantedBy=multi-user.target
Reload the system daemon.
systemctl daemon-reload
Enable mysql_exporter on system boot.
systemctl enable mysql_exporter
systemctl start mysql_exporter
- Una vez configurado el servicio, ya podremos acceder a las métricas a través de la URL configurada http://Server_IP:9104/metrics.
Monitorización del Rendimiento del Sistema Operativo con el exporter Node_Exporter
Siguiendo el mismo ejemplo que para el exporter de MySQL, uno de los «exporters» más importantes y utilizados es el Node_Exporter, que sirve para monitorizar el rendimiento del sistema operativo (CPU, Memoria, Disco, etc.).
Para instalarlo, he querido modificar un poco la estructura anterior para organizar todos los exporters en un directorio común de Prometheus. Es decir, he descargado el node_exporter en:
[root@localhost exporters]# useradd -rs /bin/false node_exporter
[root@localhost node_exporter]# pwd
/opt/Prometheus/exporters/node_exporter
[root@localhost node_exporter]# ll
total 18740
-rw-r--r-- 1 prometheus prometheus 11357 Feb 13 05:42 LICENSE
-rwxr-xr-x 1 prometheus prometheus 19170241 Feb 13 05:31 node_exporter
-rw-r--r-- 1 prometheus prometheus 463 Feb 13 05:42 NOTICE
[root@localhost node_exporter]#
Por lo tanto, el servicio a configurar tiene que apuntar a esta ruta:
[root@localhost node_exporter]# cat /etc/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/opt/Prometheus/exporters/node_exporter/node_exporter
[Install]
WantedBy=multi-user.target
[root@localhost node_exporter]# systemctl start node_exporter
Como el servicio lo he configurado localmente, es decir, en el mismo servidor donde tengo configurado la consola de monitorización, configuro el fichero prometheus.yml, de la siguiente manera:
[root@localhost node_exporter]# cat /etc/prometheus/prometheus.yml
global:
scrape_interval: 10s
scrape_configs:
- job_name: 'prometheus_master'
scrape_interval: 5s
static_configs:
- targets: ['*:9090']
- job_name: 'node_exporter_metrics'
scrape_interval: 5s
static_configs:
- targets: ['localhost:9100']
[root@localhost node_exporter]#
El node_exporter escucha por el puerto 9100.
Seguidamente, reiniciamos el servicio de Prometheus para que adquiera la nueva configuración:
[root@localhost node_exporter]# systemctl restart prometheus
Si queremos conocer todas las métricas que tiene el Node_Exporter, accederemos a la URL del servicio, por ejemplo, http://localhost:9100
El siguiente paso será elegir bien las métricas o las consultas que queremos obtener.
Monitorización de la CPU del sistema operativo
Uso de CPU
Utilizaremos la fórmula:
rate(node_cpu_seconds_total{mode="system"}[1m])
Si queremos consultar un hostname o instancia específica, indicaremos el nombre o la IP y puerto de la instancia en concreto:
rate(node_cpu_seconds_total{mode="system", instance="localhost:9100"}[1m])
Si lo queremos con porcentajes de uso de CPU, utilizaremos:
rate(node_cpu_seconds_total{mode="system"}[1m]) * 100
Carga de CPU (Load)
Si queremos conocer el nivel de carga (load) del servidor en cada momento, tenemos tres métricas que lo miden cada cinco, diez y quince minutos (load1, load5 y load15).
Para apuntar a un servidor específico, utilizaremos node_load1{instance=»localhost:9100″}
Identificar los procesos que más CPU consumen
Para ello, tenemos que instalar un nuevo exporter llamado process_exporter.
- Configuración del servicio
[root@localhost ~]# cat /etc/systemd/system/process_exporter.service
[Unit]
Description=Process Exporter
After=network.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/opt/Prometheus/exporters/process_exporter/process-exporter --config.path /opt/Prometheus/exporters/process_exporter/config.yml
[Install]
WantedBy=multi-user.target
[root@localhost ~]#
- Fichero de configuración del exporter:
[root@localhost ~]# cat /opt/Prometheus/exporters/process_exporter/config.yml
process_names:
- name: "{{.Comm}}"
cmdline:
- '.+'
[root@localhost ~]#
- Fichero de configuración de Prometheus (/etc/prometheus/prometheus.yml):
job_name: 'process_exporter_metrics'
scrape_interval: 5s
static_configs:
- targets: ['localhost:9256']
- Reiniciamos los servicios:
systemctl daemon-reload
systemctl start process_exporter
systemctl restart prometheus
- Consultamos cuáles son los procesos más consumidores de CPU:
Número de procesos (namedprocess_namegroup_num_procs)
Para consultar las métricas de un servidor específico: namedprocess_namegroup_num_procs{instance=»localhost:9256″}
Consumo de CPU (namedprocess_namegroup_cpu_seconds_total)
Para consultar las métrias de un servidor específico: namedprocess_namegroup_cpu_seconds_total{instance=»localhost:9256″}
Porcentaje de uso de Memoria del sistema operativo
En este caso utilizaremos la fórmula siguiente formula para la RAM:
(1 - (node_memory_MemFree_bytes / (node_memory_MemTotal_bytes)))* 100
o para un servidor específico:
(1 - (node_memory_MemFree_bytes{instance="localhost:9100"} / (node_memory_MemTotal_bytes{instance="localhost:9100"})))* 100
Para el swap, el cálculo sería el siguiente:
(1 - (node_memory_SwapFree_bytes / (node_memory_SwapTotal_bytes)))* 100
o para un servidor específico:
(1 - (node_memory_SwapFree_bytes{instance="localhost:9100"} / (node_memory_SwapTotal_bytes{instance="localhost:9100"})))* 100
Identificar los procesos que más memoria consumen
Anteriormente ya habíamos configurado el exporter process_exporter. Podremos utilizar la métrica namedprocess_namegroup_memory_bytes para extraer los procesos que más memoria consumen:
Rendimiento de los discos
Medir la velocidad de lectura en disco
Utilizaremos el cálculo de dos métricas:
node_disk_read_bytes_total / node_disk_read_time_seconds_total
o para un servidor específico
node_disk_read_bytes_total{instance="localhost:9100"} / node_disk_read_time_seconds_total{instance="localhost:9100"}
Medir la velocidad de escritura en disco
Siguiendo el ejemplo anterior, esta vez, utilizaremos estas otras dos métricas:
node_disk_written_bytes_total / node_disk_write_time_seconds_total
o para un servidor específico
node_disk_written_bytes_total{instance="localhost:9100"} / node_disk_write_time_seconds_total{instance="localhost:9100"}
Rendimiento de la red y detección de errores
Con Node_Exporter, también podemos medir la velocidad de la red y si tenemos algún error en alguna de las tarjetas de red.
Velocidad de descarga (bytes recibidos)
Utilizaremos la métrica node_network_receive_bytes_total (o node_network_receive_bytes_total{instance=»localhost:9100″}).
Podemos utilizar la métrica node_network_receive_errs_total para saber si tenemos errores a la hora de recibir datos en nuestra red.
Velocidad de upload (bytes enviados)
En este caso utilizaremos la métrica node_network_speed_bytes.
Podemos utilizar la métrica node_network_transmit_errs_total (o node_network_transmit_errs_total{instance=»localhost:9100″}) para saber si tenemos errores a la hora de enviar datos en nuestra red.
¿Dónde guarda los datos Prometheus?
Por defecto, Prometheus guarda sus datos en el directorio /var/lib/prometheus.
[root@localhost prometheus]# pwd
/var/lib/prometheus
[root@localhost prometheus]# ll
total 12
drwxr-xr-x 3 prometheus prometheus 68 Feb 28 04:46 01EZKBXAGZMY4KWMGJ58QNQP9E
drwxr-xr-x 3 prometheus prometheus 68 Feb 28 04:46 01EZKBXC79N501B9VJXYCZT841
drwxr-xr-x 3 prometheus prometheus 68 Feb 28 07:46 01EZKP6X6HHFJBZ990HQBABCTC
drwxr-xr-x 3 prometheus prometheus 68 Feb 28 08:00 01EZKPZM70Q64J9NHTM1NTJ1N3
drwxr-xr-x 2 prometheus prometheus 76 Feb 28 08:57 chunks_head
-rw-r--r-- 1 prometheus prometheus 0 Feb 27 18:44 lock
-rw-r--r-- 1 prometheus prometheus 20001 Feb 28 08:59 queries.active
drwxr-xr-x 3 prometheus prometheus 113 Feb 28 08:57 wal
[root@localhost prometheus]#
No obstante, cuando creamos el servicio de arranque de Prometheus, podemos modificar tanto el directorio de almacenamiento como la retención de datos expresada en días o en espacio de disco.
[root@prometheus ~]# cat /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target
[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/opt/Prometheus/prometheus \
--config.file /etc/prometheus/prometheus.yml \
--storage.tsdb.path /var/lib/prometheus/ \
--storage.tsdb.retention.time=1y \
--storage.tsdb.retention.size=10G \
--web.console.templates=/opt/Prometheus/consoles \
--web.console.libraries=/opt/Prometheus/console_libraries
[Install]
WantedBy=multi-user.target
[root@prometheus ~]#
Visualización de las gráficas de Prometheus con Grafana
¿Qué es Grafana?
Grafana es un software gratuito para mostrar conjuntos de datos de series temporales que se almacenan en una base de datos (de series temporales). Estos datos se pueden recuperar de muchas de fuentes diferentes como Graphite, InfluxDB, OpenTSDB y Prometheus (por nombrar solo algunas).
Hasta ahora hemos visto cómo funciona Prometheus para analizar el rendimiento del sistema operativo, sin embargo, obtener las gráficas que queremos es una tarea algo compleja, ya que algunas de las métricas se obtienen mediante fórmulas.
Grafana nos facilita esta tarea, ya que es capaz de hacer consultas en Prometheus e incluye una serie de métricas por defecto. Es decir, no necesitamos buscar ninguna fórmula en Prometheus. Este trabajo ya viene hecho en Grafana.
Instalación de Grafana
Lo primero que haremos, será crear el repositorio de yum para poder instalar el producto.
[root@prometheuslocal yum.repos.d]# cat grafana.repo
[grafana]
name=grafana
baseurl=https://packages.grafana.com/oss/rpm
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://packages.grafana.com/gpg.key
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
[root@prometheuslocal yum.repos.d]#
A continuación, instalamos Grafana con dnf:
[root@prometheuslocal ~]# dnf -y install grafana
[root@prometheuslocal ~]# rpm -qa |grep -i grafana
grafana-7.4.3-1.x86_64
[root@prometheuslocal ~]#
Por último, habilitamos el servicio para que arranque con el boot del sistema y arrancamos Grafana:
[root@prometheuslocal ~]# systemctl enable grafana-server.service
Synchronizing state of grafana-server.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
Executing: /usr/lib/systemd/systemd-sysv-install enable grafana-server
Created symlink /etc/systemd/system/multi-user.target.wants/grafana-server.service → /usr/lib/systemd/system/grafana-server.service.
[root@prometheuslocal ~]#
[root@prometheuslocal ~]# systemctl start grafana-server.service
[root@prometheuslocal ~]#
[root@prometheuslocal ~]# ps -ef |grep -i grafana
root 3356 1 0 08:33 ? 00:00:00 gpg-agent --homedir /var/cache/PackageKit/8/metadata/grafana-8-x86_64.tmp/gpgdir --use-standard-socket --daemon
root 3441 2335 0 08:34 ? 00:00:00 gpg-agent --homedir /var/cache/dnf/grafana-13e251e56a0c8862/pubring --use-standard-socket --daemon
grafana 3621 1 7 08:35 ? 00:00:00 /usr/sbin/grafana-server --config=/etc/grafana/grafana.ini --pidfile=/var/run/grafana/grafana-server.pid --packaging=rpm cfg:default.paths.logs=/var/log/grafana cfg:default.paths.data=/var/lib/grafana cfg:default.paths.plugins=/var/lib/grafana/plugins cfg:default.paths.provisioning=/etc/grafana/provisioning
root 3632 3063 0 08:36 pts/0 00:00:00 grep --color=auto -i grafana
[root@prometheuslocal ~]#
Acceso a la consola de Grafana
Por defecto, Grafana escucha por el puerto 3000 y podemos acceder mediante HTTP:
[root@prometheuslocal ~]# grep -i http_port /etc/grafana/grafana.ini
;http_port = 3000
;root_url = %(protocol)s://%(domain)s:%(http_port)s/
[root@prometheuslocal ~]#
El usuario por defecto es «admin» con contraseña «admin».
Si queremos analizar cualquier error relacionado con Grafana, podremos ver el log en /var/log/grafana.
Configuración de Grafana para ver las gráficas de Prometheus
Ahora que ya tenemos configurado Grafana, vamos a conectarlo con Prometheus. Para ello, crearemos un nuevo Datasource de Prometheus.
Ahora ya podemos entrar en cualquier dashboard importado para visualizar las métricas por defecto, simplemente, haciendo click. Por ejemplo, vamos a entrar en Prometheus 2.0 Stats.
Si queremos personalizar alguna de las gráficas del panel, simplemente, lo editaremos y escribiremos nuestra fórmula de Prometheus:
Te puede interesar
Configuración de perfiles de rendimiento de sistema con tuned-adm
Mi pasión por la tecnología me lleva constantemente a explorar las últimas tendencias y aplicaciones, buscando siempre formas de implementar soluciones innovadoras que mejoren la eficiencia. En puerto53.com comparto contenido valioso para ayudar a otros profesionales y entusiastas de la informática a navegar y dominar el complejo mundo de la tecnología. Mi especialidad en Linux RedHat.
Más sobre mí en el este enlace,
Disculpa la pregunta pero hay forma de que en lugar de que prometheus vaya al target a buscar las métricas sea solo el que escucha y el exporter envíe las metricas? En mi escenario quiero monitorear equipos que voy dejando en clientes y quiero evitar pedir la ip publica y la redirección de puerto al cliente. Preferiría configurar el exporter o agente en el equipo a monitorear y que este apunte a mi prometheus el cual estaría escuchando en un dominio con un puerto público abierto.
Quedo atento.
Gracias!
Hola, no es posible. Va en contra de la propia naturaleza de Prometheus, según podemos ver en la propia guía para desarrollar nuestros propios exporters. Por ejemplo, una de las tareas que tenemos que realizar, según la guía, es una «landing page» del exporter, otra URL con información de las métricas e informar de los puertos por los que escucha el exporter. El exporter, sólo recoge datos del servidor pero no los envía a ningún sitio.
Un saludo.