Monitorování je starostí kontejnerů, protože infrastruktura je dynamická. Kontejnery lze běžně vytvářet a ničit a jsou pomíjivé. Jak tedy udržujete přehled o svých instancích MySQL běžících na Dockeru?
Stejně jako u jakékoli softwarové komponenty existuje mnoho možností, které lze použít. Podíváme se na Prometheus jako na řešení vytvořené pro distribuovanou infrastrukturu a velmi dobře funguje s Dockerem.
Toto je dvoudílný blog. V tomto blogu části 1 se budeme zabývat aspektem nasazení našich kontejnerů MySQL s Prometheus a jeho komponentami, které běží jako samostatné kontejnery Docker a služby Docker Swarm. V části 2 se podíváme na důležité metriky ke sledování z našich kontejnerů MySQL a také na integraci se stránkovacími a oznamovacími systémy.
Úvod do Promethea
Prometheus je úplný monitorovací a trendový systém, který zahrnuje vestavěné a aktivní stírání, ukládání, dotazování, vytváření grafů a upozornění na základě dat z časových řad. Společnost Prometheus shromažďuje metriky pomocí mechanismu stahování z nakonfigurovaných cílů v daných intervalech, vyhodnocuje výrazy pravidel, zobrazuje výsledky a může spustit výstrahy, pokud se zjistí, že některá podmínka je pravdivá. Podporuje všechny cílové metriky, které chceme měřit, pokud byste chtěli spouštět MySQL jako kontejnery Docker. Tyto metriky zahrnují metriky fyzických hostitelů, metriky kontejnerů Docker a metriky serveru MySQL.
Podívejte se na následující diagram, který ilustruje architekturu Prometheus (převzato z oficiální dokumentace Prometheus):
Chystáme se nasadit některé kontejnery MySQL (samostatné a Docker Swarm) s kompletním serverem Prometheus, exportérem MySQL (tj. agentem Prometheus pro odhalování metrik MySQL, které pak může server Prometheus seškrábat) a také správcem Alertmanager pro zpracování výstrah na shromážděných metrikách.
Další podrobnosti najdete v dokumentaci Prometheus. V tomto příkladu použijeme oficiální obrázky Docker poskytnuté týmem Prometheus.
Samostatný ukotvitelný panel
Nasazení kontejnerů MySQL
Spusťte dva samostatné servery MySQL na Dockeru, abychom zjednodušili náš návod k nasazení. Jeden kontejner bude používat nejnovější MySQL 8.0 a druhý je MySQL 5.7. Oba kontejnery jsou ve stejné síti Docker s názvem „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 standardně používá nový ověřovací plugin s názvem caching_sha2_password . Pro kompatibilitu s kontejnerem exportéru Prometheus MySQL použijte široce používané mysql_native_password plugin vždy, když na tomto serveru vytvoříme nového uživatele MySQL.
Pro druhý kontejner MySQL se systémem 5.7 provedeme následující:
$ 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
Ověřte, zda naše servery MySQL běží v pořádku:
[[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
V tuto chvíli naše architektura vypadá asi takto:
Začněme je sledovat.
Vystavení metrik Docker společnosti Prometheus
Docker má vestavěnou podporu jako cíl Prometheus, kde můžeme sledovat statistiky enginu Docker. Můžeme to jednoduše povolit vytvořením textového souboru s názvem „daemon.json“ uvnitř hostitele Docker:
$ vim /etc/docker/daemon.json
A přidejte následující řádky:
{
"metrics-addr" : "12.168.55.161:9323",
"experimental" : true
}
Kde 192.168.55.161 je primární IP adresa hostitele Docker. Poté restartujte démona Docker a načtěte změnu:
$ systemctl restart docker
Protože jsme v příkazu spuštění našich kontejnerů MySQL definovali --restart=unless-stoppped, kontejnery se automaticky spustí po spuštění Dockeru.
Nasazení nástroje MySQL Exporter
Než se přesuneme dále, exportér mysqld vyžaduje, aby byl pro účely monitorování použit uživatel MySQL. V našich kontejnerech MySQL vytvořte monitorovacího uživatele:
$ 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'@'%';
Vezměte prosím na vědomí, že se doporučuje nastavit maximální limit připojení pro uživatele, aby nedošlo k přetížení serveru sledováním scrapes při velkém zatížení. Opakujte výše uvedené příkazy na druhém kontejneru, 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'@'%';
Spusťte kontejner exportéru mysqld nazvaný „mysql8-exporter“, abychom odhalili metriky pro naši instanci MySQL 8.0, jak je uvedeno níže:
$ 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
A také další kontejner exportéru pro naši instanci 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
Povolili jsme spoustu příznaků kolektoru pro kontejner, abychom odhalili metriky MySQL. Můžete také povolit --collect.slave_status, --collect.slave_hosts, pokud máte replikaci MySQL spuštěnou na kontejnerech.
Měli bychom být schopni načíst metriky MySQL pomocí curl přímo z hostitele Docker (port 32771 je publikovaný port přiřazený automaticky Dockerem pro kontejner 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
V tuto chvíli naše architektura vypadá asi takto:
Nyní můžeme nastavit server Prometheus.
Nasazení serveru Prometheus
Nejprve vytvořte konfigurační soubor Prometheus na adrese ~/prometheus.yml a přidejte následující řádky:
$ 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']
Z konfiguračního souboru Prometheus jsme definovali tři úlohy – „prometheus“, „mysql“ a „docker“. Prvním z nich je sledování samotného serveru Prometheus. Dalším úkolem je monitorovat naše kontejnery MySQL s názvem "mysql". Definujeme koncové body na našich exportérech MySQL na portu 9104, který odhalil metriky kompatibilní s Prometheus z instancí MySQL 8.0 a 5.7. "alert.rules" je soubor pravidel, který začleníme později do dalšího příspěvku na blogu pro účely upozornění.
Konfiguraci pak můžeme namapovat pomocí kontejneru Prometheus. Potřebujeme také vytvořit svazek Dockeru pro data Prometheus pro stálost a také veřejně vystavit port 9090:
$ 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
Nyní je náš server Prometheus již spuštěn a lze k němu přistupovat přímo na portu 9090 hostitele Docker. Otevřete webový prohlížeč a přejděte na http://192.168.55.161:9090/ pro přístup k webovému uživatelskému rozhraní Prometheus. Ověřte stav cíle v části Stav -> Cíle a ujistěte se, že jsou všechny zelené:
V tuto chvíli vypadá naše kontejnerová architektura asi takto:
Náš monitorovací systém Prometheus pro naše samostatné kontejnery MySQL je nyní nasazen.
Docker Swarm
Nasazení 3uzlového clusteru Galera
Předpokládejme, že chceme nasadit tříuzlový Galera Cluster v Docker Swarm, museli bychom vytvořit 3 různé služby, z nichž každá představuje jeden uzel Galera. Pomocí tohoto přístupu můžeme zachovat staticky rozlišitelný název hostitele pro náš kontejner Galera spolu s kontejnery exportérů MySQL, které budou doprovázet každý z nich. Ke spuštění našeho clusteru Galera budeme používat obraz MariaDB 10.2 spravovaný týmem Docker.
Nejprve vytvořte konfigurační soubor MySQL, který bude používat naše služba 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
Vytvořte vyhrazenou databázovou síť v našem Swarmu s názvem "db_swarm":
$ docker network create --driver overlay db_swarm
Importujte náš konfigurační soubor MySQL do konfigurace Docker, abychom jej mohli načíst do naší služby Swarm, až jej později vytvoříme:
$ cat ~/my.cnf | docker config create my-cnf -
Vytvořte první zaváděcí službu Galera s „gcomm://“ jako adresu clusteru s názvem „galera0“. Toto je přechodná služba pouze pro proces bootstrapping. Jakmile spustíme 3 další služby Galera, tuto službu smažeme:
$ 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
V tomto bodě lze naši databázovou architekturu ilustrovat následovně:
Poté zopakujte následující příkaz 3krát, abyste vytvořili 3 různé služby Galera. Nahraďte {name} za galera1, galera2 a galera3 v tomto pořadí:
$ 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}
Ověřte naše aktuální služby Docker:
$ 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
Naše architektura nyní vypadá asi takto:
Musíme odstranit službu Galera bootstrap Swarm, galera0, abychom ji zastavili v běhu, protože pokud je kontejner přeplánován Docker Swarm, bude spuštěna nová replika s novým svazkem. Vystavujeme se riziku ztráty dat, protože --wsrep_cluster_address obsahuje "galera0" v ostatních uzlech Galera (nebo ve službách Swarm). Pojďme to tedy odstranit:
$ docker service rm galera0
V tomto okamžiku máme náš tříuzlový Galera Cluster:
Nyní jsme připraveni nasadit náš exportér MySQL a Prometheus Server.
MySQL Exporter Swarm Service
Přihlaste se do jednoho z uzlů Galera a vytvořte uživatele exportéra se správnými oprávněními:
$ 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'@'%';
Poté vytvořte službu exportéru pro každou ze služeb Galera (nahraďte {name} galera1, galera2 a galera3 v tomto pořadí):
$ 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
V tuto chvíli naše architektura vypadá asi takto se službami exportérů na obrázku:
Služba Prometheus Server Swarm
Nakonec nasadíme náš server Prometheus. Podobně jako u nasazení Galera musíme nejprve připravit konfigurační soubor Prometheus před jeho importem do Swarmu pomocí příkazu Docker config:
$ 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']
Z konfiguračního souboru Prometheus jsme definovali tři úlohy – „prometheus“ a „galera“. Prvním z nich je sledování samotného serveru Prometheus. Dalším úkolem je monitorovat naše kontejnery MySQL s názvem „galera“. Definujeme koncové body na našich exportérech MySQL na portu 9104, které odhalují metriky kompatibilní s Prometheus ze tří uzlů Galera. "alert.rules" je soubor pravidel, který začleníme později do dalšího příspěvku na blogu pro účely upozornění.
Importujte konfigurační soubor do konfigurace Docker, abyste jej mohli později použít s kontejnerem Prometheus:
$ cat ~/prometheus.yml | docker config create prometheus-yml -
Spusťte kontejner serveru Prometheus a publikujte port 9090 všech hostitelů Docker pro službu webového uživatelského rozhraní 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
Ověřte pomocí příkazu Docker service, že máme 3 služby Galera, 3 exportérské služby a 1 službu 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
Nyní je náš server Prometheus již spuštěn a lze k němu přistupovat přímo na portu 9090 z jakéhokoli uzlu Docker. Otevřete webový prohlížeč a přejděte na http://192.168.55.161:9090/ pro přístup k webovému uživatelskému rozhraní Prometheus. Ověřte stav cíle v části Stav -> Cíle a ujistěte se, že jsou všechny zelené:
V tuto chvíli naše architektura Swarm vypadá asi takto:
Pokračování...
Nyní máme naši databázi a monitorovací zásobník nasazený na Docker. V části 2 blogu se podíváme na různé metriky MySQL, na které bychom měli dávat pozor. Také uvidíme, jak nakonfigurovat upozornění pomocí Prometheus.