sql >> Database teknologi >  >> RDS >> MariaDB

Sådan overvåger du MySQL-containere med Prometheus - Implementering på Standalone og Swarm::Første del

Overvågning er et problem for containere, da infrastrukturen er dynamisk. Containere kan rutinemæssigt oprettes og ødelægges og er flygtige. Så hvordan holder du styr på dine MySQL-forekomster, der kører på Docker?

Som med enhver softwarekomponent er der mange muligheder derude, som kan bruges. Vi vil se på Prometheus som en løsning bygget til distribueret infrastruktur og fungerer meget godt med Docker.

Dette er en todelt blog. I denne del 1-blog skal vi dække implementeringsaspektet af vores MySQL-containere med Prometheus og dets komponenter, der kører som selvstændige Docker-containere og Docker Swarm-tjenester. I del 2 vil vi se på de vigtige målinger, der skal overvåges fra vores MySQL-containere, samt integration med personsøgnings- og notifikationssystemerne.

Introduktion til Prometheus

Prometheus er et komplet overvågnings- og trendsystem, der inkluderer indbygget og aktiv skrabning, lagring, forespørgsel, graftegning og alarmering baseret på tidsseriedata. Prometheus indsamler metrics gennem pull-mekanisme fra konfigurerede mål med givne intervaller, evaluerer regeludtryk, viser resultaterne og kan udløse advarsler, hvis en betingelse observeres at være sand. Det understøtter alle de målmålinger, som vi ønsker at måle, hvis man gerne vil køre MySQL som Docker-containere. Disse metrics inkluderer fysiske værts-metrics, Docker-container-metrics og MySQL-server-metrics.

Tag et kig på følgende diagram, der illustrerer Prometheus arkitektur (taget fra Prometheus officielle dokumentation):

Vi vil implementere nogle MySQL-containere (standalone og Docker Swarm) komplet med en Prometheus-server, MySQL-eksportør (dvs. en Prometheus-agent for at afsløre MySQL-metrics, som derefter kan skrabes af Prometheus-serveren) og også Alertmanager til at håndtere alarmbaserede på de indsamlede metrics.

Se Prometheus-dokumentationen for flere detaljer. I dette eksempel skal vi bruge de officielle Docker-billeder leveret af Prometheus-teamet.

Fristående docker

Implementering af MySQL-containere

Lad os køre to selvstændige MySQL-servere på Docker for at forenkle vores implementeringsgennemgang. En container vil bruge den nyeste MySQL 8.0, og den anden er MySQL 5.7. Begge containere er i det samme Docker-netværk kaldet "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 har som standard et nyt autentificeringsplugin kaldet caching_sha2_password . For kompatibilitet med Prometheus MySQL-eksporteringsbeholder, lad os bruge det meget brugte mysql_native_password plugin, når vi opretter en ny MySQL-bruger på denne server.

For den anden MySQL-container, der kører 5.7, udfører vi følgende:

$ 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

Bekræft, om vores MySQL-servere kører OK:

[[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

På dette tidspunkt ser vores arkitektur nogenlunde sådan her ud:

Lad os komme i gang med at overvåge dem.

Eksponering af Docker Metrics for Prometheus

Docker har indbygget support som Prometheus-mål, hvor vi kan bruge til at overvåge Docker-motorstatistikken. Vi kan simpelthen aktivere det ved at oprette en tekstfil kaldet "daemon.json" inde i Docker-værten:

$ vim /etc/docker/daemon.json

Og tilføj følgende linjer:

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

Hvor 192.168.55.161 er Docker-værtens primære IP-adresse. Genstart derefter Docker-dæmonen for at indlæse ændringen:

$ systemctl restart docker

Da vi har defineret --restart=unless-stopped i vores MySQL-containers kørselskommando, vil containerne automatisk blive startet efter Docker kører.

Implementering af MySQL Exporter

Før vi går videre, kræver mysqld-eksportøren, at en MySQL-bruger bruges til overvågningsformål. På vores MySQL-containere skal du oprette overvågningsbrugeren:

$ 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'@'%';

Vær opmærksom på, at det anbefales at indstille en maksimal forbindelsesgrænse for brugeren for at undgå at overbelaste serveren med overvågningsskrammer under kraftig belastning. Gentag ovenstående udsagn på den anden beholder, 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'@'%';

Lad os køre mysqld-eksporteringsbeholderen kaldet "mysql8-exporter" for at afsløre metrikkerne for vores MySQL 8.0-forekomst som nedenfor:

$ 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

Og også en anden eksportørbeholder til vores MySQL 5.7-forekomst:

$ 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

Vi aktiverede en masse samlerflag for containeren for at afsløre MySQL-metrikken. Du kan også aktivere --collect.slave_status, --collect.slave_hosts, hvis du har en MySQL-replikering, der kører på containere.

Vi burde være i stand til at hente MySQL-metrikken via curl fra Docker-værten direkte (port 32771 er den offentliggjorte port, der automatisk tildeles af Docker til container 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

På dette tidspunkt ser vores arkitektur nogenlunde sådan her ud:

Vi er nu gode til at konfigurere Prometheus-serveren.

Implementering af Prometheus Server

For det første skal du oprette en Prometheus-konfigurationsfil på ~/prometheus.yml og tilføje følgende linjer:

$ 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']

Fra Prometheus-konfigurationsfilen har vi defineret tre job - "prometheus", "mysql" og "docker". Den første er opgaven med at overvåge selve Prometheus-serveren. Den næste er opgaven med at overvåge vores MySQL-containere med navnet "mysql". Vi definerer endepunkterne på vores MySQL-eksportører på port 9104, som afslørede de Prometheus-kompatible målinger fra henholdsvis MySQL 8.0 og 5.7-forekomsterne. "alert.rules" er regelfilen, som vi vil inkludere senere i det næste blogindlæg til advarselsformål.

Vi kan derefter kortlægge konfigurationen med Prometheus-beholderen. Vi er også nødt til at oprette en Docker-volumen til Prometheus-data for persistens og også afsløre port 9090 offentligt:

$ 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

Nu kører vores Prometheus-server allerede og kan tilgås direkte på port 9090 på Docker-værten. Åbn en webbrowser og gå til http://192.168.55.161:9090/ for at få adgang til Prometheus web-brugergrænseflade. Bekræft målstatussen under Status -> Mål, og sørg for, at de alle er grønne:

På dette tidspunkt ser vores containerarkitektur nogenlunde sådan ud:

Vores Prometheus-overvågningssystem til vores selvstændige MySQL-containere er nu implementeret.

Docker Swarm

Implementering af en 3-node Galera Cluster

Hvis vi ønsker at implementere en Galera-klynge med tre knudepunkter i Docker Swarm, bliver vi nødt til at oprette 3 forskellige tjenester, hvor hver tjeneste repræsenterer en Galera-knude. Ved at bruge denne tilgang kan vi beholde et statisk opløseligt værtsnavn for vores Galera-beholder sammen med MySQL-eksportbeholdere, der vil ledsage hver af dem. Vi vil bruge MariaDB 10.2-image, der vedligeholdes af Docker-teamet til at køre vores Galera-klynge.

Først skal du oprette en MySQL-konfigurationsfil, der skal bruges af vores Swarm-tjeneste:

$ 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

Opret et dedikeret databasenetværk i vores Swarm kaldet "db_swarm":

$ docker network create --driver overlay db_swarm

Importer vores MySQL-konfigurationsfil til Docker-konfigurationen, så vi kan indlæse den i vores Swarm-tjeneste, når vi opretter den senere:

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

Opret den første Galera bootstrap-tjeneste med "gcomm://" som klyngeadressen kaldet "galera0". Dette er en forbigående service kun til bootstrapping-processen. Vi sletter denne tjeneste, når vi har fået 3 andre Galera-tjenester til at køre:

$ 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

På dette tidspunkt kan vores databasearkitektur illustreres som nedenfor:

Gentag derefter følgende kommando 3 gange for at oprette 3 forskellige Galera-tjenester. Erstat {name} med henholdsvis galera1, galera2 og galera3:

$ 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}

Bekræft vores nuværende Docker-tjenester:

$ 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

Vores arkitektur ser nu nogenlunde sådan her ud:

Vi er nødt til at fjerne Galera bootstrap Swarm-tjenesten, galera0, for at stoppe den i at køre, fordi hvis containeren bliver omlagt af Docker Swarm, vil en ny replika blive startet med en frisk ny volumen. Vi risikerer datatab, fordi --wsrep_cluster_address indeholder "galera0" i de andre Galera-noder (eller Swarm-tjenester). Så lad os fjerne det:

$ docker service rm galera0

På dette tidspunkt har vi vores tre-node Galera Cluster:

Vi er nu klar til at implementere vores MySQL-eksportør og Prometheus Server.

MySQL Exporter Swarm Service

Log ind på en af ​​Galera-knuderne og opret eksportørbrugeren med de rette rettigheder:

$ 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'@'%';

Opret derefter eksportørtjenesten for hver af Galera-tjenesterne (erstat {navn} med henholdsvis galera1, galera2 og galera3):

$ 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

På dette tidspunkt ser vores arkitektur noget sådan ud med eksporttjenester på billedet:

Prometheus Server Swarm Service

Lad os endelig implementere vores Prometheus-server. I lighed med Galera-implementeringen skal vi først forberede Prometheus-konfigurationsfilen, før vi importerer den til Swarm ved hjælp af Docker-konfigurationskommandoen:

$ 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']

Fra Prometheus-konfigurationsfilen har vi defineret tre job - "prometheus" og "galera". Den første er opgaven med at overvåge selve Prometheus-serveren. Den næste er opgaven med at overvåge vores MySQL-containere ved navn "galera". Vi definerer endepunkterne på vores MySQL-eksportører på port 9104, som afslører de Prometheus-kompatible målinger fra henholdsvis de tre Galera-knuder. "alert.rules" er regelfilen, som vi vil inkludere senere i det næste blogindlæg til advarselsformål.

Importer konfigurationsfilen til Docker config for at blive brugt med Prometheus container senere:

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

Lad os køre Prometheus-servercontaineren og udgive port 9090 for alle Docker-værter til Prometheus-web-UI-tjenesten:

$ 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

Bekræft med Docker-tjenestekommandoen, at vi har 3 Galera-tjenester, 3 eksporttjenester og 1 Prometheus-tjeneste:

$ 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

Nu kører vores Prometheus-server allerede og kan tilgås direkte på port 9090 fra enhver Docker-knude. Åbn en webbrowser og gå til http://192.168.55.161:9090/ for at få adgang til Prometheus web-brugergrænseflade. Bekræft målstatussen under Status -> Mål, og sørg for, at de alle er grønne:

På dette tidspunkt ser vores Swarm-arkitektur nogenlunde sådan ud:

Fortsættes...

Vi har nu vores database og overvågningsstak installeret på Docker. I del 2 af bloggen vil vi se nærmere på de forskellige MySQL-metrics, som vi skal holde øje med. Vi vil også se, hvordan du konfigurerer alarmering med Prometheus.


  1. Optimeringstærskler – gruppering og aggregering af data, del 4

  2. Retter et ødelagt TOAST-bord

  3. Hvordan NOT LIKE virker i MySQL

  4. TypeORM underforespørgsler