การสร้าง "ตาและหู" ให้กับระบบ เพื่อการเฝ้าระวัง การวิเคราะห์ และการแก้ไขปัญหาในระดับ Production
ในสัปดาห์ที่ผ่านมา เราเรียนรู้การจัดการ Workloads บน Kubernetes ไปแล้ว
ใช้ควบคุมการ Rollout และ Rollback อย่างปลอดภัย
การสเกลจำนวน Pod อัตโนมัติตามโหลดที่เข้ามา
ด่านหน้ารับ Traffic ระดับ Layer 7 เข้าสู่ Cluster
แยกตัวแปรและตั้งค่าต่างๆ ออกจาก Code หลัก
เมื่อคุณ Deploy ระบบขึ้น Production แล้ว (Day 1) งานของ DevOps ยังไม่จบ!
เราเข้าสู่ Application Performance Management (APM) ซึ่งเป็นเสาหลักที่สามของ DevOps Engineering (ถัดจาก Pull Request Automation และ Deployment Automation)
แม้เราจะมี Code ที่ดีที่สุด แต่ Operational Errors เกิดขึ้นได้เสมอ! ตัวอย่างเช่น มีผู้ใช้พิมพ์ช่องว่าง (Whitespace) เยอะๆ ต่อท้ายโพสต์ จนทำให้ Stack Overflow ล่มมาแล้ว
Monitoring & Logging จะช่วยตอบคำถามว่า: "เกิดอะไรขึ้น?", "ระบบช้าที่ตรงไหน?", "ทำไมผู้ใช้ถึงเจอ Error?" และแจ้งเตือนทีม Engineer ทันทีเพื่อแก้ไข
"ระบบทำงานอยู่หรือไม่? ทรัพยากรใกล้เต็มหรือยัง?"
เน้นการดู Dashboard อาศัยการตั้งค่าล่วงหน้าเพื่อเฝ้าระวังปัญหาที่เรา *คาดว่าจะเกิด* (Known Unknowns)
"ทำไมระบบถึงทำงานผิดปกติ และต้นตอมาจากไหน?"
เน้นการใช้ข้อมูลภายในเพื่อทำความเข้าใจและไขปัญหาที่เรา *ไม่เคยคาดคิดมาก่อน* (Unknown Unknowns)
เสาหลัก 3 ประการที่ทำให้เราสามารถวิเคราะห์ระบบได้อย่างสมบูรณ์
ตัวชี้วัดเชิงปริมาณ (ตัวเลข)
บันทึกเหตุการณ์ (ข้อความ)
การตามรอยระหว่าง Services
Metrics คือจุดข้อมูลที่เป็น "ตัวเลข" ที่วัดได้ในช่วงเวลาต่างๆ (Time Series Data) เพื่อประเมินสุขภาพของระบบ
การเก็บ Metrics ใช้พื้นที่จัดเก็บน้อยมากเมื่อเทียบกับ Logs เพราะเก็บแค่จุดเวลาและตัวเลข
* เกร็ดความรู้: Netflix ต้องเก็บ Metrics แบบ Time Series ถึง 2.5 พันล้านรายการ เพื่อดูแลสุขภาพของระบบระดับโลก!
บางครั้งค่า "เฉลี่ย" (Average) ก็หลอกตาเรา
สมมติว่าเว็บไซต์โหลดเสร็จเฉลี่ยที่ 1 วินาที ดูเหมือนจะดีใช่ไหม?
วิธีแก้: ใช้ Quartile / Percentile Analysis
เรามักจะวัดค่า P95 หรือ P99 (ผู้ใช้ที่ช้าที่สุด 1% หรือ 5% ใช้เวลาเท่าไหร่) ทำให้เราเห็นปัญหาของกลุ่มผู้ใช้ส่วนน้อยได้อย่างชัดเจน
ในขณะที่ Metrics บอกเราว่าเกิดปัญหา (เป็นตัวเลข) Logs คือสิ่งที่จะบอกเราว่า "ปัญหาเกิดจากอะไร" (เป็นข้อความ)
*ปัญหา: Logs มีปริมาณมหาศาลมาก ต้องมีระบบค้นหาที่ดี (เช่น ELK Stack)
เมื่อระบบเปลี่ยนเป็น Microservices การใช้แค่ Logs อาจไม่พอ
สมมติการค้นหาใน Google 1 ครั้ง อาจวิ่งผ่าน 5 Services ถ้าผลลัพธ์ช้า เราจะรู้ได้ยังไงว่า Service ไหนเป็นตัวถ่วง?
Prometheus, DataDog, AWS CloudWatch
ELK Stack (Elasticsearch, Logstash, Kibana), Fluentd, Loki
Grafana, Kibana
ในวิชานี้ เราจะเน้นไปที่ชุด Prometheus + Grafana (สำหรับ Metrics)
และ ELK Stack (สำหรับ Logs)
Prometheus เป็นระบบ Monitoring และ Time Series Database แบบ Open-source (ถูกพัฒนาขึ้นครั้งแรกที่ SoundCloud) ปัจจุบันเป็นมาตรฐานหลัก (De-facto) สำหรับ Kubernetes
จุดแตกต่างสำคัญ: Prometheus ใช้แนวคิด "Pull" (ไปดึงมา) ไม่ใช่ "Push" (รอรับข้อมูล)
Target (เช่น Node, Web App)
Expose ข้อมูลที่ /metrics (เช่น Node Exporter)
Prometheus Server
ตั้งเวลาดึงข้อมูล (เช่น ทุก 15 วินาที)
ข้อดีของ Pull Model:
Prometheus มาพร้อมกับภาษาเฉพาะ (PromQL) สำหรับดึงและคำนวณข้อมูล
# ดึงข้อมูล CPU Usage ของ Node ทั้งหมด
node_cpu_seconds_total
# คำนวณหา อัตราการใช้ CPU ในช่วง 5 นาที (Rate)
rate(node_cpu_seconds_total[5m])
# กรองเฉพาะ HTTP 500 Errors จาก Service ชื่อ "backend"
http_requests_total{status="500", job="backend"}
คำสั่งเหล่านี้จะถูกส่งไปยัง Time Series Database (TSDB) ภายใน Prometheus เพื่อวิเคราะห์
Prometheus เก่งเรื่องการเก็บและคำนวณ แต่ UI ไม่สวย Grafana จึงเข้ามาอุดช่องโหว่นี้
Grafana จะทำหน้าที่เป็น "หน้าต่าง" ดึงข้อมูลจาก Prometheus มาวาดกราฟ
App / Node
Expose Metrics
Prometheus
Scrape & Store TSDB
Grafana
Query PromQL & Plot Graphs
*ในขั้นตอน Lab เราจะทำการเพิ่ม Prometheus เป็น Data Source ในหน้า UI ของ Grafana และสร้าง Dashboard สำหรับดูสถานะ Server (Node Exporter)
เมื่อก่อนเราแค่ SSH เข้าไปใน Server พิมพ์ tail -f /var/log/syslog ก็แก้ปัญหาได้แล้ว
มี Pod 50 ตัว รันกระจายกัน ถ้ามีคนบอกว่า "ล็อกอินไม่ได้" เราจะ SSH เข้าไปหา log ใน Pod ตัวไหน? การค้นหาแบบ Manual เป็นไปไม่ได้อีกต่อไป
ELK Stack เป็นกลุ่มโปรแกรม Open-source ยอดนิยมสำหรับทำ Centralized Logging (รวบรวม Logs ไว้ที่เดียว)
*ผู้ใช้จะส่ง Log จากทุกระบบมาที่ Logstash -> แปลงเสร็จส่งให้ Elasticsearch -> ดูผลผ่าน Kibana
Log ที่มาจากระบบต่างๆ มักจะเป็น Text ธรรมดาที่อ่านยาก Logstash ทำหน้าที่ สกัด (Parse) ให้เป็นโครงสร้าง (Structured Data)
# ขาเข้า (Raw Text)
192.168.1.1 - - [10/Oct/2026:13:55:36] "GET /api/v1/users HTTP/1.1" 500 45
# ขาออก (JSON) ที่จะถูกส่งต่อให้ Elasticsearch
{
"client_ip": "192.168.1.1",
"timestamp": "2026-10-10T13:55:36Z",
"path": "/api/v1/users",
"status": 500
}
เมื่อข้อมูลถูกแปลงเป็น JSON แล้ว จะถูกนำมาเก็บไว้ที่ Elasticsearch
หน้ากาก (UI) ที่ใช้เชื่อมต่อกับ Elasticsearch
"error" AND status:500 บนหน้าจอ Kibana ได้เลยมี Dashboard ที่สวยงามไปก็ไร้ประโยชน์ ถ้าไม่มีใครนั่งดูมัน!
หลักการของ Alerting คือการให้ระบบคอมพิวเตอร์เฝ้าดูกราฟแทนเรา เมื่อเงื่อนไขทาง Metrics แตะจุดวิกฤต (Threshold) ให้ทำการปลุก หรือแจ้งเตือน On-call Engineer ทันที
Prometheus มีเครื่องมือแยกที่ชื่อ Alertmanager เพื่อจัดการเรื่องการแจ้งเตือน
# ตัวอย่างการตั้งเงื่อนไข (Alerting Rule)
alert: HighCpuUsage
expr: rate(node_cpu_seconds_total[5m]) > 0.8
for: 5m # ต้องเป็นไปตามเงื่อนไขนาน 5 นาทีถึงจะแจ้ง (ป้องกันการแกว่งชั่วคราว)
labels:
severity: critical
เมื่อถูก Trigger จะมีการ Routing (ส่งต่อ) ไปยังระบบแจ้งเตือนภายนอก เช่น Slack, Microsoft Teams, Email, PagerDuty หรือ SMS (Twilio)
หากเราตั้งค่าให้ระบบแจ้งเตือนทุกครั้งที่มี CPU พุ่งนิดหน่อย หรือมี Error เล็กๆ น้อยๆ โทรศัพท์ของ Engineer จะดังทั้งวันทั้งคืน
Best Practice:
แจ้งเตือนเฉพาะเมื่อ User Impact เกิดขึ้นแล้วเท่านั้น (เช่น ผู้ใช้เข้าเว็บไม่ได้เลย) และควรรวม Alert ที่เกิดพร้อมกันเป็นก้อนเดียว (Grouping)
ติดตั้ง "หอคอยเฝ้าระวัง" ให้กับ Kubernetes Cluster ของเรา
สร้างระบบเฝ้าระวัง (Monitoring Stack) ของคุณเองด้วย Prometheus, Grafana และ cAdvisor
prometheus.yml) ให้ทำการ Scrape ข้อมูลจาก Nodeสร้างโฟลเดอร์สำหรับเก็บไฟล์ Configuration ของ Monitoring Stack
# 1. สร้างโฟลเดอร์ใหม่และเข้าไปข้างใน
$ mkdir monitoring-stack && cd monitoring-stack
# 2. สร้างไฟล์เปล่าเตรียมไว้สำหรับ Docker Compose และ Prometheus
$ touch docker-compose.yml prometheus.yml
# 3. ตรวจสอบว่าไฟล์ถูกสร้างเรียบร้อยแล้ว
$ ls -l
-rw-r--r-- 1 user group 0 Oct 24 10:00 docker-compose.yml
-rw-r--r-- 1 user group 0 Oct 24 10:00 prometheus.yml
ตั้งค่าให้ Prometheus ไปดึง (Scrape) ข้อมูลจากตัวเอง และจาก cAdvisor
# แก้ไขไฟล์ prometheus.yml
$ nano prometheus.yml
global:
scrape_interval: 15s # ดึงข้อมูลทุกๆ 15 วินาที
scrape_configs:
# 1. ให้ Prometheus มอนิเตอร์ตัวเอง
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# 2. ให้ดึงข้อมูลจาก cAdvisor ที่จะรันในพอร์ต 8080
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080'] # ใช้ชื่อ Service จาก Docker Compose
ประกอบร่าง 3 บริการ (Prometheus, Grafana, cAdvisor) ให้อยู่ใน Stack เดียวกัน
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml # Mount ไฟล์ Config เข้าไป
ports:
- "9090:9090"
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
depends_on:
- prometheus
cadvisor: # เครื่องมือดึง Metrics ของ Docker
image: gcr.io/cadvisor/cadvisor:latest
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
ใช้คำสั่งเพื่อรันทั้ง Stack ขึ้นมาแบบ Background
$ docker-compose up -d
Creating network "monitoring-stack_default" with the default driver
Creating monitoring-stack_cadvisor_1 ... done
Creating monitoring-stack_prometheus_1 ... done
Creating monitoring-stack_grafana_1 ... done
# ตรวจสอบว่าคอนเทนเนอร์รันอยู่ครบ 3 ตัวหรือไม่
$ docker-compose ps
ต้องแน่ใจว่า Prometheus สามารถดึงข้อมูลจาก cAdvisor ได้สำเร็จ
http://localhost:9090prometheus และ cadvisor มีสถานะเป็น UPเปิด http://localhost:3000 แล้วล็อกอินด้วย Username: admin / Password: admin (ระบบจะบังคับให้เปลี่ยนรหัสผ่านใหม่)
http://prometheus:9090 ✅ ควรจะขึ้นกล่องสีเขียวว่า "Data source is working"
# คำสั่ง PromQL คำนวณ CPU Usage (%) ของแต่ละ Container
sum(rate(container_cpu_usage_seconds_total{name!=""}[1m])) by (name) * 100
💡 Pro Tip (ทำ Dashboard อัตโนมัติ):
แทนที่จะสร้างเองทีละกราฟ คุณสามารถไปที่ Dashboards > Import แล้วใส่ ID 893 (หรือ 14282) เพื่อโหลด Dashboard ของ Docker Container (cAdvisor) แบบสำเร็จรูปสวยๆ จาก Grafana.com ได้เลย!
docker-compose.ymlprometheus.yml