Monitoring MySQL, MariaDB/Galera Cluster ด้วย Prometheus + Grafana

Monitor MySQL, MariaDB Galera Cluster ด้วย Prometheus + Grafana

ก่อนหน้าผู้เขียนก็มีโพสต์เกี่ยวกับเรื่อง Grafana ไปหลายบทความแล้วดูได้ที่นี่ และบทความนี้เราจะมาทำระบบ Monitoring ด้วย Prometheus และ Grafana กันครับ โดยจะใช้ Prometheus ซึ่งเป็น open-source เป็นฐานข้อมูล และใช้ตัว Grafana ทำหน้าที่แสดงค่าต่างๆ โดยใช้ Exporter ดึงข้อมูลหรือ query เพื่อนำมาแสดงค่า ซึ่งเราจะเพิ่ม Exporter หลักๆ 2 ตัวเข้ามาใน Prometheus และ deploy stack ด้วย docker-compose.

1. node-exporter (Server system data collection)
2. mysqld_exporter (MySQL server data collection)

node-exporter เป็น Exporter ตัวหนึ่งใน Prometheus ที่เอาไว้ดึงค่าต่างๆ ของฮาร์ดแวร์ภายในเครื่องเซิร์ฟเวอร์ เช่น CPU, Disk, Memory ฯลฯ เป็นต้น.

mysqld_exporter เป็น Exporter ตัวหนึ่งใน Prometheus ที่เอาไว้ดึงค่าต่างๆ (database status data) จากภายในเครื่องเซิร์ฟเวอร์ MySQL หรือ MariaDB โดยใช้ Grafana มาแสดงข้อมูล metrics ต่างๆ อีกที

credit image: intl.cloud.tencent.com / MySQL Exporter

ส่วน Grafana ก็ขออภิบายสั้นๆ มันเป็นแพลตฟอร์ม open-source/commercial ซอฟต์แวร์ที่ใช้ในการวิเคราะห์ metrics โดยที่ตัว Grafana นั้นจะทำการ query ข้อมูล metrics ผ่าน Data souce ออกมาแสดงในหน้า Dashboard สวยๆ งามๆ ให้เราเข้าใจข้อมูล metrics ได้อย่างง่ายขึ้น (อารมณ์แบบเดียวกันกับ Google Data Studio)

ไม่พูดเยอะ ดู Architecture เลยละกันครับ จะได้เห็นภาพ (มั้ง!!) 55++

Monitoring architecture:

Prometheus

Architecture: MySQL Exporter

credit image: programming.vip

Docker monitoring ด้วย cAdvisor

ไหนๆ ก็ Deploy บน Docker Engine ด้วย Docker-compose แล้ว ฉะนั้นผู้เขียนเลยยัด cAdvisor Exporter อีกตัวสำหรับมอนิเตอร์ Docker เพิ่มเข้าไปในไฟล์ docker-compose.yml

Docker monitoring by using cAdvisor

เริ่มต้นด้วยการสร้าง Docker Engine CE (เราใช้ Ruk-com PaaS ในการสร้างระบบ Monitoring นี้)

Docker Engine CE

หลังจากติดตั้ง Docker Engine CE เสร็จแล้ว ก็จัดเตรียม source code สำหรับ deploy ตัว Prometheus + Grafana (ในบทความนี้ผู้เขียนใช้ https://gitlab.com/) และสร้างโปรเจ๊กต์ใหม่ชื่อ prom-grafana-dock

ถัดไปกลับมาที่ Docker Engine CE Host (หรือเซิร์ฟเวอร์) เพื่อสร้าง public SSH key

วิธีสร้าง public SSH key

เปิด Web SSH ดังรูป

public SSH key

พิมพ์คำสั่ง ssh-keygen สำหรับสร้างคีย์ใหม่ (บรรทัด Overwrite ให้ตอบ “y“)

ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
/root/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:liR24bXteEBErf3mzfDT0qveShUoole8SiJudBQmJE0
The key's randomart image is:
+---[RSA 2048]----+
|   .+E o.o=.     |
|    ..o..+.o. .  |
|      o.+.o*.. . |
|     ..+..+++   .|
|     o +So..o. . |
|    o o.+ ..  =  |
|     o   .   + *.|
|    .       . +.*|
|            .+o+o|
+----[SHA256]-----+

ใช้คำสั่ง cat ดู public key แล้วคัดลอก

cat .ssh/id_rsa.pub

ไปยังหน้า Gitlab เรา จากนั้นกดปุ่ม Add SSH key แล้วนำ key มาวาง

ถัดไปกลับมาที่ Docker Engine CE (หรือเซิร์ฟเวอร์) ให้สร้างโฟร์เดอร์ prom-grafana-dock สำหรับเก็บ source code

ที่ root directory พิมพ์คำสั่งสร้าง directory

mkdir prom-grafana-dock

จากนั้นพิมพ์คำสั่ง cd เพื่อเข้าไปยังไดเรกทอรี

cd prom-grafana-dock

พิมพ์คำสั่ง git init เพื่อ initialize git local

git init

ทำการเชื่อมโยง Local Project กับ Remote Project โดยใช้คำสั่ง git remote

git remote add origin [email protected]:admin948/prom-grafana-dock.git

อย่า! คัดลอกคำสั่งไปวางนะครับ อันนี้เป็น repository แบบ private ไม่ใช่ public!

ถัดไปเราก็สามารถเขียนไฟล์ source code (docker-compose.yml) บนเซิร์ฟเวอร์นี้ได้เลย แล้ว Check-In ด้วยคำสั่ง git add และ git commit เพื่อซิงค์ขึ้นเก็บบน Gitlab

ก่อนที่เราจะได้ Node Stack “Prometheus + Grafana” container เราต้องสร้าง Dockerfile ไฟล์ขึ้นมาก่อนนะครับ จากนั้นจึงนำไป build เป็น image และนำไปรันเป็น container เพื่อใช้งาน Prometheus + Grafana contaniner ต่อไปครับ

เริ่มกันเลย… ได้เวลาเขียนคำสั่งมัดรวมซอฟต์แวร์ต่างๆ ลงไปในไฟล์คอนฟิกและ docker-compose.yml 

Prometheus & Grafana docker-compose

จัดเตรียมความพร้อมสร้างไดเรกทอรีเก็บไฟล์ดังนี้

cd prom-grafana-dock
mkdir grafana
mkdir alertmanager
mkdir prometheus

สร้างไฟล์ config.monitoring

vi grafana/config.monitoring

GF_SECURITY_ADMIN_PASSWORD=grafana_password
GF_USERS_ALLOW_SIGN_UP=false

สร้างไฟล์ config.yml

vi alertmanager/config.yml

route:
  receiver: 'slack'

receivers:
  - name: 'slack'

สร้างไฟล์ alert.rules

vi prometheus/alert.rules

groups:
- name: example
  rules:

  # Alert for any instance that is unreachable for >2 minutes.
  - alert: service_down
    expr: up == 0
    for: 2m
    labels:
      severity: page
    annotations:
      summary: "Instance {{ $labels.instance }} down"
      description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 2 minutes."

  - alert: high_load
    expr: node_load1 > 0.5
    for: 2m
    labels:
      severity: page
    annotations:
      summary: "Instance {{ $labels.instance }} under high load"
      description: "{{ $labels.instance }} of job {{ $labels.job }} is under high load."

สร้างไฟล์ที่ชื่อว่า prometheus.yml

vi prometheus/prometheus.yml

global: 
  external_labels: 
    monitor: devops_monitor
  scrape_interval: 5s
scrape_configs: 
  - job_name: prometheus
    static_configs: 
      - targets: 
        - "localhost:9090"
        
  - job_name: node_exporter
    static_configs:
      - targets:
        - "node_exporter:9100"
        
  - job_name: mysqld_exporter
    static_configs:
      - targets:
        - "mysqld_exporter:9104"

  - job_name: 'node_cadvisor'
    static_configs:
      - targets: 
        - "node_cadvisor:8080"

สร้างไฟล์ docker-compose.yml

version: '3.7'

volumes:
    prometheus_data: {}
    grafana_data: {}

services:

  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus/:/etc/prometheus/
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/usr/share/prometheus/console_libraries'
      - '--web.console.templates=/usr/share/prometheus/consoles'
    ports:
      - 9090:9090
    container_name: prometheus
    links:
      - cadvisor:cadvisor
      - alertmanager:alertmanager
    depends_on:
      - cadvisor
    restart: always

  node-exporter:
    image: prom/node-exporter
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command: 
      - '--path.procfs=/host/proc' 
      - '--path.sysfs=/host/sys'
      - --collector.filesystem.ignored-mount-points
      - "^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)"
    ports:
      - 9100:9100
    container_name: node_exporter
    restart: always
    deploy:
      mode: global

  alertmanager:
    image: prom/alertmanager
    ports:
      - 9093:9093
    container_name: node_alertmanager
    volumes:
      - ./alertmanager/:/etc/alertmanager/
    restart: always
    command:
      - '--config.file=/etc/alertmanager/config.yml'
      - '--storage.path=/alertmanager'

  cadvisor:
    image: google/cadvisor
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    ports:
      - 8080:8080
    container_name: node_cadvisor
    restart: always
    deploy:
      mode: global

  mysqld_exporter:
    image: prom/mysqld-exporter:latest
    depends_on:
      - prometheus
    environment:
      - DATA_SOURCE_NAME='mysqld-exporter:12qwaszx@(dbhost:3306)/'
    ports:
      - 9104:9104
    container_name: mysqld_exporter
    restart: always

  grafana:
    image: grafana/grafana
    depends_on:
      - prometheus
    ports:
      - 3000:3000
    container_name: grafana
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning/:/etc/grafana/provisioning/
    env_file:
      - ./grafana/config.monitoring
    restart: always
    links: 
      - prometheus:prometheus
    environment:
      GF_INSTALL_PLUGINS: grafana-clock-panel, grafana-simple-json-datasource, cloudflare-app, redis-app

ใส่ส่วนของ Grafana container เราได้เพิ่มให้มีการติดตั้งปลั๊กอิน cloudflare-app, redis-app เข้าไปใน Grafana container ด้วย

และผู้เขียนไม่ขออธิบายคำสั่งต่างๆ ในไฟล์ docker-compose.yml นะครับ สามารถศึกษาเพิ่มเติมได้ที่ docker-compose

กรณีขึั้น production ควรมีการกำหนด Firewall เพิ่มเติมเนื่องจากคำสั่งสร้าง Containers จากตัวอย่างนี้เปิดอนุญาตให้เข้าถึงได้ทั้งหมด (0.0.0.0:PORT)

บรรทัดคำว่า DATA_SOURCE_NAME=’mysqld-exporter:12qwaszx@(dbhost:3306)/’
ให้แทนที่ mysqld-exporter, 12qwaszx, และ MySQL connection address (dbhost) ด้วยข้อมูลจริงเซิร์ฟเวอร์คุณ

Deploy MySQL exporter

  • สร้าง MySQL exporter account ที่เซิร์ฟเวอร์ Database Node
mysql -uROOT -pPASSWORD
  • พิมพ์คำสั่ง create account
MariaDB [(none)]> CREATE USER 'mysqld-exporter' IDENTIFIED BY '12qwaszx' WITH MAX_USER_CONNECTIONS 3;

MariaDB [(none)]> GRANT PROCESS, REPLICATION CLIENT, REPLICATION SLAVE, SELECT ON *.* TO 'mysqld-exporter';

MariaDB [(none)]> flush privileges;

ถึดไปก็ Deploy ตัว MySQL exporter ที่เขียนคำสั่งไว้ในไฟล์ docker-compose.yml แล้ว

รัน Build container จากไฟล์สคริปต์ docker-compose.yml

docker-compose up -d

d = option ที่ใช้กำหนดว่า ให้รันแบบ background process

 docker-compose up -d
docker-compose up -d

สร้างไฟล์สคริปต์ Build container

สร้างไฟล์ใหม่ชื่อ prom-grafana-start.sh

#!/bin/bash
# Created by suseman.com

echo "Starting grafana..."
docker-compose up -d grafana
echo "Grafana running http://0.0.0.0:3000/"

echo "Starting prometheus..."
docker-compose up -d prometheus node_exporter mysqld_exporter
echo "Prometheus running http://0.0.0.0:9090/"

ตรวจสอบไฟล์ใน directory “prom-grafana-dock” จะมีลิสต์ดังนี้

-rw-r--r-- 1 root root  945 Apr 12 16:13 docker-compose.yml
drwxr-xr-x 7 root root 4096 Apr 12 16:00 .git
-rw-r--r-- 1 root root  401 Apr 12 16:15 prometheus.yml
-rw-r--r-- 1 root root  278 Apr 12 16:26 prom-grafana-start.sh

เพิ่มไฟล์เข้า git แล้วสั่งซิงค์ขึ้น Gitlab

git add .
git commit -m "Initial commit"

ถัดมาก็ Push ไฟล์ขึั้น Gitlab โดยใช้คำสั่ง git push

git push -u origin master
To [email protected]:admin948/prom-grafana-dock.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

เมื่อไปดูที่ Gitlab ก็จะพบไฟล์ที่ Git Project ของเรา

Gitlab/ prom-grafana-dock

ถัดไปทำการ Deploy Container ด้วยสคริปต์ที่ได้สร้างไว้แล้ว ให้พิมพ์คำสั่ง sh prom-grafana-start.sh

sh prom-grafana-start.sh
docker-compose up -d

ตรวจสอบดู Containers ที่รันอยู่ด้วยคำสั่ง docker-compose ps

docker-compose ps
docker-compose ps

ตรวจสอบสถานะ Prometheus monitoring

กลับไปที่ Prometheus และตรวจสอบสถานะ ให้ไปที่หน้า State -> Target จากนั้นเราจะเห็นว่าสถานะของ Target ตรง State จะเป็น UP (collected monitoring data)

Prometheus monitoring

จากนั้นคอนฟิก Grafana และสร้าง Dashboard สำหรับ Prometheus

Login เข้าสู่ Grafana

เปิด Web browser พิพม์ <IP Address:3000>

User: admin
Pass: admin

ระบบจะขึ้นให้เปลี่ยนรหัสผ่านใหม่

Grafana

ถัดไปให้ทำการ Add Data Source: Prometheus

Add data source

ตรง URL ให้ใส่เป็น http://prometheus:9090

Prometheus

จากนั้นทำการ Import Grafana Dashboard จาก Mysql monitor template (Galera/MariaDB)

Granfina import: Mysql monitoring

Galera/MariaDB – Overview
MariaDB/Galera Cluster
MariaDB overview information
Mysql monitoring

ดู cAdvisor เข้าผ่าน http://<IP Address>:8080

cAdvisor

ดู Prometheus เข้าผ่าน http://<IP Address>:9090/metrics

Prometheus Main Page

กลับไปที่ Prometheus และตรวจสอบสถานะ ให้ไปที่หน้า State -> Target จากนั้นเราจะเห็นว่าสถานะของ Target ตรง State จะเป็น UP (collected monitoring data)

สร้าง Dashboard สำหรับ Docker container monitoring

โดย Import Dashboard จากที่นี่

General Docker monitoring

คำสั่ง Docker อื่นๆ ที่จำเป็น

คำสั่งดู containers ที่รันอยู่

docker-compose ps

คำสั่ง stop containers ทั้งหมด (ที่สร้างขึ้นจาก docker compose)

docker-compose stop

คำสั่งลบ images ทั้งหมด

docker rmi -f $(docker images -a -q)

คำสั่งดูรายชื่อ containers ทั้งหมด

docker container ls
docker ps

คำสั่งเข้าถึง container ที่ต้องการ เช่น container ชื่อ mysqld_exporter

docker exec -it mysqld_exporter /bin/sh

สำหรับบทความนี้คงจบไว้เพียงเท่านี้ หวังว่าจะเป็นประโยชน์ผู้ที่อ่านจบและศึกษาแล้วลองนำไปปรับใช้กับงานที่ทำกันดูนะครับ ^^ และต้องขอขอบคุณ ruk-com cloud ผู้ให้การสนับสนุน PaaS ในการสร้าง Stack ระบบ Monitoring environment นี้ด้วยครับผม.

source:
[1] https://intl.cloud.tencent.com/document/product/457/38553
[2] https://blog.51cto.com/u_10874766/2494690
[3] https://grafana.com/oss/prometheus
[4] https://docs.docker.com/compose/install/
[5] https://intl.cloud.tencent.com/document/product/457/38553
[6] https://severalnines.com/database-blog/how-monitor-mysql-containers-prometheus-deployment-standalone-and-swarm-part-one

Scroll to top