ก่อนหน้าผู้เขียนก็มีโพสต์เกี่ยวกับเรื่อง 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 ต่างๆ อีกที
ส่วน Grafana ก็ขออภิบายสั้นๆ มันเป็นแพลตฟอร์ม open-source/commercial ซอฟต์แวร์ที่ใช้ในการวิเคราะห์ metrics โดยที่ตัว Grafana นั้นจะทำการ query ข้อมูล metrics ผ่าน Data souce ออกมาแสดงในหน้า Dashboard สวยๆ งามๆ ให้เราเข้าใจข้อมูล metrics ได้อย่างง่ายขึ้น (อารมณ์แบบเดียวกันกับ Google Data Studio)
ไม่พูดเยอะ ดู Architecture เลยละกันครับ จะได้เห็นภาพ (มั้ง!!) 55++
Monitoring architecture:
Architecture: MySQL Exporter
Docker monitoring ด้วย cAdvisor
ไหนๆ ก็ Deploy บน Docker Engine ด้วย Docker-compose แล้ว ฉะนั้นผู้เขียนเลยยัด cAdvisor Exporter อีกตัวสำหรับมอนิเตอร์ Docker เพิ่มเข้าไปในไฟล์ docker-compose.yml
เริ่มต้นด้วยการสร้าง Docker Engine CE (เราใช้ Ruk-com PaaS ในการสร้างระบบ Monitoring นี้)
หลังจากติดตั้ง 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 ดังรูป
พิมพ์คำสั่ง 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
สร้างไฟล์สคริปต์ 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 ของเรา
ถัดไปทำการ Deploy Container ด้วยสคริปต์ที่ได้สร้างไว้แล้ว ให้พิมพ์คำสั่ง sh prom-grafana-start.sh
sh prom-grafana-start.sh
ตรวจสอบดู Containers ที่รันอยู่ด้วยคำสั่ง docker-compose ps
docker-compose ps
ตรวจสอบสถานะ Prometheus monitoring
กลับไปที่ Prometheus และตรวจสอบสถานะ ให้ไปที่หน้า State -> Target จากนั้นเราจะเห็นว่าสถานะของ Target ตรง State จะเป็น UP (collected monitoring data)
จากนั้นคอนฟิก Grafana และสร้าง Dashboard สำหรับ Prometheus
Login เข้าสู่ Grafana
เปิด Web browser พิพม์ <IP Address:3000>
User: admin
Pass: admin
ระบบจะขึ้นให้เปลี่ยนรหัสผ่านใหม่
ถัดไปให้ทำการ Add Data Source: Prometheus
ตรง URL ให้ใส่เป็น http://prometheus:9090
จากนั้นทำการ Import Grafana Dashboard จาก Mysql monitor template (Galera/MariaDB)
Granfina import: Mysql monitoring
ดู cAdvisor เข้าผ่าน http://<IP Address>:8080
ดู Prometheus เข้าผ่าน http://<IP Address>:9090/metrics
กลับไปที่ Prometheus และตรวจสอบสถานะ ให้ไปที่หน้า State -> Target จากนั้นเราจะเห็นว่าสถานะของ Target ตรง State จะเป็น UP (collected monitoring data)
สร้าง Dashboard สำหรับ Docker container monitoring
โดย Import Dashboard จากที่นี่
คำสั่ง Docker อื่นๆ ที่จำเป็น
คำสั่งดู containers ที่รันอยู่
docker-compose ps
คำสั่ง stop containers ทั้งหมด (ที่สร้างขึ้นจาก docker compose)
docker-compose stop
คำสั่งลบ images ทั้งหมด
docker rmi -f $(docker images -a -q)
คำสั่งดูรายชื่อ containers ทั้งหมด
docker container ls
คำสั่งเข้าถึง 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