sql >> Base de Datos >  >> RDS >> MariaDB

Cómo monitorear contenedores MySQL con Prometheus - Implementación en Standalone y Swarm:Primera parte

El monitoreo es una preocupación para los contenedores, ya que la infraestructura es dinámica. Los contenedores se pueden crear y destruir de forma rutinaria y son efímeros. Entonces, ¿cómo realiza un seguimiento de sus instancias de MySQL que se ejecutan en Docker?

Al igual que con cualquier componente de software, existen muchas opciones que se pueden utilizar. Veremos a Prometheus como una solución creada para infraestructura distribuida y funciona muy bien con Docker.

Este es un blog de dos partes. En este blog de la parte 1, cubriremos el aspecto de implementación de nuestros contenedores MySQL con Prometheus y sus componentes, ejecutándose como contenedores Docker independientes y servicios Docker Swarm. En la parte 2, veremos las métricas importantes para monitorear desde nuestros contenedores MySQL, así como la integración con los sistemas de paginación y notificación.

Introducción a Prometeo

Prometheus es un sistema completo de seguimiento y tendencias que incluye raspado, almacenamiento, consultas, gráficos y alertas integrados y activos basados ​​en datos de series temporales. Prometheus recopila métricas mediante un mecanismo de extracción de objetivos configurados en intervalos determinados, evalúa las expresiones de las reglas, muestra los resultados y puede activar alertas si se observa que alguna condición es verdadera. Admite todas las métricas de destino que queremos medir si a uno le gustaría ejecutar MySQL como contenedores Docker. Esas métricas incluyen métricas de hosts físicos, métricas de contenedores de Docker y métricas de servidores MySQL.

Eche un vistazo al siguiente diagrama que ilustra la arquitectura de Prometheus (tomado de la documentación oficial de Prometheus):

Vamos a implementar algunos contenedores de MySQL (independientes y Docker Swarm) completos con un servidor Prometheus, un exportador de MySQL (es decir, un agente de Prometheus para exponer las métricas de MySQL, que luego puede extraer el servidor de Prometheus) y también Alertmanager para manejar alertas basadas en en las métricas recopiladas.

Para obtener más detalles, consulta la documentación de Prometheus. En este ejemplo, vamos a utilizar las imágenes oficiales de Docker proporcionadas por el equipo de Prometheus.

Docker independiente

Implementación de contenedores MySQL

Ejecutemos dos servidores MySQL independientes en Docker para simplificar nuestro tutorial de implementación. Un contenedor usará la última versión de MySQL 8.0 y el otro es MySQL 5.7. Ambos contenedores están en la misma red Docker llamada "db_network":

$ docker network create db_network
$ docker run -d \
--name mysql80 \
--publish 3306 \
--network db_network \
--restart unless-stopped \
--env MYSQL_ROOT_PASSWORD=mypassword \
--volume mysql80-datadir:/var/lib/mysql \
mysql:8 \
--default-authentication-plugin=mysql_native_password

MySQL 8 usa por defecto un nuevo complemento de autenticación llamado caching_sha2_password . Para compatibilidad con el contenedor de exportación MySQL de Prometheus, usemos la ampliamente utilizada mysql_native_password complemento cada vez que creamos un nuevo usuario de MySQL en este servidor.

Para el segundo contenedor de MySQL que ejecuta 5.7, ejecutamos lo siguiente:

$ docker run -d \
--name mysql57 \
--publish 3306 \
--network db_network \
--restart unless-stopped \
--env MYSQL_ROOT_PASSWORD=mypassword \
--volume mysql57-datadir:/var/lib/mysql \
mysql:5.7

Verifique si nuestros servidores MySQL funcionan correctamente:

[[email protected] mysql]# docker ps | grep mysql
cc3cd3c4022a        mysql:5.7           "docker-entrypoint.s…"   12 minutes ago      Up 12 minutes       0.0.0.0:32770->3306/tcp   mysql57
9b7857c5b6a1        mysql:8             "docker-entrypoint.s…"   14 minutes ago      Up 14 minutes       0.0.0.0:32769->3306/tcp   mysql80

En este punto, nuestra arquitectura se parece a esto:

Comencemos a monitorearlos.

Exposición de métricas de Docker a Prometheus

Docker tiene soporte incorporado como objetivo de Prometheus, donde podemos usar para monitorear las estadísticas del motor de Docker. Simplemente podemos habilitarlo creando un archivo de texto llamado "daemon.json" dentro del host de Docker:

$ vim /etc/docker/daemon.json

Y agregue las siguientes líneas:

{
  "metrics-addr" : "12.168.55.161:9323",
  "experimental" : true
}

Donde 192.168.55.161 es la dirección IP principal del host de Docker. Luego, reinicie el demonio Docker para cargar el cambio:

$ systemctl restart docker

Dado que hemos definido --restart=unless-stopped en el comando de ejecución de nuestros contenedores MySQL, los contenedores se iniciarán automáticamente después de que se ejecute Docker.

Implementación del Exportador MySQL

Antes de continuar, el exportador mysqld requiere que se use un usuario de MySQL para fines de monitoreo. En nuestros contenedores de MySQL, cree el usuario de supervisión:

$ docker exec -it mysql80 mysql -uroot -p
Enter password:
mysql> CREATE USER 'exporter'@'%' IDENTIFIED BY 'exporterpassword' WITH MAX_USER_CONNECTIONS 3;
mysql> GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';

Tenga en cuenta que se recomienda establecer un límite máximo de conexión para el usuario para evitar sobrecargar el servidor con raspaduras de monitoreo bajo una carga pesada. Repita las declaraciones anteriores en el segundo contenedor, mysql57:

$ docker exec -it mysql57 mysql -uroot -p
Enter password:
mysql> CREATE USER 'exporter'@'%' IDENTIFIED BY 'exporterpassword' WITH MAX_USER_CONNECTIONS 3;
mysql> GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';

Ejecutemos el contenedor exportador de mysqld llamado "mysql8-exporter" para exponer las métricas de nuestra instancia de MySQL 8.0 como se muestra a continuación:

$ docker run -d \
--name mysql80-exporter \
--publish 9104 \
--network db_network \
--restart always \
--env DATA_SOURCE_NAME="exporter:[email protected](mysql80:3306)/" \
prom/mysqld-exporter:latest \
--collect.info_schema.processlist \
--collect.info_schema.innodb_metrics \
--collect.info_schema.tablestats \
--collect.info_schema.tables \
--collect.info_schema.userstats \
--collect.engine_innodb_status

Y también otro contenedor exportador para nuestra instancia de MySQL 5.7:

$ docker run -d \
--name mysql57-exporter \
--publish 9104 \
--network db_network \
--restart always \
-e DATA_SOURCE_NAME="exporter:[email protected](mysql57:3306)/" \
prom/mysqld-exporter:latest \
--collect.info_schema.processlist \
--collect.info_schema.innodb_metrics \
--collect.info_schema.tablestats \
--collect.info_schema.tables \
--collect.info_schema.userstats \
--collect.engine_innodb_status

Habilitamos un montón de indicadores de recopiladores para que el contenedor exponga las métricas de MySQL. También puede habilitar --collect.slave_status, --collect.slave_hosts si tiene una replicación de MySQL ejecutándose en contenedores.

Deberíamos poder recuperar las métricas de MySQL a través de curl desde el host de Docker directamente (el puerto 32771 es el puerto publicado asignado automáticamente por Docker para el contenedor mysql80-exporter):

$ curl 127.0.0.1:32771/metrics
...
mysql_info_schema_threads_seconds{state="waiting for lock"} 0
mysql_info_schema_threads_seconds{state="waiting for table flush"} 0
mysql_info_schema_threads_seconds{state="waiting for tables"} 0
mysql_info_schema_threads_seconds{state="waiting on cond"} 0
mysql_info_schema_threads_seconds{state="writing to net"} 0
...
process_virtual_memory_bytes 1.9390464e+07

En este punto, nuestra arquitectura se parece a esto:

Ahora estamos listos para configurar el servidor Prometheus.

Implementación del servidor Prometheus

En primer lugar, cree el archivo de configuración de Prometheus en ~/prometheus.yml y agregue las siguientes líneas:

$ vim ~/prometheus.yml
global:
  scrape_interval:     5s
  scrape_timeout:      3s
  evaluation_interval: 5s

# Our alerting rule files
rule_files:
  - "alert.rules"

# Scrape endpoints
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'mysql'
    static_configs:
      - targets: ['mysql57-exporter:9104','mysql80-exporter:9104']

  - job_name: 'docker'
    static_configs:
      - targets: ['192.168.55.161:9323']

Desde el archivo de configuración de Prometheus, hemos definido tres trabajos:"prometheus", "mysql" y "docker". El primero es el trabajo de monitorear el propio servidor Prometheus. El siguiente es el trabajo de monitorear nuestros contenedores MySQL llamados "mysql". Definimos los puntos finales en nuestros exportadores de MySQL en el puerto 9104, que expuso las métricas compatibles con Prometheus de las instancias de MySQL 8.0 y 5.7 respectivamente. El "alert.rules" es el archivo de reglas que incluiremos más adelante en la próxima publicación del blog con fines de alerta.

Luego podemos mapear la configuración con el contenedor Prometheus. También necesitamos crear un volumen de Docker para los datos de Prometheus para la persistencia y también exponer el puerto 9090 públicamente:

$ docker run -d \
--name prometheus-server \
--publish 9090:9090 \
--network db_network \
--restart unless-stopped \
--mount type=volume,src=prometheus-data,target=/prometheus \
--mount type=bind,src="$(pwd)"/prometheus.yml,target=/etc/prometheus/prometheus.yml \
--mount type=bind,src="$(pwd)
prom/prometheus

Ahora nuestro servidor Prometheus ya se está ejecutando y se puede acceder directamente en el puerto 9090 del host Docker. Abra un navegador web y vaya a http://192.168.55.161:9090/ para acceder a la interfaz de usuario web de Prometheus. Verifique el estado del objetivo en Estado -> Objetivos y asegúrese de que estén todos en verde:

En este punto, nuestra arquitectura de contenedores se parece a esto:

Nuestro sistema de monitoreo Prometheus para nuestros contenedores MySQL independientes ya está implementado.

Enjambre de estibadores

Implementación de un clúster Galera de 3 nodos

Supongamos que queremos implementar un clúster Galera de tres nodos en Docker Swarm, tendríamos que crear 3 servicios diferentes, cada servicio representando un nodo Galera. Con este enfoque, podemos mantener un nombre de host estático que se pueda resolver para nuestro contenedor Galera, junto con los contenedores exportadores de MySQL que acompañarán a cada uno de ellos. Usaremos la imagen de MariaDB 10.2 mantenida por el equipo de Docker para ejecutar nuestro clúster de Galera.

En primer lugar, cree un archivo de configuración de MySQL para que lo utilice nuestro servicio Swarm:

$ vim ~/my.cnf
[mysqld]

default_storage_engine          = InnoDB
binlog_format                   = ROW

innodb_flush_log_at_trx_commit  = 0
innodb_flush_method             = O_DIRECT
innodb_file_per_table           = 1
innodb_autoinc_lock_mode        = 2
innodb_lock_schedule_algorithm  = FCFS # MariaDB >10.1.19 and >10.2.3 only

wsrep_on                        = ON
wsrep_provider                  = /usr/lib/galera/libgalera_smm.so
wsrep_sst_method                = mariabackup

Cree una red de base de datos dedicada en nuestro Swarm llamada "db_swarm":

$ docker network create --driver overlay db_swarm

Importe nuestro archivo de configuración de MySQL a la configuración de Docker para que podamos cargarlo en nuestro servicio Swarm cuando lo creemos más tarde:

$ cat ~/my.cnf | docker config create my-cnf -

Cree el primer servicio de arranque de Galera, con "gcomm://" como la dirección del clúster denominada "galera0". Este es un servicio transitorio solo para el proceso de arranque. Eliminaremos este servicio una vez que hayamos activado otros 3 servicios de Galera:

$ docker service create \
--name galera0 \
--replicas 1 \
--hostname galera0 \
--network db_swarm \
--publish 3306 \
--publish 4444 \
--publish 4567 \
--publish 4568 \
--config src=my-cnf,target=/etc/mysql/mariadb.conf.d/my.cnf \
--env MYSQL_ROOT_PASSWORD=mypassword \
--mount type=volume,src=galera0-datadir,dst=/var/lib/mysql \
mariadb:10.2 \
--wsrep_cluster_address=gcomm:// \
--wsrep_sst_auth="root:mypassword" \
--wsrep_node_address=galera0

En este punto, la arquitectura de nuestra base de datos se puede ilustrar de la siguiente manera:

Luego, repita el siguiente comando 3 veces para crear 3 servicios de Galera diferentes. Reemplace {nombre} con galera1, galera2 y galera3 respectivamente:

$ docker service create \
--name {name} \
--replicas 1 \
--hostname {name} \
--network db_swarm \
--publish 3306 \
--publish 4444 \
--publish 4567 \
--publish 4568 \
--config src=my-cnf,target=/etc/mysql/mariadb.conf.d/my.cnf \
--env MYSQL_ROOT_PASSWORD=mypassword \
--mount type=volume,src={name}-datadir,dst=/var/lib/mysql \
mariadb:10.2 \
--wsrep_cluster_address=gcomm://galera0,galera1,galera2,galera3 \
--wsrep_sst_auth="root:mypassword" \
--wsrep_node_address={name}

Verifique nuestros servicios Docker actuales:

$ docker service ls 
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
wpcxye3c4e9d        galera0             replicated          1/1                 mariadb:10.2        *:30022->3306/tcp, *:30023->4444/tcp, *:30024-30025->4567-4568/tcp
jsamvxw9tqpw        galera1             replicated          1/1                 mariadb:10.2        *:30026->3306/tcp, *:30027->4444/tcp, *:30028-30029->4567-4568/tcp
otbwnb3ridg0        galera2             replicated          1/1                 mariadb:10.2        *:30030->3306/tcp, *:30031->4444/tcp, *:30032-30033->4567-4568/tcp
5jp9dpv5twy3        galera3             replicated          1/1                 mariadb:10.2        *:30034->3306/tcp, *:30035->4444/tcp, *:30036-30037->4567-4568/tcp

Nuestra arquitectura ahora se parece a esto:

Necesitamos eliminar el servicio Galera bootstrap Swarm, galera0, para que deje de ejecutarse porque si Docker Swarm reprograma el contenedor, se iniciará una nueva réplica con un nuevo volumen nuevo. Corremos el riesgo de pérdida de datos porque --wsrep_cluster_address contiene "galera0" en los otros nodos Galera (o servicios Swarm). Entonces, eliminémoslo:

$ docker service rm galera0

En este punto, tenemos nuestro Galera Cluster de tres nodos:

Ahora estamos listos para implementar nuestro exportador MySQL y Prometheus Server.

Servicio de enjambre de exportador MySQL

Inicie sesión en uno de los nodos de Galera y cree el usuario exportador con los privilegios adecuados:

$ docker exec -it {galera1} mysql -uroot -p
Enter password:
mysql> CREATE USER 'exporter'@'%' IDENTIFIED BY 'exporterpassword' WITH MAX_USER_CONNECTIONS 3;
mysql> GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';

Luego, cree el servicio exportador para cada uno de los servicios de Galera (reemplace {name} con galera1, galera2 y galera3 respectivamente):

$ docker service create \
--name {name}-exporter \
--network db_swarm \
--replicas 1 \
-p 9104 \
-e DATA_SOURCE_NAME="exporter:[email protected]({name}:3306)/" \
prom/mysqld-exporter:latest \
--collect.info_schema.processlist \
--collect.info_schema.innodb_metrics \
--collect.info_schema.tablestats \
--collect.info_schema.tables \
--collect.info_schema.userstats \
--collect.engine_innodb_status

En este punto, nuestra arquitectura se parece a esto con los servicios de exportación en la imagen:

Servicio de enjambre de servidores Prometheus

Finalmente, implementemos nuestro servidor Prometheus. Similar a la implementación de Galera, primero debemos preparar el archivo de configuración de Prometheus antes de importarlo a Swarm usando el comando de configuración de Docker:

$ vim ~/prometheus.yml
global:
  scrape_interval:     5s
  scrape_timeout:      3s
  evaluation_interval: 5s

# Our alerting rule files
rule_files:
  - "alert.rules"

# Scrape endpoints
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'galera'
    static_configs:
      - targets: ['galera1-exporter:9104','galera2-exporter:9104', 'galera3-exporter:9104']

Desde el archivo de configuración de Prometheus, hemos definido tres trabajos:"prometheus" y "galera". El primero es el trabajo de monitorear el propio servidor Prometheus. El siguiente es el trabajo de monitorear nuestros contenedores MySQL llamados "galera". Definimos los puntos finales en nuestros exportadores de MySQL en el puerto 9104, que exponen las métricas compatibles con Prometheus de los tres nodos de Galera respectivamente. El "alert.rules" es el archivo de reglas que incluiremos más adelante en la próxima publicación del blog con fines de alerta.

Importe el archivo de configuración en la configuración de Docker para usarlo con el contenedor de Prometheus más adelante:

$ cat ~/prometheus.yml | docker config create prometheus-yml -

Ejecutemos el contenedor del servidor de Prometheus y publiquemos el puerto 9090 de todos los hosts de Docker para el servicio de interfaz de usuario web de Prometheus:

$ docker service create \
--name prometheus-server \
--publish 9090:9090 \
--network db_swarm \
--replicas 1 \    
--config src=prometheus-yml,target=/etc/prometheus/prometheus.yml \
--mount type=volume,src=prometheus-data,dst=/prometheus \
prom/prometheus

Verifique con el comando del servicio Docker que tenemos 3 servicios Galera, 3 servicios exportadores y 1 servicio Prometheus:

$ docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                         PORTS
jsamvxw9tqpw        galera1             replicated          1/1                 mariadb:10.2                  *:30026->3306/tcp, *:30027->4444/tcp, *:30028-30029->4567-4568/tcp
hbh1dtljn535        galera1-exporter    replicated          1/1                 prom/mysqld-exporter:latest   *:30038->9104/tcp
otbwnb3ridg0        galera2             replicated          1/1                 mariadb:10.2                  *:30030->3306/tcp, *:30031->4444/tcp, *:30032-30033->4567-4568/tcp
jq8i77ch5oi3        galera2-exporter    replicated          1/1                 prom/mysqld-exporter:latest   *:30039->9104/tcp
5jp9dpv5twy3        galera3             replicated          1/1                 mariadb:10.2                  *:30034->3306/tcp, *:30035->4444/tcp, *:30036-30037->4567-4568/tcp
10gdkm1ypkav        galera3-exporter    replicated          1/1                 prom/mysqld-exporter:latest   *:30040->9104/tcp
gv9llxrig30e        prometheus-server   replicated          1/1                 prom/prometheus:latest        *:9090->9090/tcp

Ahora nuestro servidor Prometheus ya se está ejecutando y se puede acceder directamente en el puerto 9090 desde cualquier nodo de Docker. Abra un navegador web y vaya a http://192.168.55.161:9090/ para acceder a la interfaz de usuario web de Prometheus. Verifique el estado del objetivo en Estado -> Objetivos y asegúrese de que estén todos en verde:

En este punto, nuestra arquitectura Swarm se parece a esto:

Continuará..

Ahora tenemos nuestra base de datos y nuestra pila de monitoreo implementada en Docker. En la parte 2 del blog, analizaremos las diferentes métricas de MySQL para vigilar. También veremos cómo configurar las alertas con Prometheus.