Övervakning är ett problem för containrar, eftersom infrastrukturen är dynamisk. Behållare kan rutinmässigt skapas och förstöras och är tillfälliga. Så hur håller du reda på dina MySQL-instanser som körs på Docker?
Som med alla programvarukomponenter finns det många alternativ där ute som kan användas. Vi kommer att titta på Prometheus som en lösning byggd för distribuerad infrastruktur och fungerar mycket bra med Docker.
Det här är en tvådelad blogg. I den här del 1-bloggen kommer vi att täcka distributionsaspekten av våra MySQL-behållare med Prometheus och dess komponenter, som körs som fristående Docker-behållare och Docker Swarm-tjänster. I del 2 kommer vi att titta på de viktiga mätvärdena att övervaka från våra MySQL-behållare, samt integration med personsöknings- och meddelandesystemen.
Introduktion till Prometheus
Prometheus är ett fullständigt övervaknings- och trendsystem som inkluderar inbyggd och aktiv skrapning, lagring, sökning, grafer och varningar baserat på tidsseriedata. Prometheus samlar in mätvärden genom dragmekanism från konfigurerade mål vid givna intervall, utvärderar regeluttryck, visar resultaten och kan utlösa varningar om något villkor observeras vara sant. Den stöder alla målvärden som vi vill mäta om man skulle vilja köra MySQL som Docker-behållare. Dessa mätvärden inkluderar mätvärden för fysiska värdar, Docker-containerstatistik och MySQL-servermätvärden.
Ta en titt på följande diagram som illustrerar Prometheus arkitektur (tagen från Prometheus officiella dokumentation):
Vi kommer att distribuera några MySQL-behållare (fristående och Docker Swarm) kompletta med en Prometheus-server, MySQL-exportör (d.v.s. en Prometheus-agent för att exponera MySQL-mått, som sedan kan skrapas av Prometheus-servern) och även Alertmanager för att hantera varningsbaserade på de insamlade mätvärdena.
För mer information kolla in Prometheus dokumentation. I det här exemplet kommer vi att använda de officiella Docker-bilderna från Prometheus-teamet.
Fristående hamnarbetare
Distribuera MySQL-behållare
Låt oss köra två fristående MySQL-servrar på Docker för att förenkla vår implementeringsgenomgång. En behållare kommer att använda den senaste MySQL 8.0 och den andra är MySQL 5.7. Båda behållarna är i samma Docker-nätverk som kallas "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 ett nytt autentiseringsplugin som heter caching_sha2_password . För kompatibilitet med Prometheus MySQL-exportbehållare, låt oss använda det allmänt använda mysql_native_password plugin när vi skapar en ny MySQL-användare på denna server.
För den andra MySQL-behållaren som kör 5.7, kör vi följande:
$ 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
Kontrollera om våra MySQL-servrar körs 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
Vid det här laget ser vår arkitektur ut ungefär så här:
Låt oss börja övervaka dem.
Exponera Docker Metrics för Prometheus
Docker har inbyggt stöd som Prometheus-mål, där vi kan använda för att övervaka Docker-motorstatistiken. Vi kan helt enkelt aktivera det genom att skapa en textfil som heter "daemon.json" inuti Docker-värden:
$ vim /etc/docker/daemon.json
Och lägg till följande rader:
{
"metrics-addr" : "12.168.55.161:9323",
"experimental" : true
}
Där 192.168.55.161 är Docker-värdens primära IP-adress. Starta sedan om Docker-demonen för att ladda ändringen:
$ systemctl restart docker
Eftersom vi har definierat --restart=unless-stopped i våra MySQL-behållares körkommando, kommer behållarna att startas automatiskt efter att Docker körs.
Distribuera MySQL Exporter
Innan vi går vidare kräver mysqld-exportören att en MySQL-användare används för övervakningsändamål. Skapa övervakningsanvändaren på våra MySQL-behållare:
$ 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'@'%';
Observera att det rekommenderas att sätta en maxgräns för anslutning för användaren för att undvika att överbelasta servern med övervakningsskrap under hög belastning. Upprepa ovanstående påståenden på den andra behållaren, 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'@'%';
Låt oss köra mysqld-exportbehållaren som heter "mysql8-exporter" för att exponera mätvärdena för vår MySQL 8.0-instans enligt nedan:
$ 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
Och även en annan exportörbehållare för vår MySQL 5.7-instans:
$ 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 aktiverade ett gäng samlarflaggor för behållaren för att exponera MySQL-måtten. Du kan också aktivera --collect.slave_status, --collect.slave_hosts om du har en MySQL-replikering som körs på behållare.
Vi borde kunna hämta MySQL-måtten via curl från Docker-värden direkt (port 32771 är den publicerade porten som tilldelas automatiskt av Docker för 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
Vid det här laget ser vår arkitektur ut ungefär så här:
Vi kan nu ställa in Prometheus-servern.
Distribuera Prometheus Server
Skapa först Prometheus konfigurationsfil på ~/prometheus.yml och lägg till följande rader:
$ 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']
Från Prometheus konfigurationsfil har vi definierat tre jobb - "prometheus", "mysql" och "docker". Den första är jobbet att övervaka själva Prometheus-servern. Nästa är jobbet att övervaka våra MySQL-behållare som heter "mysql". Vi definierar slutpunkterna på våra MySQL-exportörer på port 9104, som exponerade Prometheus-kompatibla mätvärden från MySQL 8.0- respektive 5.7-instanserna. "alert.rules" är regelfilen som vi kommer att inkludera senare i nästa blogginlägg i varningssyfte.
Vi kan sedan kartlägga konfigurationen med Prometheus-behållaren. Vi måste också skapa en Docker-volym för Prometheus-data för beständighet och även exponera 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 är vår Prometheus-server redan igång och kan nås direkt på port 9090 hos Docker-värden. Öppna en webbläsare och gå till http://192.168.55.161:9090/ för att komma åt Prometheus webbgränssnitt. Verifiera målstatusen under Status -> Mål och se till att alla är gröna:
Vid det här laget ser vår containerarkitektur ut ungefär så här:
Vårt Prometheus-övervakningssystem för våra fristående MySQL-containrar är nu implementerat.
Docker Swarm
Distribuera ett Galera-kluster med 3 noder
Förutsatt att vi vill distribuera ett Galera-kluster med tre noder i Docker Swarm, måste vi skapa tre olika tjänster, där varje tjänst representerar en Galera-nod. Med detta tillvägagångssätt kan vi behålla ett statiskt lösbart värdnamn för vår Galera-behållare, tillsammans med MySQL-exportbehållare som följer med var och en av dem. Vi kommer att använda MariaDB 10.2-bilden som underhålls av Docker-teamet för att köra vårt Galera-kluster.
Skapa först en MySQL-konfigurationsfil som ska användas av vår Swarm-tjänst:
$ 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
Skapa ett dedikerat databasnätverk i vår Swarm som heter "db_swarm":
$ docker network create --driver overlay db_swarm
Importera vår MySQL-konfigurationsfil till Docker-konfigurationen så att vi kan ladda den till vår Swarm-tjänst när vi skapar den senare:
$ cat ~/my.cnf | docker config create my-cnf -
Skapa den första Galera bootstrap-tjänsten, med "gcomm://" som klusteradress som heter "galera0". Detta är en övergående tjänst endast för bootstrapping-processen. Vi kommer att ta bort den här tjänsten när vi har kört 3 andra Galera-tjänster:
$ 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
Vid det här laget kan vår databasarkitektur illustreras enligt nedan:
Upprepa sedan följande kommando 3 gånger för att skapa 3 olika Galera-tjänster. Ersätt {name} med galera1, galera2 respektive 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}
Verifiera våra nuvarande Docker-tjänster:
$ 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
Vår arkitektur ser nu ut ungefär så här:
Vi måste ta bort Galera bootstrap Swarm-tjänsten, galera0, för att stoppa den från att köras eftersom om behållaren planeras om av Docker Swarm kommer en ny replik att startas med en ny ny volym. Vi löper risk för dataförlust eftersom --wsrep_cluster_address innehåller "galera0" i de andra Galera-noderna (eller Swarm-tjänsterna). Så låt oss ta bort det:
$ docker service rm galera0
Vid det här laget har vi vårt Galera-kluster med tre noder:
Vi är nu redo att distribuera vår MySQL-exportör och Prometheus Server.
MySQL Exporter Swarm Service
Logga in på en av Galera-noderna och skapa exportören med rätt behörighet:
$ 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'@'%';
Skapa sedan exporttjänsten för var och en av Galera-tjänsterna (ersätt {name} med galera1, galera2 respektive 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
Vid det här laget ser vår arkitektur ut ungefär så här med exporttjänster på bilden:
Prometheus Server Swarm Service
Slutligen, låt oss distribuera vår Prometheus-server. I likhet med Galera-distributionen måste vi först förbereda Prometheus-konfigurationsfilen innan vi importerar den till Swarm med Docker-konfigurationskommandot:
$ 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']
Från Prometheus konfigurationsfil har vi definierat tre jobb - "prometheus" och "galera". Den första är jobbet att övervaka själva Prometheus-servern. Nästa är jobbet att övervaka våra MySQL-behållare som heter "galera". Vi definierar slutpunkterna på våra MySQL-exportörer på port 9104, som exponerar Prometheus-kompatibla mätvärden från de tre Galera-noderna. "alert.rules" är regelfilen som vi kommer att inkludera senare i nästa blogginlägg i varningssyfte.
Importera konfigurationsfilen till Docker-konfigurationen för att användas med Prometheus-behållaren senare:
$ cat ~/prometheus.yml | docker config create prometheus-yml -
Låt oss köra Prometheus-serverbehållaren och publicera port 9090 för alla Docker-värdar för Prometheus webbgränssnittstjänst:
$ 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
Verifiera med Docker-tjänstkommandot att vi har 3 Galera-tjänster, 3 exporttjänster och 1 Prometheus-tjänst:
$ 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 är vår Prometheus-server redan igång och kan nås direkt på port 9090 från vilken Docker-nod som helst. Öppna en webbläsare och gå till http://192.168.55.161:9090/ för att komma åt Prometheus webbgränssnitt. Verifiera målstatusen under Status -> Mål och se till att alla är gröna:
Vid det här laget ser vår Swarm-arkitektur ut ungefär så här:
Fortsättning följer...
Vi har nu vår databas och övervakningsstack utplacerad på Docker. I del 2 av bloggen kommer vi att titta på de olika MySQL-måtten att hålla ett öga på. Vi kommer också att se hur du konfigurerar varning med Prometheus.