1. Tổng quan.
Trong thế giới hiện đại của ứng dụng và hệ thống phức tạp, việc theo dõi và giám sát hệ thống trở nên ngày càng quan trọng. Điều này giúp đảm bảo rằng ứng dụng của bạn hoạt động một cách ổn định, tối ưu hóa tài nguyên, và giải quyết vấn đề ngay khi chúng xuất hiện. Trong bài viết này, chúng ta sẽ tìm hiểu về cách xây dựng một hệ thống theo dõi sử dụng các công cụ phổ biến như Grafana, Prometheus, cAdvisor và Node Exporter.
Prometheus là một hệ thống giám sát và thu thập số liệu mã nguồn mở. Nó hoạt động bằng cách scrape (lấy số liệu) từ các ứng dụng và dịch vụ, sau đó lưu trữ số liệu này trong cơ sở dữ liệu dựa trên time-series. Prometheus cung cấp một ngôn ngữ truy vấn mạnh mẽ để truy cập và biểu đồ số liệu
Grafana là một nền tảng trực quan hóa và giám sát mã nguồn mở. Nó cho phép bạn tạo biểu đồ và bảng điều khiển tùy chỉnh để hiển thị số liệu từ Prometheus và các nguồn dữ liệu khác. Grafana cung cấp một giao diện người dùng dễ sử dụng để theo dõi hiệu suất ứng dụng và hệ thống.
cAdvisor (Container Advisor) là một công cụ giám sát mã nguồn mở được phát triển bởi Google. Nó theo dõi các container Docker và cung cấp thông tin về tài nguyên, hiệu suất và sự hoạt động của chúng. cAdvisor tích hợp dễ dàng với Prometheus để cung cấp số liệu chi tiết về container.
Node Exporter là một phần mềm giám sát mã nguồn mở cho hệ thống máy chủ. Nó thu thập thông tin về tài nguyên hệ thống như CPU, bộ nhớ, đĩa và mạng. Node Exporter là một phần quan trọng để hiểu hiệu suất của máy chủ và hệ thống.
Mô hình hoạt động của hệ thống theo dõi sử dụng Grafana, Prometheus, cAdvisor và Node Exporter như sau:
- Node Exporter chạy trên mỗi máy chủ cần được giám sát. Nó thu thập số liệu từ máy chủ và cung cấp chúng cho Prometheus.
- cAdvisor chạy trên mỗi máy chủ Docker và giám sát các container. Nó cũng cung cấp số liệu cho Prometheus.
- Prometheus là trung tâm thu thập số liệu. Nó lấy số liệu từ Node Exporter, cAdvisor và các ứng dụng khác, sau đó lưu trữ chúng trong cơ sở dữ liệu time-series.
- Grafana kết nối đến Prometheus để truy vấn và hiển thị số liệu. Grafana cho phép bạn tạo biểu đồ, bảng điều khiển và cảnh báo để theo dõi hiệu suất và sự hoạt động của hệ thống.
2. Thực hành.
Sơ đồ.
- Theo dõi sơ đồ trên và bạn thấy mình có 2 máy chủ:
- Máy chủ 1: 192.168.13.200/23 Là máy chủ chạy Docker Host và Monitoring bao gồm Prometheus, Grafana, Node Explore và cAdvisor.
- Máy chủ 2: 192.168.13.184 là máy chủ chỉ chạy Docker, Node Explore và cAdvisor
Bây giờ hãy thiết kế thư mục và file theo cấu trúc sau.
.
├── alertmanager
│ └── config.yml
├── docker-compose.yaml
├── grafana
│ └── provisioning
│ └── dashboards
│ └── dashboard.json
└── prometheus
├── alert.rules
└── prometheus.yml
Tạo các folder chứa các manifest.
mkdir -p /home/asterisk/demo/prometheus
mkdir -p /home/asterisk/demo/alertmanager
mkdir -p /home/asterisk/demo/grafana/provisioning/dashboards
Tạo file config cho Alertmanager.
cat > /home/asterisk/demo/alertmanager/config.yml << 'OEF'
route:
receiver: 'chatwork'
group_by: ['alertname']
group_wait: 15s
group_interval: 5m
repeat_interval: 3h
receivers:
- name: 'chatwork'
webhook_configs:
- url: https://cw-forwarder.sun-asterisk.vn/api/v1/webhooks/498f6b7b661c2651c
send_resolved: false
max_alerts: 3
OEF
Tạo file config lưu thông tin Dashboard cho Grafana.
cat > /home/asterisk/demo/grafana/provisioning/dashboards/dashboard.json << 'OEF'
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"description": "Docker Monitoring Template",
"editable": true,
"fiscalYearStartMonth": 0,
"gnetId": 179,
"graphTooltip": 1,
"id": 1,
"links": [],
"liveNow": false,
"panels": [
{
"collapsed": false,
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 0
},
"id": 17,
"panels": [],
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"refId": "A"
}
],
"title": "Host Info",
"type": "row"
},
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [
{
"options": {
"match": "null",
"result": {
"text": "N/A"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "s"
},
"overrides": []
},
"gridPos": {
"h": 5,
"w": 4,
"x": 0,
"y": 1
},
"id": 15,
"links": [],
"maxDataPoints": 100,
"options": {
"colorMode": "none",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"mean"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "10.1.2",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "time() - process_start_time_seconds{job=\"prometheus\"}",
"format": "time_series",
"intervalFactor": 1,
"refId": "A"
}
],
"title": "Uptime",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"fieldConfig": {
"defaults": {
"color": {
"fixedColor": "rgb(31, 120, 193)",
"mode": "fixed"
},
"mappings": [
{
"options": {
"match": "null",
"result": {
"text": "N/A"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "#d44a3a",
"value": null
},
{
"color": "rgba(237, 129, 40, 0.89)",
"value": 0
},
{
"color": "#299c46",
"value": 1
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 5,
"w": 4,
"x": 4,
"y": 1
},
"id": 31,
"links": [],
"maxDataPoints": 100,
"options": {
"colorMode": "none",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"mean"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "10.1.2",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "count(rate(container_last_seen{job=\"cadvisor\", name!=\"\"}[5m]))",
"format": "time_series",
"intervalFactor": 1,
"refId": "A"
}
],
"title": "Running Containers",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"decimals": 2,
"mappings": [
{
"options": {
"match": "null",
"result": {
"text": "N/A"
}
},
"type": "special"
}
],
"max": 100,
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "rgba(50, 172, 45, 0.97)",
"value": null
},
{
"color": "rgba(237, 129, 40, 0.89)",
"value": 65
},
{
"color": "rgba(245, 54, 54, 0.9)",
"value": 90
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 5,
"w": 4,
"x": 8,
"y": 1
},
"id": 6,
"links": [],
"maxDataPoints": 100,
"options": {
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "10.1.2",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "sum(sum by (container_name)( rate(container_cpu_usage_seconds_total[1m] ) )) / count(node_cpu_seconds_total{mode=\"system\"}) * 100",
"format": "time_series",
"interval": "1m",
"intervalFactor": 1,
"legendFormat": "",
"refId": "A",
"step": 10
}
],
"title": "CPU usage",
"type": "gauge"
},
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [
{
"options": {
"match": "null",
"result": {
"text": "N/A"
}
},
"type": "special"
}
],
"max": 100,
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "rgba(50, 172, 45, 0.97)",
"value": null
},
{
"color": "rgba(237, 129, 40, 0.89)",
"value": 65
},
{
"color": "rgba(245, 54, 54, 0.9)",
"value": 90
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 5,
"w": 3,
"x": 12,
"y": 1
},
"id": 4,
"links": [],
"maxDataPoints": 100,
"options": {
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "10.1.2",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "(sum(node_memory_MemTotal_bytes) - sum(node_memory_MemFree_bytes +node_memory_Buffers_bytes + node_memory_Cached_bytes) ) / sum(node_memory_MemTotal_bytes) * 100",
"format": "time_series",
"interval": "10s",
"intervalFactor": 1,
"refId": "A",
"step": 10
}
],
"title": "Memory usage",
"type": "gauge"
},
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"decimals": 2,
"mappings": [
{
"options": {
"match": "null",
"result": {
"text": "N/A"
}
},
"type": "special"
}
],
"max": 100,
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "rgba(50, 172, 45, 0.97)",
"value": null
},
{
"color": "rgba(237, 129, 40, 0.89)",
"value": 65
},
{
"color": "rgba(245, 54, 54, 0.9)",
"value": 90
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 5,
"w": 3,
"x": 15,
"y": 1
},
"id": 7,
"links": [],
"maxDataPoints": 100,
"options": {
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "10.1.2",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "sum (container_fs_limit_bytes - container_fs_usage_bytes) / sum(container_fs_limit_bytes)",
"interval": "10s",
"intervalFactor": 1,
"metric": "",
"refId": "A",
"step": 10
}
],
"title": "Filesystem usage",
"type": "gauge"
},
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [
{
"options": {
"match": "null",
"result": {
"text": "N/A"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "#d44a3a",
"value": null
},
{
"color": "rgba(237, 129, 40, 0.89)",
"value": 0
},
{
"color": "#299c46",
"value": 1
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 5,
"w": 3,
"x": 18,
"y": 1
},
"id": 11,
"links": [],
"maxDataPoints": 100,
"options": {
"colorMode": "background",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"mean"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "10.1.2",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "sum(up)",
"format": "time_series",
"intervalFactor": 1,
"refId": "A"
}
],
"title": "Targets Online",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [
{
"options": {
"0": {
"text": "N/A"
}
},
"type": "value"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "#299c46",
"value": null
},
{
"color": "rgba(237, 129, 40, 0.89)",
"value": 0
},
{
"color": "#d44a3a",
"value": 1
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 5,
"w": 3,
"x": 21,
"y": 1
},
"id": 13,
"links": [],
"maxDataPoints": 100,
"options": {
"colorMode": "background",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"mean"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "10.1.2",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "sum(ALERTS)",
"format": "time_series",
"intervalFactor": 1,
"refId": "A"
}
],
"title": "Alerts",
"type": "stat"
},
{
"aliasColors": {
"RECEIVE": "#ea6460",
"SENT": "#1f78c1",
"TRANSMIT": "#1f78c1"
},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"fill": 4,
"fillGradient": 0,
"gridPos": {
"h": 8,
"w": 8,
"x": 0,
"y": 6
},
"hiddenSeries": false,
"id": 25,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "10.1.2",
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "sum(rate(container_network_receive_bytes_total{id=\"/\"}[$interval])) by (id)",
"format": "time_series",
"interval": "2m",
"intervalFactor": 2,
"legendFormat": "RECEIVE",
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "- sum(rate(container_network_transmit_bytes_total{id=\"/\"}[$interval])) by (id)",
"format": "time_series",
"interval": "2m",
"intervalFactor": 2,
"legendFormat": "TRANSMIT",
"refId": "B"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Node Network Traffic",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "Bps",
"logBase": 1,
"show": true
},
{
"format": "s",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {
"Available Memory": "#508642",
"Used Memory": "#bf1b00"
},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"fill": 3,
"fillGradient": 0,
"gridPos": {
"h": 8,
"w": 7,
"x": 8,
"y": 6
},
"hiddenSeries": false,
"id": 27,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "10.1.2",
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": true,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "sum(node_memory_MemTotal_bytes) - sum(node_memory_MemAvailable_bytes)",
"format": "time_series",
"interval": "2m",
"intervalFactor": 2,
"legendFormat": "Used Memory",
"refId": "B"
},
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "sum(node_memory_MemAvailable_bytes)",
"format": "time_series",
"interval": "2m",
"intervalFactor": 2,
"legendFormat": "Available Memory",
"refId": "A"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Node Mermory",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "decbytes",
"logBase": 1,
"show": true
},
{
"format": "s",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {
"Available Memory": "#508642",
"Free Storage": "#447ebc",
"Total Storage Available": "#508642",
"Used Memory": "#bf1b00",
"Used Storage": "#bf1b00"
},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"fill": 3,
"fillGradient": 0,
"gridPos": {
"h": 8,
"w": 9,
"x": 15,
"y": 6
},
"hiddenSeries": false,
"id": 28,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "10.1.2",
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": true,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "sum(node_filesystem_free_bytes {job=\"node-exporter\", instance=~\".*9100\", device=~\"/dev/.*\", mountpoint!=\"/var/lib/docker/aufs\"}) ",
"format": "time_series",
"interval": "2m",
"intervalFactor": 2,
"legendFormat": "Free Storage",
"refId": "A"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Filesystem Available",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "decbytes",
"logBase": 1,
"show": true
},
{
"format": "s",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"collapsed": false,
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 14
},
"id": 19,
"panels": [],
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"refId": "A"
}
],
"title": "Container Performance",
"type": "row"
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"decimals": 3,
"editable": true,
"error": false,
"fill": 0,
"fillGradient": 0,
"grid": {},
"gridPos": {
"h": 10,
"w": 6,
"x": 0,
"y": 15
},
"hiddenSeries": false,
"id": 3,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": false,
"min": false,
"rightSide": false,
"show": true,
"sort": "current",
"sortDesc": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "10.1.2",
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "container_cpu_load_average_10s{image!=\"\"}",
"format": "time_series",
"interval": "10s",
"intervalFactor": 1,
"legendFormat": "{{ name }}",
"metric": "container_cpu_user_seconds_total",
"refId": "A",
"step": 10
}
],
"thresholds": [],
"timeRegions": [],
"title": "Container CPU usage",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "percentunit",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"decimals": 2,
"editable": true,
"error": false,
"fill": 0,
"fillGradient": 0,
"grid": {},
"gridPos": {
"h": 10,
"w": 6,
"x": 6,
"y": 15
},
"hiddenSeries": false,
"id": 2,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": false,
"min": false,
"rightSide": false,
"show": true,
"sort": "current",
"sortDesc": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "10.1.2",
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "container_memory_max_usage_bytes{image!=\"\"}",
"format": "time_series",
"interval": "10s",
"intervalFactor": 1,
"legendFormat": "{{ name }}",
"metric": "container_memory_usage:sort_desc",
"refId": "A",
"step": 10
}
],
"thresholds": [],
"timeRegions": [],
"title": "Container Memory Usage",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"columns": [],
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"fontSize": "100%",
"gridPos": {
"h": 10,
"w": 12,
"x": 12,
"y": 15
},
"id": 23,
"links": [],
"scroll": true,
"showHeader": true,
"sort": {
"col": 0,
"desc": true
},
"styles": [
{
"alias": "Time",
"align": "auto",
"dateFormat": "YYYY-MM-DD HH:mm:ss",
"pattern": "Time",
"type": "date"
},
{
"alias": "",
"align": "auto",
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"decimals": 2,
"pattern": "/.*/",
"thresholds": [],
"type": "number",
"unit": "short"
}
],
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "ALERTS",
"format": "table",
"intervalFactor": 1,
"refId": "A"
}
],
"title": "Alerts",
"transform": "table",
"type": "table-old"
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"decimals": 2,
"editable": true,
"error": false,
"fill": 0,
"fillGradient": 0,
"grid": {},
"gridPos": {
"h": 14,
"w": 6,
"x": 0,
"y": 25
},
"hiddenSeries": false,
"id": 8,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": false,
"min": false,
"rightSide": false,
"show": true,
"sort": "current",
"sortDesc": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "10.1.2",
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "sort_desc(sum by (name) (rate(container_network_receive_bytes_total{image!=\"\"}[1m] ) ))",
"interval": "10s",
"intervalFactor": 1,
"legendFormat": "{{ name }}",
"metric": "container_network_receive_bytes_total",
"refId": "A",
"step": 10
}
],
"thresholds": [],
"timeRegions": [],
"title": "Container Network Input",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"decimals": 2,
"editable": true,
"error": false,
"fill": 0,
"fillGradient": 0,
"grid": {},
"gridPos": {
"h": 14,
"w": 6,
"x": 6,
"y": 25
},
"hiddenSeries": false,
"id": 9,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": false,
"min": false,
"rightSide": false,
"show": true,
"sort": "current",
"sortDesc": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "10.1.2",
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"expr": "sort_desc(sum by (name) (rate(container_network_transmit_bytes_total{image!=\"\"}[1m] ) ))",
"format": "time_series",
"intervalFactor": 2,
"legendFormat": "{{ name }}",
"metric": "container_network_transmit_bytes_total",
"refId": "B",
"step": 4
}
],
"thresholds": [],
"timeRegions": [],
"title": "Container Network Output",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": false
}
],
"yaxis": {
"align": false
}
},
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"decimals": 2,
"displayName": "",
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Time"
},
"properties": [
{
"id": "displayName",
"value": "Time"
},
{
"id": "unit",
"value": "time: YYYY-MM-DD HH:mm:ss"
},
{
"id": "custom.align"
}
]
},
{
"matcher": {
"id": "byName",
"options": "Prometheus Version"
},
"properties": [
{
"id": "custom.width",
"value": 204
}
]
}
]
},
"gridPos": {
"h": 14,
"w": 12,
"x": 12,
"y": 25
},
"id": 30,
"links": [],
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"frameIndex": 0,
"showHeader": true,
"sortBy": []
},
"pluginVersion": "10.1.2",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"editorMode": "code",
"expr": "sum by (goos, goversion, instance, version) (prometheus_build_info{})",
"format": "table",
"hide": false,
"instant": false,
"interval": "15m",
"intervalFactor": 2,
"legendFormat": "cAdvisor Version: {{cadvisorVersion}}",
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"editorMode": "code",
"expr": "sum by (kernelVersion, job, instance, cadvisorVersion, osVersion) (cadvisor_version_info{})",
"format": "table",
"hide": false,
"interval": "15m",
"intervalFactor": 2,
"legendFormat": "Prometheus Version: {{version}}",
"range": true,
"refId": "B"
},
{
"datasource": {
"type": "prometheus",
"uid": "d6845e8c-9606-4d7f-b711-2895f53fb803"
},
"editorMode": "code",
"expr": "sum by (goarch, goos, goversion, instance, version) (node_exporter_build_info{})",
"format": "table",
"hide": false,
"interval": "15m",
"intervalFactor": 2,
"legendFormat": "Node-Exporter Version: {{version}}",
"range": true,
"refId": "C"
}
],
"title": "Running Versions",
"transformations": [
{
"id": "seriesToRows",
"options": {
"reducers": []
}
},
{
"id": "joinByField",
"options": {
"byField": "instance",
"mode": "outer"
}
},
{
"id": "organize",
"options": {
"excludeByName": {
"Time 1": true,
"Time 2": true,
"Time 3": true,
"Value #A": true,
"Value #B": true,
"Value #C": true,
"goarch": true,
"goos 1": true,
"goos 2": true,
"goversion": true,
"goversion 1": true,
"goversion 2": true,
"version 1": false
},
"indexByName": {},
"renameByName": {
"Value #B": "",
"cadvisorVersion": "Cadvisor Version",
"goos 1": "",
"goversion 1": "",
"job": "Job",
"kernelVersion": "Cadvisor Kernel Version",
"osVersion": "Cadvisor OS Version",
"version 1": "Prometheus Version",
"version 2": "Node Exporter Version"
}
}
}
],
"type": "table"
}
],
"refresh": "10s",
"schemaVersion": 38,
"style": "dark",
"tags": [
"docker",
"prometheus, ",
"node-exporter",
"cadvisor"
],
"templating": {
"list": [
{
"auto": false,
"auto_count": 30,
"auto_min": "10s",
"current": {
"selected": false,
"text": "1m",
"value": "1m"
},
"hide": 0,
"label": "interval",
"name": "interval",
"options": [
{
"selected": true,
"text": "1m",
"value": "1m"
},
{
"selected": false,
"text": "10m",
"value": "10m"
},
{
"selected": false,
"text": "30m",
"value": "30m"
},
{
"selected": false,
"text": "1h",
"value": "1h"
},
{
"selected": false,
"text": "6h",
"value": "6h"
},
{
"selected": false,
"text": "12h",
"value": "12h"
},
{
"selected": false,
"text": "1d",
"value": "1d"
},
{
"selected": false,
"text": "7d",
"value": "7d"
},
{
"selected": false,
"text": "14d",
"value": "14d"
},
{
"selected": false,
"text": "30d",
"value": "30d"
}
],
"query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d",
"refresh": 2,
"skipUrlSync": false,
"type": "interval"
}
]
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "browser",
"title": "Docker and Host Monitoring w/ Prometheus",
"uid": "64nrElFmk",
"version": 4,
"weekStart": ""
}
OEF
Tạo file cấu hình cho Prometheus.
cat > /home/asterisk/demo/prometheus/prometheus.yml << 'OEF'
global:
scrape_interval: 1s
evaluation_interval: 15s
external_labels:
monitor: 'Project-technical-report'
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
rule_files:
- "/alertmanager/alert.rules"
scrape_configs:
- job_name: prometheus
scrape_interval: 5s
scrape_timeout: 2s
honor_labels: true
static_configs:
- targets: ['prometheus:9090']
- job_name: node-exporter
scrape_interval: 5s
scrape_timeout: 2s
honor_labels: true
static_configs:
- targets: ['node-exporter:9100', '192.168.13.184:9100']
- job_name: cadvisor
scrape_interval: 5s
scrape_timeout: 2s
honor_labels: true
static_configs:
- targets: ['cadvisor:8080', '192.168.13.184:8080']
OEF
Tiếp theo là file chứa các thông tin rules giúp phát hiện cảnh báo.
cat > /home/asterisk/demo/prometheus/alert.rules << 'OEF'
groups:
- name: targets
rules:
- alert: monitor_service_down
expr: up == 0
for: 30s
labels:
severity: critical
annotations:
summary: "Monitor service non-operational"
description: "Service {{ $labels.instance }} is down."
- name: host
rules:
- alert: HighMemoryLoad
expr: (sum(node_memory_MemTotal_bytes) - sum(node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes) ) / sum(node_memory_MemTotal_bytes) * 100 > 85
for: 2m
labels:
severity: warning
annotations:
summary: "Server memory is almost full"
description: "Docker host memory usage is {{ humanize $value}}%. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}."
- name: containers
rules:
- alert: PHP_FPM_Down
expr: absent(container_memory_usage_bytes{name="project-report-php-fpm"})
for: 30s
labels:
severity: critical
annotations:
summary: "PHP-FPM Container is Down"
description: "PHP-FPM container is down for more than 30 seconds."
- alert: MySQL_Down
expr: absent(container_memory_usage_bytes{name="project-report-mysql"})
for: 30s
labels:
severity: critical
annotations:
summary: "MySQL Container is Down"
description: "MySQL container is down for more than 30 seconds."
OEF
Cuối cùng là file Docker Compose.
cat > /home/asterisk/demo/docker-compose.yaml << 'OEF'
version: "3.4"
services:
cadvisor:
image: gcr.io/google-containers/cadvisor:latest
container_name: cadvisor
ports:
- 8080:8080
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- 9090:9090
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
volumes:
- ./prometheus:/etc/prometheus
- prometheus-db:/prometheus
- ./prometheus/alert.rules:/alertmanager/alert.rules
depends_on:
- cadvisor
- node-exporter
- alertmanager
node-exporter:
image: prom/node-exporter
container_name: 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
restart: always
alertmanager:
image: prom/alertmanager:v0.22.2
container_name: alertmanager
volumes:
- ./alertmanager:/etc/alertmanager
command:
- '--config.file=/etc/alertmanager/config.yml'
- '--storage.path=/alertmanager'
ports:
- 9093:9093
restart: unless-stopped
grafana:
image: grafana/grafana
ports:
- 3000:3000
volumes:
- grafana-db:/var/lib/grafana
- ./grafana/provisioning/:/etc/grafana/provisioning/
restart: always
user: "472"
depends_on:
- prometheus
volumes:
grafana-db:
prometheus-db:
OEF
Dưới đây là 1 ví dụ nếu bạn muốn giám sát thêm 1 Docker host, ví dụ Docker host của mình là 192.168.13.184.
cat > /home/asterisk/demo/docker-compose.yaml << 'OEF'
version: "3.4"
services:
cadvisor:
image: gcr.io/google-containers/cadvisor:latest
container_name: cadvisor
ports:
- 8080:8080
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
node-exporter:
image: prom/node-exporter
container_name: 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
restart: always
OEF
Chuẩn bị xong rồi thì thực hiện Run Docker Compose nhé.
docker-compose up -d
Kết quả.
$root@flask-13-200:/home/asterisk/demo# docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
alertmanager "/bin/alertmanager -…" alertmanager running 0.0.0.0:9093->9093/tcp, :::9093->9093/tcp
cadvisor "/usr/bin/cadvisor -…" cadvisor running (healthy) 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp
demo-grafana-1 "/run.sh" grafana running 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
node-exporter "/bin/node_exporter …" node-exporter running 0.0.0.0:9100->9100/tcp, :::9100->9100/tcp
prometheus "/bin/prometheus --c…" prometheus running 0.0.0.0:9090->9090/tcp, :::9090->9090/tcp
Tiếp tục thực hiện Run Docker Compose trên máy host thứ 2 nếu bạn muốn, ví dụ của mình là 192.168.13.184.
$ docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
cadvisor "/usr/bin/cadvisor -…" cadvisor running (healthy) 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp
node-exporter "/bin/node_exporter …" node-exporter running 0.0.0.0:9100->9100/tcp, :::9100->9100/tcp
Tham khảo thêm Dashboard từ trang chủ Grafana, file dashboard ở trên mình lấy từ link dưới này với ID là 179 nhưng mình đã chỉnh sửa lại một số thông tin.
https://grafana.com/grafana/dashboards/179-docker-prometheus-monitoring/
Kết quả Targets trên Prometheus.
Thêm thông tin Datasource trên Grafana.
Import Dashboard và bạn có kết quả.
Kết luận.
Việc xây dựng một hệ thống theo dõi với Grafana, Prometheus, cAdvisor và Node Exporter giúp bạn theo dõi và giám sát hiệu suất của hệ thống một cách hiệu quả. Nhờ vào sự tích hợp mạnh mẽ giữa các công cụ này, bạn có khả năng phát hiện sớm các vấn đề và đảm bảo rằng hệ thống của bạn hoạt động ổn định và tối ưu hóa tài nguyên. Điều này đóng một vai trò quan trọng trong việc đảm bảo sự thành công của ứng dụng và dịch vụ của bạn.