Monitorización de Dispositivos

Monitorización de Dispositivos

TELEGRAF+INFLUXDB+GRAFANA

Hola a todos:

Han sido varios compañeros los que me han pedido que haga este tutorial sobre monitorización, y es que cualquier administrador de sistemas que se precie, querrá tener controlados todos los host, así como sacar datos que le puedan ser útiles para futuras aplicaciones. Dado que hay gente de distintos niveles informáticos, voy a intentar hacer el tutorial lo más entendible para todos. 

Esta claro que no todos tenemos la misma configuración, y por tanto las configuraciones que iré mostrando, la tendréis que adaptar a vuestras necesidades. 

En mi caso cuento con dos Raspberry (RPI) 2 y 3 respectivamente, en las cuales tengo instalados varios contenedores para diversos fines.

Los contenedores que nos ocupan van a ser tres.

Telegraf: este contenedor se encarga de “leer” los datos de los dispositivos.

InfluxDB: es el contenedor encargado de almacenar la información que le proporciona el / los contenedores Telegraf. Aquí hago un inciso… ¿Por qué Influx?. Influx es una base de datos especializada en Time Series; y esto que es… normalmente en una base de datos podemos almacenar un nombre, un numero, en definitiva un dato “fijo”, los datos que vamos a almacenar nosotros son datos que van variando en el tiempo, y para esto Influx está mejor preparada que otras BBDD.

Grafana: este programa (que lo haremos funcionar en un contenedor) es el encargado de coger los datos de Influx y hacer la representación gráfica de los mismos.

A continuación expongo un esquema de cual es mi estructura, que es la que vamos a monitorizar.

Creo que está claro, pero si hay alguna duda, extiendo la explicación. A grandes rasgos tenemos en la RPI2 un contenedor Telegraf especializado en SNMP para leer los OID de mi router Mikrotik (Esto lo explicaré más adelante). En cada RPI tenemos otros dos contenedores Telegraf especializados en leer los datos de las Raspberry. Quiero destacar el contenedor Telegraf MQTT. Muchos se preguntarán por que este contenedor, cuando podemos mandar los datos desde el contenedor Mqtt a Homeassistant (HA) y que HA nos lo mande a Influx. Pues la respuesta es por lo siguiente; observé cuando trabajaba con HA que cada vez que reiniciaba HA, se me producía un corte en las gráficas del PZEM que tengo monitorizando mi red eléctrica de casa. Para evitar esto se me ocurrió crear un contenedor Telegraf que le pregunte directamente al contenedor Broker de Mqtt, así no tengo que pasar por HA.

Entrando en harina, vamos a empezar con la instalación de los contenedores. Decir que tengo la estructura de directorios igual que se ha realizado en otros muchos tutoriales (/Docker/(Lista de Contenedores). Cada uno tendrá que adaptar la configuración de los contenedores en base a su estructura. Como la RPI 3 ya la tengo entretenida con HA, le dejé el trabajo de monitorización a la RPI2. 

Instalación de InfluxDB 

 Enlace del contenedor para más info: https://hub.docker.com/_/influxdb

root@BBDD:# cd /docker/infludb

root@BBDD:/docker/influxdb#

docker run -p 8086:8086 –-name=influxdb –restart=always -v $PWD:/var/lib/influxdb influxdb

También tenemos la opción de crear el contenedor desde la raíz:

root@BBDD:# docker run -p 8086:8086 –name=influxdb –restart=always -v docker/influxdb:/var/lib/influxdb influxdb

Una vez creado el contenedor tenemos que proceder a crear las bases de datos que vayamos a necesitar.

root@BBDD:# docker exec -it influxdb /bin/bash

(el que tenga Portainer también puede acceder al contenedor mediante la consola).

Una vez dentro del contenedor teclearemos:

root@(contenedor)# influx

› create database (nombre de la base de datos, Ej: RPI3 yo tengo home_assistant, rpi2, rpi3, mqtt y mikrotik,pero cada uno que cree las que necesite)

› use  (nombre de la base de datos, esto pondrá en uso la base de datos seleccionada.

Creamos el usuario:

› create user (usuario) with password ‘(password)’ with all privileges

Siguiendo estos pasos crearemos todas las bases de datos necesarias. Entrar en cada base de datos y crear también sus usuarios.

Instalación de Grafana

Enlace del contenedor para más info: https://hub.docker.com/r/grafana/grafana

Yo personalmente Grafana no siempre la tengo ejecutándose, así que le hice un switch en HA para arrancarla cuando sea necesario. La instalación de Grafana la hice en la RPI3, pero cada uno que la haga donde más le guste. No preocuparse por que luego en la configuración interna de Grafana declararemos la ruta donde está o están ubicadas las bases de datos.

root@raspberrypi# docker run -d –name=grafana -p 3000:3000 grafana/grafana

Podremos comprobar si funciona entrando la http://(iphost:3000) y poniendo “admin” en usuario y password. Una vez dentro podremos crear nuestro usuario.

Instalación de Telegraf

Telegraf para lectura de Host y Contenedores.

Ahora con Telegraf, empezamos a entrar ya en harina… comenzaremos monitorizando las RPI’s o la RPI según tengamos una o varias.

Antes de crear el contenedor, comentar que con Telegraf podemos monitorizar tanto nuestras raspberrys como los contenedores docker que en ellas tengamos funcionando. Para ello tendremos que declarar la ubicación del docker.sock en la variable de creación del contenedor.

Instalaremos un contenedor de Telegraf en cada host que queramos monitorizar. La instalación es igual en todos los host, teniendo que cambiar los parámetros de configuración en el archivo telegraf.conf que veremos más adelante.

Enlace del contenedor para más info: https://hub.docker.com/_/telegraf

Para instalar Telegraf  interesa primero que el contenedor nos cree el archivo de configuración. Para crear este archivo teclearemos:

root@rasberrypi#  docker run –rm telegraf telegraf config > telegraf.conf

Ahora cogeremos el archivo telegraf.conf . Normalmente este archivo lo deberemos de dejar en el directorio persistente, quedando su ruta como:

/docker/telegraf/telegraf.conf

Este fichero es muy extenso por que tiene un montón de opciones de configuración, pero a nosotros de momento sólo nos interesa monitorizar nuestra RPI. Yo voy a pegar mi fichero de configuración donde declaro únicamente las variables que he necesitado. No obstante el que quiera puede trabajar con el fichero que nos ha creado el contenedor y ver todas sus variables. Con el mismo fichero podremos hacer que Télegraf nos monitorice el host o también el contenedor.

Si queremos monitorizar sólo los host, el fichero llegará a los parámetros “Input Plugins”, si queremos monitorizar también los contenedores, crearemos el fichero completo tal y como se muestra a continuación.

telegraf.conf (para leer Host y Dockers)

   interval = "10s"
   round_interval = true
   metric_batch_size = 1000
   metric_buffer_limit = 10000
   collection_jitter = "0s"
   flush_interval = "10s"
   flush_jitter = "0s"
   precision = ""
   debug = false
   quiet = false
   logfile = ""
   hostname = ""
   omit_hostname = false
###############################################################################
#                            OUTPUT PLUGINS                                   #
###############################################################################
[[outputs.influxdb]]
  urls = ["http://(iphost donde esté influxdb):8086"]
  database = "(nombre de la BBDD que hayamos creado EJ: rpi3 para almacenar los datos de mi rpi3"
  skip_database_creation = true
  username = "(usuario que hayamos creado en la BBDD correspondiente)"
  password = "(password del usuario que hayamos creado en la BBDD correspondiente)"
  user_agent = "telegraf"

###############################################################################
#                            INPUT PLUGINS                                    #
###############################################################################

# Read metrics about cpu usage
[[inputs.cpu]]
  percpu = true
  totalcpu = true
  collect_cpu_time = false

[[inputs.disk]]
  mount_points = ["/"]
  ignore_fs = ["tmpfs", "devtmpfs"]

[[inputs.kernel]]
[[inputs.mem]]
[[inputs.processes]]
[[inputs.swap]]
[[inputs.system]]
[[inputs.net]]
  interfaces = ["eth0"]
[[inputs.netstat]]
[[inputs.file]] 
  files = ["/sys/class/thermal/thermal_zone0/temp"]
  name_override = "cpu_temperature"
  data_format = "value"
  data_type = "integer"
###############################################################################
#                            INPUT DOCKERS                                    #
###############################################################################

[[inputs.docker]]
  
  endpoint = "unix:///var/run/docker.sock"
  gather_services = false
  container_names = []
  container_name_include = []
  container_name_exclude = []
  timeout = "5s"
  perdevice = true
  total = false
  docker_label_include = []
  docker_label_exclude = []
  tag_env = ["JAVA_HOME", "HEAP_SIZE"] 

Una vez que hemos terminado de configurar el fichero telegraf.conf procedemos a levantar el contenedor.

1
2
3
4
5
docker run --net=host \
> --name=telegraf \
> -v /docker/telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro\
> -v /var/run/docker.sock:/var/run/docker.sock \
> telegraf

Dos observaciones:

  • En la primera variable indicamos donde está el fichero telegraf.conf pero después hay que declararlo dentro del contenedor en su posición normal. Este punto lo veremos más en detalle en los otros contenedores.
  • La segunda variable es la que nos permitirá que el contenedor pueda leer los parámetros de Docker para sacar información de ellos.

Si todo ha ido bien, en la consola de Telegraf debe salirnos algo así:

2019-06-10T15:09:38Z I! Starting Telegraf 1.10.4
2019-06-10T15:09:38Z I! Using config file: /etc/telegraf/telegraf.conf
2019-06-10T15:09:38Z I! Loaded inputs: disk swap system net netstat cpu kernel mem processes file docker
2019-06-10T15:09:38Z I! Loaded aggregators: 
2019-06-10T15:09:38Z I! Loaded processors: 
2019-06-10T15:09:38Z I! Loaded outputs: influxdb
2019-06-10T15:09:38Z I! Tags enabled: host=raspberrypi
2019-06-10T15:09:38Z I! [agent] Config: Interval:10s, Quiet:false, Hostname:"raspberrypi", Flush Interval:10s

Y si entramos en el contenedor de InfluxDB deben haberse creado las tablas y los datos que estamos extrayendo con Telegraf. Adjunto una captura de mi BBDD de la RPI3 (observar los comandos usados)

root@BBDD:~# docker exec -it influxdb /bin/bash
 root@4758ee3fe82e:/# influx
 Connected to http://localhost:8086 version 1.7.6
 InfluxDB shell version: 1.7.6
 Enter an InfluxQL query
   >show databases
   name: databases
   name
   _internal
   home_assistant
   rpi2
   rpi3
   mikrotik
   mqtt
   >use rpi3
   Using database rpi3
   >show measurements
   name: measurements
   name
   cpu
   cpu_temperature
   disk
   docker
   docker_container_blkio
   docker_container_cpu
   docker_container_mem
   docker_container_net
   docker_container_status
   kernel
   mem
   net
   netstat
   processes
   swap
   system 

Podemos ver como Telegraf ha creado automáticamente todas las tablas de datos tanto de la RPI como del docker que hay en ella. Luego veremos en Grafana que los datos de las tablas son más extensos de lo que aquí aparecen.

Este es un ejemplo de datos extraídos de mi RPI3. Podemos configurar en Grafana alertas; Ej: la temperatura de la CPU.
Datos extraídos de cada docker que tengo en cada RPI, con su correspondiente Telegraf.

Telegraf para lectura del Broker Mqtt

Siguiendo con la instalación de nuestros contenedores Telegraf, vamos a configurar ahora el que nos va a leer directamente del broker de mqtt, el cual también es un contenedor.

Este contenedor lo llamaremos ahora mqtttelegraf para diferenciarlo del otro. Yo en cuestión lo tengo instalado en la RPI2 y lee del brocker mqtt que está en la RPI3. La instalación del contenedor es exactamente igual que el anterior con la salvedad de la ruda del fichero telegraf.conf, pero primero si no queremos liarnos, cogemos el telegraf.conf que habíamos editado antes y lo modificamos.

Aquí lo característico de este fichero es la parte de mqtt. Habrá que sacar el topic que queremos extraer; para ello podemos usar programas como mqtt.fx (del cual hay un tuto al respecto). Y luego hay que sacar las “keys” que queremos leer. Observar que los datos se sacan preformateados a “JSON”, cuidado no sacarlos en formato Influx por que no los entiende. Yo lo probé y daba error en la base de datos.

telegraf.conf (para leer broker de mqtt, en este caso un pzem)

 [global_tags]
[agent]
  interval = "10s"
  round_interval = true
  metric_batch_size = 1000
  metric_buffer_limit = 10000
  collection_jitter = "0s"
  flush_interval = "10s"
  flush_jitter = "0s"
  precision = ""
  debug = false
  quiet = false
  logfile = ""
  hostname = ""
  omit_hostname = false

###############################################################################
#                            OUTPUT PLUGINS                                   #
###############################################################################


[[outputs.influxdb]]

  urls = ["http://10.17.17.4:8086"]
  database = "mqtt"
  skip_database_creation = false
  username = "root"
  password = "ea5alg"
  user_agent = "telegraf"

###############################################################################
#                            INPUT PLUGINS MQTT                               #
###############################################################################

[[inputs.mqtt_consumer]]
  servers = ["tcp://ipdelbroker:1883"]
  qos = 0
  connection_timeout = "30s"
  topics = [
    "tele/contador/SENSOR",
  ]
  persistent_session = false
  client_id = "contador"
  username = "userdelbroker"
  password = "password del broker"
  data_format = "json"
  tag_keys = [
    "Total",
    "Yesterday",
    "Today",
    "Power",
    "ApparentPower",
    "ReactivePower",
    "Factor",
    "Voltage",
    "Current"
  ]

 

El comando para su instalación sería:

docker run --net=host \
   --name=telegraf \
   -v /docker/mqtttelegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro\
   telegraf 

Observar que el fichero telegraf.conf está en el directorio mqtttelegraf, pero dentro del contenedor la ruta tenemos que dejar la suya, de no hacerse así, al arrancar Telegraf nos daría un fallo.

Con esto ya tenemos monitorizando el broker…Para guardar sus datos si veis arriba cuando hemos sacado las bases de datos de influxdb, tengo una que se llama mqtt. Con los mismos comandos podemos ver las tablas que nos ha creado Telegraf. Con estos datos he creado la monitorización de mi PZEM con los consumos eléctricos.

Esta pantalla es una unión entre datos recolectados de HA y del PZEM

Telegraf para lectura SNMP de dispositivos.

Para aquellos que no lo sepan, SNMP es un protocolo simple de administración de dispositivos, que nos permite extraer información de estos. https://es.wikipedia.org/wiki/Protocolo_simple_de_administraci%C3%B3n_de_red

Este protocolo lo tienen infinidad de dispositivos como switches, routers, tarjetas de red, PC’s etc, etc. Para poder leer los datos, el dispositivo tiene que tener activado el servicio SNMP. De no tenerlo, en muchas ocasiones, sobre todo si tienen sistemas linux embebidos, se les puede instalar, dígase el caso por ejemplo de OpenWRT u otros…

No quiero hacerme muy extenso en el tema así que voy a comentarlo muy por encima; si alguien necesita más información puede dejarme un comentario. Cada dato de un dispositivo está representado por una serie de números organizados de forma jerárquica, estableciéndose muchos de ellos por reglas RF y el resto más específicos los proporciona el fabricante. Estos números son los OID; así por ejemplo un OID tiene esta forma: “.1.3.6.1.4.1.14988.1.1.3.14.0” este en cuestión muestra la información de la CPU de mi router. Toda esta información la recopilan los fabricantes de cada dispositivo en un fichero llamado MIB. Estos MIB pueden ser vistos con programas como el “ManageEngine MIBBrowser” que es el que yo uso. Podemos cargar el fichero MIB y sacar información mediante en SNMPWalk de todos los OID que tiene el dispositivo.

Imagen del programa para gestionar los MIB donde podemos ver los OID de un dispositivo.

Bueno, pues una vez que tenemos el listado de los OID que nos interesan, del dispositivo en cuestión, procederemos a modificar nuestro telegraf.conf. Mi consejo es crear un contenedor telegraf por cada dispositivo que queramos monitorizar, de lo contrario se nos puede hacer muy extenso el fichero de configuración y podríamos tener conflictos. También decir que si son muchos los dispositivos a monitorizar hay otras herramientas para tal fin como “LibreNMS” que hacen mejor esta función; pero bueno aquí se trata de monitorizar uno o dos dispositivos que tengamos en casa (router, Nas, etc).

Pues los pasos son los mismos… editar el telegraf.conf de la siguiente manera (NOTA: este fichero es para monitorizar un router Mikrotik, para otros dispositivos hay que cambiar los OID y resto de parámetros).

 # Global tags can be specified here in key="value" format.
[global_tags]
[agent]
 
  interval = "10s"
  round_interval = true
  metric_batch_size = 1000
  metric_buffer_limit = 10000
  collection_jitter = "0s"
  flush_interval = "10s"
  flush_jitter = "0s"
  precision = ""
  debug = false
  quiet = false
  logfile = ""
  hostname = ""
  omit_hostname = false


###############################################################################
#                            OUTPUT PLUGINS                                   #
###############################################################################

# Configuration for sending metrics to InfluxDB
[[outputs.influxdb]]
  urls = ["http://ipdeinfluxdb:8086"]
  database = "nombre de la base de datos"
  skip_database_creation = false
  ## HTTP Basic Auth
  username = "usuario base de datos"
  password = "password base de datos"
  ## HTTP User-Agent
  user_agent = "telegraf"

###############################################################################
#                            INPUT PLUGINS MIKROTIK                           #
###############################################################################

[[inputs.snmp]]
  agents = [ "10.17.17.1:161" ] # 

  [[inputs.snmp.field]]
    name = "hostname"
    oid = ".1.3.6.1.2.1.1.5.0"
    is_tag = true
  [[inputs.snmp.field]]
    name = "uptime"
    oid = ".1.3.6.1.2.1.1.3.0"
  [[inputs.snmp.field]]
    name = "cpu-frequency"
    oid = ".1.3.6.1.4.1.14988.1.1.3.14.0"
  [[inputs.snmp.field]]
    name = "cpu-load"
    oid = ".1.3.6.1.2.1.25.3.3.1.2.1"
  [[inputs.snmp.field]]
    name = "active-fan"
    oid = ".1.3.6.1.4.1.14988.1.1.3.9.0"
  [[inputs.snmp.field]]
    name = "voltage"
    oid = ".1.3.6.1.4.1.14988.1.1.3.8.0"
  [[inputs.snmp.field]]
    name = "temperature"
    oid = ".1.3.6.1.4.1.14988.1.1.3.10.0"
  [[inputs.snmp.field]]
    name = "processor-temperature"
    oid = ".1.3.6.1.4.1.14988.1.1.3.11.0"
  [[inputs.snmp.field]]
    name = "current"
    oid = ".1.3.6.1.4.1.14988.1.1.3.13.0"
  [[inputs.snmp.field]]
    name = "fan-speed"
    oid = ".1.3.6.1.4.1.14988.1.1.3.17.0"
  [[inputs.snmp.field]]
    name = "fan-speed2"
    oid = ".1.3.6.1.4.1.14988.1.1.3.18.0"
  [[inputs.snmp.field]]
    name = "power-consumption"
    oid = ".1.3.6.1.4.1.14988.1.1.3.12.0"
  [[inputs.snmp.field]]
    name = "psu1-state"
    oid = ".1.3.6.1.4.1.14988.1.1.3.15.0"
  [[inputs.snmp.field]]
    name = "psu2-state"
    oid = ".1.3.6.1.4.1.14988.1.1.3.16.0"

  # Interfaces
  [[inputs.snmp.table]]
    name = "snmp-interfaces"
    inherit_tags = ["hostname"]
    [[inputs.snmp.table.field]]
      name = "if-name"
      oid = ".1.3.6.1.2.1.2.2.1.2"
      is_tag = true
    [[inputs.snmp.table.field]]
      name = "mac-address"
      oid = ".1.3.6.1.2.1.2.2.1.6"
      is_tag = true

    [[inputs.snmp.table.field]]
      name = "actual-mtu"
      oid = ".1.3.6.1.2.1.2.2.1.4"
    [[inputs.snmp.table.field]]
      name = "admin-status"
      oid = ".1.3.6.1.2.1.2.2.1.7"
    [[inputs.snmp.table.field]]
      name = "oper-status"
      oid = ".1.3.6.1.2.1.2.2.1.8"
    [[inputs.snmp.table.field]]
      name = "bytes-in"
      oid = ".1.3.6.1.2.1.31.1.1.1.6"
    [[inputs.snmp.table.field]]
      name = "packets-in"
      oid = ".1.3.6.1.2.1.31.1.1.1.7"
    [[inputs.snmp.table.field]]
      name = "discards-in"
      oid = ".1.3.6.1.2.1.2.2.1.13"
    [[inputs.snmp.table.field]]
      name = "errors-in"
      oid = ".1.3.6.1.2.1.2.2.1.14"
    [[inputs.snmp.table.field]]
      name = "bytes-out"
      oid = ".1.3.6.1.2.1.31.1.1.1.10"
    [[inputs.snmp.table.field]]
      name = "packets-out"
      oid = ".1.3.6.1.2.1.31.1.1.1.11"
    [[inputs.snmp.table.field]]
      name = "discards-out"
      oid = ".1.3.6.1.2.1.2.2.1.19"
    [[inputs.snmp.table.field]]
      name= "errors-out"
      oid= ".1.3.6.1.2.1.2.2.1.20"

  # Wireless interfaces
  [[inputs.snmp.table]]
    name = "snmp-wireless-interfaces"
    inherit_tags = ["hostname"]
    [[inputs.snmp.table.field]]
      name = "ssid"
      oid = ".1.3.6.1.4.1.14988.1.1.1.3.1.4"
      is_tag = true
    [[inputs.snmp.table.field]]
      name = "bssid"
      oid = ".1.3.6.1.4.1.14988.1.1.1.3.1.5"
      is_tag = true
    
    [[inputs.snmp.table.field]]
      name = "tx-rate"
      oid = ".1.3.6.1.4.1.14988.1.1.1.3.1.2"
    [[inputs.snmp.table.field]]
      name = "rx-rate"
      oid = ".1.3.6.1.4.1.14988.1.1.1.3.1.3"
    [[inputs.snmp.table.field]]
      name = "client-count"
      oid = ".1.3.6.1.4.1.14988.1.1.1.3.1.6"
    [[inputs.snmp.table.field]]
      name = "frequency"
      oid = ".1.3.6.1.4.1.14988.1.1.1.3.1.7"
    [[inputs.snmp.table.field]]
      name = "band"
      oid = ".1.3.6.1.4.1.14988.1.1.1.3.1.8"
    [[inputs.snmp.table.field]]
      name = "noise-floor"
      oid = ".1.3.6.1.4.1.14988.1.1.1.3.1.9"
    [[inputs.snmp.table.field]]
      name = "overall-ccq"
      oid = ".1.3.6.1.4.1.14988.1.1.1.3.1.10"
  # Memory usage (storage/RAM)
  [[inputs.snmp.table]]
    name = "snmp-memory-usage"
    inherit_tags = ["hostname"]
    [[inputs.snmp.table.field]]
      name = "memory-name"
      oid = ".1.3.6.1.2.1.25.2.3.1.3"
      is_tag = true
    [[inputs.snmp.table.field]]
      name = "total-memory"
      oid = ".1.3.6.1.2.1.25.2.3.1.5"
    [[inputs.snmp.table.field]]
      name = "used-memory"
      oid = ".1.3.6.1.2.1.25.2.3.1.6"

 

Yo he creado una base de datos llamada mikrotik en mi InfluxDB, y de la misma forma que las anteriores cuando tenga en funcionamiento el contenedor, podré ver los datos que extraemos.

Para crear el contenedor (el mio está en la PI2) lo haremos igual que el anterior.

 docker run --net=host \
   --name=telegraf \
   -v /docker/mktttelegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro\
   telegraf  

Observar que aquí telegraf.conf esta en el directorio mktttelegraf, así tengo cada configuración en su correspondiente directorio.

Con el contenedor ya funcionando podemos tener datos interesantes de nuestros dispositivos.

Datos del router Mikrotik

 

Deja un comentario

Síguenos

Siguenos en facebook