kubernetes monitoring prometheus | iCafeFX Network
บทนำ: การเฝ้าสังเกตระบบในโลกของ Kubernetes และบทบาทสำคัญของ Prometheus
ในยุคที่การพัฒนาแอปพลิเคชันหันมาใช้สถาปัตยกรรมแบบไมโครเซอร์วิสและคอนเทนเนอร์กันอย่างแพร่หลาย Kubernetes ได้ก้าวขึ้นมาเป็นแพลตฟอร์มการออร์เคสเทรชันชั้นนำที่ช่วยจัดการกับความซับซ้อนเหล่านี้ อย่างไรก็ตาม พลังอำนาจของ Kubernetes มาพร้อมกับความท้าทายใหม่ โดยเฉพาะอย่างยิ่งในด้าน "การมองเห็น" (Visibility) เราไม่สามารถจัดการสิ่งที่เราไม่เห็นหรือวัดค่าไม่ได้ เมื่อแอปพลิเคชันถูกแบ่งออกเป็นบริการย่อยๆ นับร้อยที่ทำงานในคอนเทนเนอร์ที่เกิดและตายได้ตลอดเวลา วิธีการเฝ้าสังเกตระบบ (Monitoring) แบบเดิมๆ ที่ใช้กับเครื่องเซิร์ฟเวอร์หรือ VM แบบคงที่จึงใช้การไม่ได้อีกต่อไป
นี่คือจุดที่ Prometheus ก้าวเข้ามามีบทบาทสำคัญ Prometheus คือระบบการเฝ้าสังเกตและแจ้งเตือนแบบโอเพนซอร์สที่ถูกออกแบบมาให้ทำงานในสภาพแวดล้อมแบบไดนามิกโดยเฉพาะ ด้วยโมเดลการเก็บข้อมูลแบบ time-series และภาษาสอบถาม (PromQL) ที่ทรงพลัง มันจึงกลายเป็นเครื่องมือมาตรฐานสำหรับการเฝ้าสังเกตระบบ Kubernetes โดยพฤตินัย และเป็นโครงการที่อยู่ภายใต้มูลนิธิ Cloud Native Computing Foundation (CNCF) เช่นเดียวกับ Kubernetes
บทความนี้จะเจาะลึกถึงการนำ Prometheus มาใช้สำหรับการเฝ้าสังเกตระบบ Kubernetes อย่างครอบคลุม ตั้งแต่แนวคิดพื้นฐาน สถาปัตยกรรม วิธีการติดตั้งและกำหนดค่า ไปจนถึงแนวปฏิบัติที่ดีที่สุดและกรณีศึกษาในโลกจริง
ทำความเข้าใจ Prometheus: สถาปัตยกรรมและแนวคิดหลัก
ก่อนที่จะนำ Prometheus ไปใช้กับ Kubernetes เราจำเป็นต้องเข้าใจองค์ประกอบและวิธีการทำงานของมันเสียก่อน Prometheus ไม่ได้เป็นเพียงเครื่องมือเก็บเมตริก แต่เป็นระบบนิเวศที่สมบูรณ์สำหรับการเฝ้าสังเกต
สถาปัตยกรรมหลักของ Prometheus
สถาปัตยกรรมของ Prometheus ประกอบด้วยส่วนประกอบหลักๆ ดังนี้:
- Prometheus Server: หัวใจหลักของระบบ ประกอบด้วยส่วนเก็บข้อมูล time-series และส่วนดึงข้อมูล (Data Retrieval Worker) ที่ทำหน้าที่ดึงเมตริกจาก Target ต่างๆ
- Client Libraries: ไลบรารีสำหรับการส่งเมตริกจากแอปพลิเคชัน (Instrumentation) รองรับหลายภาษา เช่น Go, Java, Python, Ruby
- Pushgateway: เกตเวย์สำหรับรับเมตริกจากงานที่ทำงานระยะสั้น (Short-lived jobs) ที่ไม่สามารถดึงข้อมูล (Pull) แบบตรงๆ ได้
- Exporters: อุปกรณ์ส่งออกเมตริกจากระบบที่สาม (เช่น ฮาร์ดแวร์เซิร์ฟเวอร์, ฐานข้อมูล, เมสเซจจิงคิว) ให้อยู่ในรูปแบบที่ Prometheus เข้าใจ
- Alertmanager: ส่วนจัดการการแจ้งเตือนแยกต่างหาก รับการแจ้งเตือนจาก Prometheus Server แล้วทำการจัดกลุ่ม แยกซ้ำ และส่งไปยังช่องทางที่เหมาะสม เช่น อีเมล, Slack, PagerDuty
- Web UI / Grafana: ส่วนติดต่อผู้ใช้สำหรับแสดงผลและสร้างแดชบอร์ด (โดยทั่วไปนิยมใช้ Grafana เนื่องจากมีความสามารถที่หลากหลายและสวยงามกว่า Web UI ของ Prometheus)
โมเดลข้อมูลและ PromQL
Prometheus เก็บข้อมูลในรูปแบบ time-series ที่มีป้ายกำกับ (Multi-dimensional time-series data) เมตริกแต่ละตัวจะถูกระบุด้วยชื่อเมตริกและคู่คีย์-ค่า (Key-Value Pair) ของป้ายกำกับ (Label)
ตัวอย่างข้อมูลเมตริก:
http_requests_total{method="POST", handler="/api/v1/users", status="200", instance="10.0.0.1:8080", job="user-service"}
พลังที่แท้จริงของ Prometheus อยู่ที่ PromQL (Prometheus Query Language) ซึ่งเป็นภาษาที่ทรงพลังสำหรับการสอบถามและวิเคราะห์ข้อมูลเมตริก
ตัวอย่างการใช้งาน PromQL:
# อัตราการร้องขอ HTTP ต่อวินาทีในช่วง 5 นาทีที่ผ่านมา
rate(http_requests_total[5m])
# ค่าเฉลี่ยการใช้หน่วยความจำของ Pod ทั้งหมดในเนมสเปซ "production"
avg(container_memory_usage_bytes{namespace="production"}) by (pod)
# ค่าเปอร์เซ็นไทล์ที่ 95 ของเวลาในการตอบสนอง
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
การติดตั้งและกำหนดค่า Prometheus บน Kubernetes
มีหลายวิธีในการติดตั้ง Prometheus บนคลัสเตอร์ Kubernetes ตั้งแต่การติดตั้งด้วยมือไปจนถึงการใช้โอเปอเรเตอร์ ซึ่งช่วยลดความซับซ้อนในการจัดการ
วิธีการติดตั้ง
- การใช้ Helm Chart (วิธีที่นิยม): Helm คือตัวจัดการแพ็กเกจสำหรับ Kubernetes การใช้ Chart ของ Prometheus Community ทำให้การติดตั้งทำได้ง่ายและรวดเร็ว
- การใช้ Prometheus Operator (วิธีที่แนะนำสำหรับ Production): โอเปอเรเตอร์จะขยาย Kubernetes API เพื่อสร้าง จัดการ และกำหนดค่าแอปพลิเคชัน Prometheus โดยอัตโนมัติ มันแนะนำ Custom Resource Definitions (CRDs) เช่น Prometheus, ServiceMonitor, PodMonitor ซึ่งทำให้การจัดการมีวินัยและเป็นไปตามแนวคิดของ Kubernetes มากขึ้น
- การ Deploy Manifest ไฟล์ YAML โดยตรง: เหมาะสำหรับการเรียนรู้หรือสภาพแวดล้อมที่จำกัด
ตัวอย่างการติดตั้งด้วย Helm
# เพิ่ม Repo Helm ของชุมชน Prometheus
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# ติดตั้ง Prometheus Stack (รวม Grafana ด้วย)
helm install prometheus-stack prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set grafana.adminPassword="admin"
การกำหนดค่า Service Discovery
หนึ่งในความสามารถที่ยอดเยี่ยมของ Prometheus คือการค้นพบบริการ (Service Discovery) บน Kubernetes โดยอัตโนมัติ Prometheus สามารถค้นหาและดึงเมตริกจาก Pod, Service, Endpoints, และ Node ใหม่ๆ ที่เกิดขึ้นในคลัสเตอร์ได้โดยไม่ต้องกำหนดค่าใหม่ กลไกนี้ทำงานผ่านบทบาท (Role) ของ Kubernetes:
- node: ดึงเมตริกจาก Kubelet ของแต่ละโหนด (เช่น เมตริกคอนเทนเนอร์)
- endpoints: ดึงเมตริกจาก Pod ที่ถูกอ้างอิงโดย Service ของ Kubernetes
- pod: ดึงเมตริกจาก Pod ทั้งหมดโดยตรง (ผ่าน annotation)
- ingress: ดึงเมตริกจาก Ingress resource
การเฝ้าสังเกตส่วนต่างๆ ของ Kubernetes ด้วย Prometheus
การเฝ้าสังเกตคลัสเตอร์ Kubernetes ที่ดีต้องครอบคลุมหลายระดับ (Multi-level)
1. การเฝ้าสังเกตระดับคลัสเตอร์และโหนด
เป็นการตรวจสอบสุขภาพของโครงสร้างพื้นฐานที่ Kubernetes ทำงานอยู่
- Node Resources: การใช้ CPU, Memory, Disk, Network ของแต่ละโหนด ใช้เมตริกจาก `node-exporter`
- สถานะโหนด: โหนดพร้อมทำงาน (Ready) หรือไม่
- เมตริกจาก Kubelet: `kubelet_volume_stats_*`, `kubelet_node_name`
2. การเฝ้าสังเกตระดับ Kubernetes Control Plane
ส่วนนี้สำคัญมาก หาก Control Plane ล้มเหลว คลัสเตอร์ทั้งหมดจะได้รับผลกระทบ
- API Server: อัตราการร้องขอ (Request Rate), เวลาตอบสนอง, อัตราความผิดพลาด
- etcd: ความล่าช้าในการเขียน/อ่าน, ผู้นำของคลัสเตอร์ (Leader), ขนาดฐานข้อมูล
- Controller Manager & Scheduler: ความล่าช้าในการประมวลผลคิว
3. การเฝ้าสังเกตระดับ Workload (แอปพลิเคชัน)
การเฝ้าสังเกตแอปพลิเคชันที่พัฒนาขึ้นเอง ซึ่งสามารถทำได้ 2 วิธีหลัก:
| วิธีการ | รายละเอียด | ข้อดี | ข้อเสีย |
|---|---|---|---|
| Instrumentation (การติดตั้งเครื่องมือในโค้ด) | ใช้ Client Libraries ของ Prometheus เพื่อส่งเมตริกจากภายในแอปพลิเคชันโดยตรง | ได้เมตริกที่เฉพาะเจาะจงกับธุรกิจ (Business Metrics) และการทำงานภายในแอปพลิเคชัน | ต้องแก้ไขโค้ดแอปพลิเคชัน |
| Exporters | รัน Exporter เป็น Sidecar Container ใน Pod เดียวกันกับแอปพลิเคชัน เพื่อแปลงและส่งเมตริกจากแอปพลิเคชัน | ไม่ต้องแก้ไขโค้ดแอปพลิเคชัน เหมาะสำหรับแอปพลิเคชันที่ควบคุมไม่ได้ | ได้เมตริกในระดับที่ตื้นกว่า อาจเพิ่มการใช้ทรัพยากร |
การสร้างแดชบอร์ดและการแจ้งเตือน
การสร้างแดชบอร์ดด้วย Grafana
Grafana คือเครื่องมือสร้างแดชบอร์ดที่นิยมใช้คู่กับ Prometheus มากที่สุด หลังการติดตั้ง เราสามารถนำเข้าเทมเพลตแดชบอร์ดสำเร็จรูปจากชุมชนได้
- แดชบอร์ดสำหรับ Kubernetes: เช่น "Kubernetes / Compute Resources / Cluster" ซึ่งแสดงภาพรวมการใช้ทรัพยากรของคลัสเตอร์
- แดชบอร์ดสำหรับแอปพลิเคชัน: สร้างขึ้นเองโดยใช้เมตริกจากแอปพลิเคชันและ PromQL
การกำหนดกฎการแจ้งเตือน (Alerting Rules)
การแจ้งเตือนที่ได้ผลต้องชัดเจน มีความหมาย และไม่สร้างความรำคาญ Prometheus อนุญาตให้เรากำหนดกฎการแจ้งเตือนในไฟล์ YAML
groups:
- name: kubernetes-resources
rules:
- alert: HighMemoryUsage
expr: (sum(container_memory_usage_bytes{namespace="production"}) by (pod) / sum(kube_pod_container_resource_limits_memory_bytes{namespace="production"}) by (pod)) * 100 > 85
for: 5m
labels:
severity: warning
annotations:
summary: "Pod {{ $labels.pod }} ใช้หน่วยความจำสูง"
description: "Pod {{ $labels.pod }} ในเนมสเปซ {{ $labels.namespace }} ใช้หน่วยความจำเกิน 85% ของลิมิตเป็นเวลา 5 นาทีแล้ว (ค่าปัจจุบัน: {{ $value }}%)"
- alert: PodCrashLooping
expr: rate(kube_pod_container_status_restarts_total{namespace="production"}[5m]) * 300 > 5
for: 2m
labels:
severity: critical
annotations:
summary: "Pod {{ $labels.pod }} กำลัง Crash Loop"
description: "Pod {{ $labels.pod }} รีสตาร์ทมากกว่า 5 ครั้งใน 5 นาทีที่ผ่านมา"
การจัดการการแจ้งเตือนด้วย Alertmanager
Alertmanager รับหน้าที่จัดการการแจ้งเตือนจาก Prometheus Server โดยมีฟีเจอร์สำคัญ:
- การจัดกลุ่ม (Grouping): รวมการแจ้งเตือนที่เกี่ยวข้องกันเป็นกลุ่มเดียว (เช่น การแจ้งเตือนจากโหนดเดียวกัน)
- การแยกซ้ำ (Deduplication): ลดการแจ้งเตือนที่ซ้ำซ้อนสำหรับเหตุการณ์เดียวกัน
- การปราบปราม (Inhibition): ปิด (Suppress) การแจ้งเตือนย่อยเมื่อมีการแจ้งเตือนที่สำคัญกว่าเกิดขึ้นแล้ว (เช่น ปิดการแจ้งเตือนของเซอร์วิสทั้งหมดเมื่อโหนดล่ม)
- การส่งต่อ (Routing): ส่งการแจ้งเตือนไปยังช่องทางที่เหมาะสมตามความรุนแรง (Severity) หรือทีมที่รับผิดชอบ
แนวปฏิบัติที่ดีที่สุดและกรณีศึกษาในโลกจริง
แนวปฏิบัติที่ดีที่สุด (Best Practices)
- ตั้งชื่อเมตริกและป้ายกำกับอย่างมีแบบแผน: ใช้คำนำหน้าที่สื่อความหมาย (เช่น `http_`, `db_`) และกำหนดชุดป้ายกำกับที่สอดคล้องกันทั่วทั้งแอปพลิเคชัน
- หลีกเลี่ยงป้ายกำกับที่มีค่าที่เปลี่ยนแปลงสูง (High Cardinality): การเพิ่มป้ายกำกับเช่น User ID, Session ID โดยตรงจะทำให้จำนวน time-series พุ่งสูงขึ้นจนอาจทำให้ระบบล่มได้ ควรใช้การรวมข้อมูล (Aggregation) หรือบันทึก (Logging) แทน
- ใช้ ServiceMonitor/PodMonitor แทนการกำหนดค่า Static Config: หากใช้ Prometheus Operator ให้ใช้ Custom Resources ในการกำหนดค่าเป้าหมาย ซึ่งสอดคล้องกับแนวคิดของ Kubernetes มากกว่า
- ออกแบบการแจ้งเตือนตามอาการ (Symptom-Based) ไม่ใช่ตามสาเหตุ (Cause-Based): แจ้งเตือนเมื่อผู้ใช้ได้รับผลกระทบ (เช่น อัตราความผิดพลาดสูง, เวลาตอบสนองช้า) แทนที่จะแจ้งเตือนเมื่อทรัพยากรใกล้เต็ม (ซึ่งอาจยังไม่ส่งผลต่อผู้ใช้)
- จัดการอายุข้อมูลและการเก็บข้อมูลระยะยาว: กำหนดค่า `retention` ให้เหมาะสม และพิจารณาใช้ Thanos หรือ Cortex สำหรับการเก็บข้อมูลระยะยาวและมุมมองหลายคลัสเตอร์
กรณีศึกษา: บริษัท E-commerce แห่งหนึ่ง
ปัญหา: ทีม DevOps ไม่สามารถระบุสาเหตุของความล่าช้าในการชำระเงินในช่วง Peak Hour ได้อย่างรวดเร็ว เมตริกจากระบบเดิมครอบคลุมเพียงระดับโหนดและคอนเทนเนอร์เท่านั้น
โซลูชัน:
- ติดตั้ง Prometheus Stack พร้อม Operator บนคลัสเตอร์ Kubernetes
- Instrument ไมโครเซอร์วิส "payment-service" ด้วย Client Library ของ Prometheus (Go) เพื่อส่งเมตริกเช่น `payment_request_duration_seconds`, `payment_status_total`
- สร้าง ServiceMonitor เพื่อให้ Prometheus ดึงเมตริกจาก Pod ของ payment-service โดยอัตโนมัติ
- สร้างแดชบอร์ด Grafana ที่แสดงภาพรวมของระบบชำระเงิน เชื่อมโยงจาก Ingress ลงไปถึงฐานข้อมูล
- ตั้งกฎการแจ้งเตือนเมื่อเวลาในการประมวลผลชำระเงินเปอร์เซ็นไทล์ที่ 95 สูงกว่า 3 วินาที
ผลลัพธ์: เมื่อเกิดปัญหาความล่าช้าในครั้งต่อไป ทีมสามารถใช้ PromQL เพื่อสอบหาได้ทันทีว่าเซอร์วิสใดเป็นคอขวด และพบว่าปัญหามาจากการเชื่อมต่อไปยัง API ภายนอกที่ช้าลง การแจ้งเตือนเกิดขึ้นก่อนที่ทีม Support จะได้รับสายจากลูกค้า และ Mean Time To Resolution (MTTR) ลดลงจาก 45 นาที เหลือเพียง 8 นาที
การเปรียบเทียบ: Prometheus กับเครื่องมือเฝ้าสังเกตระบบอื่นๆ
| คุณลักษณะ | Prometheus | Datadog | Dynatrace |
|---|---|---|---|
| โมเดลการเก็บข้อมูล | Pull-based, Multi-dimensional time-series | Push-based, Multi-dimensional time-series | Push-based, Full-Stack Observability |
| การค้นพบบริการบน K8s | ยอดเยี่ยม (Native Integration) | ดี (ผ่าน Agent) | ดี (ผ่าน OneAgent Operator) |
| ภาษาสอบถาม | PromQL (ทรงพลังมาก) | Query Language (ดี) | Dynatrace Query Language (ดี) |
| ต้นทุน | โอเพนซอร์ส (ไม่มีค่าไลเซนส์) | SaaS/On-Prem แบบเสียค่าใช้จ่าย | SaaS/On-Prem แบบเสียค่าใช้จ่าย |
| เหมาะสำหรับ | องค์กรที่ต้องการควบคุมเต็มที่, ทีมที่มีความชำนาญ, งบประมาณจำกัด | องค์กรที่ต้องการโซลูชันครบวงจรพร้อมใช้งาน, ไม่ต้องการจัดการ infrastructure เอง | องค์กรที่ต้องการ AI-powered observability และการวิเคราะห์รากเหง้าของปัญหาโดยอัตโนมัติ |
Summary
Prometheus ได้พิสูจน์ตัวเองแล้วว่าเป็นเครื่องมือเฝ้าสังเกตระบบที่ขาดไม่ได้สำหรับคลัสเตอร์ Kubernetes ด้วยสถาปัตยกรรมแบบดึงข้อมูล (Pull) ที่เหมาะกับสภาพแวดล้อมแบบไดนามิก โมเดลข้อมูลแบบมีมิติ และภาษาสอบถาม PromQL ที่ทรงพลัง มันให้ความสามารถในการมองเห็นที่ครอบคลุมทุกชั้นของคลัสเตอร์ ตั้งแต่โครงสร้างพื้นฐาน ตัวควบคุม (Control Plane) ไปจนถึงแอปพลิเคชันระดับไมโครเซอร์วิส การผนวกเข้ากับระบบนิเวศ Kubernetes ผ่านการค้นพบบริการอัตโนมัติและโอเปอเรเตอร์ ทำให้การจัดการมีวินัยและง่ายขึ้นอย่างมาก แม้ว่าการเริ่มต้นใช้งานและการออกแบบเมตริกและการแจ้งเตือนที่ดีจะต้องใช้การเรียนรู้และความเข้าใจ แต่ผลตอบแทนที่ได้ในแง่ของความเสถียรของระบบ การแก้ปัญหาได้รวดเร็ว และการตัดสินใจบนพื้นฐานข้อมูลนั้นมีค่าอย่างยิ่ง การผสมผสาน Prometheus กับเครื่องมืออื่นๆ เช่น Grafana สำหรับแดชบอร์ด และ Alertmanager สำหรับการแจ้งเตือน ทำให้ได้โซลูชันการเฝ้าสังเกตระบบแบบครบวงจรที่แข็งแกร่งและเป็นที่นิยมในชุมชน Cloud Native ในท้ายที่สุด การลงทุนกับระบบเฝ้าสังเกตที่เหมาะสมด้วย Prometheus ไม่ใช่แค่เรื่องของเทคนิค แต่คือรากฐานสำคัญของการดำเนินงานแพลตฟอร์ม Kubernetes อย่างมีประสิทธิภาพและน่าเชื่อถือในยุคดิจิทัล