Triển khai Hệ thống giám sát và cảnh báo toàn diện với Prometheus, Grafana và Alertmanager

1. Cài đặt Prometheus

Prometheus là một hệ thống giám sát và cảnh báo mã nguồn mở, được xây dựng bằng ngôn ngữ Go và hỗ trợ nhiều client khác nhau. Để bắt đầu, chúng ta cần tải và cấu hình Prometheus.

Bạn có thể tải Prometheus từ trang chính thức: https://prometheus.io/download/

1.1. Tải và giải nén Prometheus

Trong ví dụ này, chúng ta sẽ cài đặt Prometheus vào thư mục /opt/prometheus.

wget https://github.com/prometheus/prometheus/releases/download/v2.37.6/prometheus-2.37.6.linux-amd64.tar.gz
sudo mkdir -p /opt/prometheus
sudo tar xvf prometheus-2.37.6.linux-amd64.tar.gz -C /opt/prometheus/
cd /opt/prometheus/prometheus-2.37.6.linux-amd64/

1.2. Điều chỉnh tệp cấu hình chính: prometheus.yml

Tệp prometheus.yml là trái tim của Prometheus, định nghĩa cách nó thu thập dữ liệu, đánh giá quy tắc và tích hợp với Alertmanager. Tạo các thư mục cần thiết cho cấu hình và tệp JSON:

sudo mkdir -p conf/{json,rules}
sudo vim prometheus.yml

Nội dung cấu hình:

# Cấu hình toàn cục
global:
  scrape_interval: 15s # Tần suất thu thập metrics. Mặc định là 1 phút.
  evaluation_interval: 15s # Tần suất đánh giá các quy tắc cảnh báo. Mặc định là 1 phút.

# Cấu hình Alertmanager
alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - 192.168.53.180:9093 # Địa chỉ của Alertmanager

# Tải các tệp quy tắc cảnh báo
rule_files:
  - "conf/rules/*.yml"

# Cấu hình thu thập metrics
scrape_configs:
  # Tự giám sát Prometheus
  - job_name: "prometheus-server"
    static_configs:
      - targets: ["localhost:9090"]

  # Giám sát các exporter khác thông qua cơ chế khám phá dịch vụ (file_sd)
  - job_name: 'node-exporter-mon'
    file_sd_configs:
    - files:
       - 'conf/json/node-exporter-*.json'
  - job_name: 'redis-exporter-mon'
    file_sd_configs:
    - files:
       - 'conf/json/redis-exporter-*.json'
  - job_name: 'mysql-exporter-mon'
    file_sd_configs:
    - files:
       - 'conf/json/mysql-exporter-*.json'
  - job_name: 'nginx-exporter-mon'
    file_sd_configs:
    - files:
       - 'conf/json/nginx-exporter-*.json'
  - job_name: 'blackbox-exporter-mon'
    metrics_path: /probe
    params:
      module: [tcp_connect]
    file_sd_configs:
    - files:
       - 'conf/json/blackbox-exporter-*.json'
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: 192.168.53.181:9006     # Địa chỉ của Blackbox Exporter
  - job_name: 'jmx-exporter-mon'
    file_sd_configs:
    - files:
       - 'conf/json/jmx-exporter-*.json'
  - job_name: 'docker-exporter-mon'
    file_sd_configs:
    - files:
       - 'conf/json/docker-exporter-*.json'
  - job_name: 'api-exporter-mon'
    scrape_interval: 15s
    metrics_path: /actuator/prometheus
    file_sd_configs:
    - files:
       - 'conf/json/api-exporter-*.json'

1.3. Cấu hình quy tắc cảnh báo

Prometheus sử dụng các tệp quy tắc để định nghĩa các ngưỡng cảnh báo. Chúng ta sẽ tạo một tệp node-rule.yml trong thư mục conf/rules/.

cd conf/rules/
sudo vim node-rule.yml

Dưới đây là một ví dụ về các quy tắc cảnh báo cho máy chủ vật lý, bao gồm CPU, bộ nhớ, trạng thái máy chủ, IO đĩa, băng thông mạng và dung lượng đĩa:

groups:
- name: alert-examples
  rules:
  - alert: HighNginxRequests
    expr: sum(irate(nginx_server_requests{instance="181-nginx", code="2xx"}[5m])) by (code)>1000
    for: 2s
    labels:
      severity: critical
    annotations:
      summary: "Yêu cầu Nginx tăng cao"
      description: "Máy chủ Nginx {{ $labels.instance }} nhận hơn 1000 yêu cầu 2xx trong 2 giây gần nhất."

- name: PhysicalNodeStatusAlerts
  rules:
  - alert: HighCPULoad
    expr: 100 - avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by(instance)*100 > 10
    for: 2s
    labels:
      severity: critical
    annotations:
      summary: "CPU {{ $labels.instance }} sử dụng cao"
      description: "CPU của máy chủ {{ $labels.instance }} vượt quá 10% (hiện tại: {{ $value | humanizePercentage }}). Cần kiểm tra ngay."

  - alert: HighMemoryUsage
    expr: (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) / node_memory_MemTotal_bytes * 100 > 20
    for: 2s
    labels:
      severity: critical
    annotations:
      summary: "Bộ nhớ {{ $labels.instance }} sử dụng cao"
      description: "Bộ nhớ của máy chủ {{ $labels.instance }} vượt quá 20% (hiện tại: {{ $value | humanizePercentage }}). Cần kiểm tra ngay."

  - alert: InstanceDown
    expr: up == 0
    for: 2s
    labels:
      severity: critical
    annotations:
      summary: "Máy chủ {{ $labels.instance }} không hoạt động"
      description: "Máy chủ {{ $labels.instance }} không phản hồi trong hơn 2 giây."

  - alert: DiskIOPerformanceIssue
    expr: 100 - (avg(irate(node_disk_io_time_seconds_total[1m])) by(instance) * 100) < 60
    for: 2s
    labels:
      severity: critical
    annotations:
      summary: "Hiệu suất IO đĩa {{ $labels.instance }} thấp"
      description: "Hiệu suất IO đĩa của máy chủ {{ $labels.instance }} dưới 60% (hiện tại: {{ $value | humanizePercentage }}). Có thể có vấn đề."

  - alert: HighNetworkReceiveBandwidth
    expr: ((sum(rate (node_network_receive_bytes_total{device!~'tap.*|veth.*|br.*|docker.*|virbr*|lo*'}[5m])) by (instance)) / 100) > 102400
    for: 2s
    labels:
      severity: critical
    annotations:
      summary: "Băng thông mạng đầu vào {{ $labels.instance }} cao"
      description: "Băng thông mạng đầu vào của máy chủ {{ $labels.instance }} vượt quá 100MB/s trong 5 phút. Tỷ lệ sử dụng RX: {{ $value | humanizeBytes }}."

  - alert: HighNetworkTransmitBandwidth
    expr: ((sum(rate (node_network_transmit_bytes_total{device!~'tap.*|veth.*|br.*|docker.*|virbr*|lo*'}[5m])) by (instance)) / 100) > 102400
    for: 2s
    labels:
      severity: critical
    annotations:
      summary: "Băng thông mạng đầu ra {{ $labels.instance }} cao"
      description: "Băng thông mạng đầu ra của máy chủ {{ $labels.instance }} vượt quá 100MB/s trong 5 phút. Tỷ lệ sử dụng TX: {{ $value | humanizeBytes }}."

  - alert: HighTCPConnections
    expr: node_netstat_Tcp_CurrEstab > 1000
    for: 2s
    labels:
      severity: critical
    annotations:
      summary: "Số lượng kết nối TCP {{ $labels.instance }} cao"
      description: "Số lượng kết nối TCP ESTABLISHED trên máy chủ {{ $labels.instance }} vượt quá 1000 (hiện tại: {{ $value }})."

  - alert: DiskCapacityHigh
    expr: 100 - (node_filesystem_free_bytes{fstype=~"ext4|xfs"}/node_filesystem_size_bytes {fstype=~"ext4|xfs"}*100) > 80
    for: 2s
    labels:
      severity: critical
    annotations:
      summary: "Dung lượng đĩa {{ $labels.instance }} cao"
      description: "Dung lượng đĩa trên phân vùng {{ $labels.mountpoint }} của máy chủ {{ $labels.instance }} vượt quá 80% (hiện tại: {{ $value | humanizePercentage }})."

1.4. Thiết lập dịch vụ Prometheus với Systemd

Để quản lý Prometheus dễ dàng hơn, chúng ta sẽ tạo một tệp dịch vụ Systemd.

sudo vim /etc/systemd/system/prometheus.service

Nội dung tệp prometheus.service:

[Unit]
Description=Prometheus Monitoring System
Documentation=https://prometheus.io/docs/introduction/overview/
After=network.target

[Service]
ExecStart=/opt/prometheus/prometheus-2.37.6.linux-amd64/prometheus \
  --config.file=/opt/prometheus/prometheus-2.37.6.linux-amd64/prometheus.yml \
  --web.listen-address=:9090 \
  --web.enable-lifecycle \
  --storage.tsdb.path=/opt/prometheus/prometheus-2.37.6.linux-amd64/data \
  --storage.tsdb.retention.time=15d
Restart=always
RestartSec=5s

[Install]
WantedBy=multi-user.target

Lưu ý: Thêm --web.enable-lifecycle để cho phép Prometheus tải lại cấu hình mà không cần khởi động lại dịch vụ thông qua API /-/reload.

sudo systemctl daemon-reload
sudo systemctl start prometheus
sudo systemctl enable prometheus

Bạn có thể truy cập giao diện web của Prometheus tại http://<Prometheus_IP>:9090.

2. Cài đặt Node Exporter

Node Exporter thu thập các metrics hệ thống của máy chủ (CPU, RAM, đĩa, mạng). Bạn nên cài đặt nó trên mỗi máy chủ mà bạn muốn giám sát.

Tải Node Exporter từ trang chính thức: https://prometheus.io/download/

2.1. Cài đặt và khởi chạy Node Exporter

Trên máy chủ cần giám sát (ví dụ: 192.168.53.181192.168.53.182):

wget https://github.com/prometheus/node_exporter/releases/download/v1.1.2/node_exporter-1.1.2.linux-amd64.tar.gz
sudo mkdir -p /opt/exporter/node_exporter
sudo tar xvf node_exporter-1.1.2.linux-amd64.tar.gz -C /opt/exporter/node_exporter/ --strip-components=1
cd /opt/exporter/node_exporter/
./node_exporter --web.listen-address=:9004 &

Thay vì chạy nền thủ công, bạn nên tạo một dịch vụ Systemd cho Node Exporter để đảm bảo nó luôn chạy và tự khởi động cùng hệ thống.

sudo vim /etc/systemd/system/node_exporter.service

Nội dung tệp node_exporter.service:

[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=root
Group=root
ExecStart=/opt/exporter/node_exporter/node_exporter --web.listen-address=":9004"
Restart=always
RestartSec=5s

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl start node_exporter
sudo systemctl enable node_exporter

2.2. Cấu hình khám phá dịch vụ cho Prometheus

Prometheus sẽ tự động phát hiện các Node Exporter thông qua tệp JSON. Tạo tệp này trong thư mục conf/json mà chúng ta đã định nghĩa trong prometheus.yml.

sudo vim /opt/prometheus/prometheus-2.37.6.linux-amd64/conf/json/node-exporter-instances.json

Nội dung tệp node-exporter-instances.json:

[
 {
  "labels": {
   "environment": "dev",
   "hostname": "server-01",
   "instance": "181-node-dev"
  },
  "targets": [
   "192.168.53.181:9004"
  ]
 },
 {
  "labels": {
   "environment": "test",
   "hostname": "server-02",
   "instance": "182-node-test"
  },
  "targets": [
   "192.168.53.182:9004"
  ]
 }
]

Sau khi cập nhật tệp JSON, bạn cần yêu cầu Prometheus tải lại cấu hình:

curl -X POST http://localhost:9090/-/reload

Truy cập giao diện web Prometheus (http://<Prometheus_IP>:9090/targets) để xác minh các Node Exporter đã được phát hiện.

3. Cài đặt Grafana

Grafana cung cấp giao diện trực quan và dễ sử dụng để hiển thị dữ liệu từ Prometheus. Nó giúp biến các metrics thô thành các biểu đồ và bảng điều khiển dễ hiểu.

Bạn có thể tải Grafana từ: https://grafana.com/grafana/download/ hoặc sử dụng kho lưu trữ Yum/APT.

3.1. Cài đặt Grafana trên CentOS/RHEL

sudo yum install -y grafana-9.3.6-1.x86_64.rpm

3.2. Khởi chạy và cấu hình Grafana

sudo systemctl start grafana-server
sudo systemctl enable grafana-server

Grafana thường chạy trên cổng 3000. Bạn có thể truy cập nó tại http://<Grafana_IP>:3000. Tên người dùng và mật khẩu mặc định là admin/admin. Bạn sẽ được yêu cầu đổi mật khẩu lần đầu đăng nhập.

3.3. Thêm nguồn dữ liệu Prometheus

  1. Đăng nhập vào Grafana.
  2. Chọn biểu tượng bánh răng (Configuration) ở thanh bên trái, sau đó chọn "Data Sources".
  3. Nhấp vào "Add data source" và chọn "Prometheus".
  4. Trong trường "URL", nhập địa chỉ của máy chủ Prometheus của bạn (ví dụ: http://localhost:9090).
  5. Nhấp vào "Save & test". Bạn sẽ thấy thông báo "Data source is working".

3.4. Nhập bảng điều khiển giám sát (Dashboards)

Grafana có một thư viện lớn các bảng điều khiển được cộng đồng chia sẻ. Bạn có thể tải chúng từ https://grafana.com/grafana/dashboards/. Đối với Node Exporter, một ID dashboard phổ biến là 1860.

  1. Chọn biểu tượng "Dashboards" (hình vuông) ở thanh bên trái, sau đó chọn "Import".
  2. Nhập ID của bảng điều khiển (ví dụ: 1860 cho Node Exporter Full) hoặc tải lên tệp JSON của bảng điều khiển.
  3. Chọn nguồn dữ liệu Prometheus mà bạn đã cấu hình.
  4. Nhấp vào "Import".

Các biến như "interval", "environment", "hostname", "node" trong dashboard sẽ tự động đọc từ các label mà bạn đã định nghĩa trong tệp node-exporter-instances.json. Đảm bảo rằng các label trong tệp JSON của bạn khớp với các biến mà dashboard mong đợi để hiển thị dữ liệu chính xác.

4. Cấu hình Alertmanager

Alertmanager xử lý các cảnh báo được gửi bởi Prometheus, nhóm chúng, loại bỏ trùng lặp và định tuyến chúng đến các receiver phù hợp như email, Slack, PagerDuty, v.v.

Tải Alertmanager từ: https://github.com/prometheus/alertmanager/releases

4.1. Cài đặt Alertmanager

wget https://github.com/prometheus/alertmanager/releases/download/v0.25.0/alertmanager-0.25.0.linux-amd64.tar.gz
sudo mkdir -p /opt/alertmanager
sudo tar xvf alertmanager-0.25.0.linux-amd64.tar.gz -C /opt/alertmanager/ --strip-components=1
cd /opt/alertmanager/
sudo cp alertmanager.yml alertmanager.yml.bak
sudo vim alertmanager.yml

4.2. Cấu hình alertmanager.yml cho cảnh báo email

Để Alertmanager gửi email, bạn cần cấu hình thông tin SMTP. Trong ví dụ này, chúng ta sử dụng dịch vụ email 163.com.

Lưu ý: Bạn cần tạo mật khẩu ủy quyền (authorization code) trong cài đặt tài khoản email của mình (không phải mật khẩu đăng nhập chính) để sử dụng với SMTP.

global:
  resolve_timeout: 1m
  smtp_smarthost: 'smtp.163.com:25' # Máy chủ SMTP và cổng (cổng 587 với TLS là khuyến nghị)
  smtp_from: 'your_email@163.com' # Email người gửi
  smtp_auth_username: 'your_email@163.com' # Tên đăng nhập SMTP
  smtp_auth_password: 'your_authorization_code' # Mật khẩu ủy quyền từ 163.com
  smtp_require_tls: false # Đặt thành true nếu sử dụng cổng 587 hoặc 465

route:
  group_by: [alertname, instance] # Nhóm các cảnh báo có cùng tên và instance
  group_wait: 15s # Thời gian chờ trước khi gửi nhóm cảnh báo đầu tiên
  group_interval: 5m # Khoảng thời gian giữa các thông báo cho cùng một nhóm
  repeat_interval: 4h # Khoảng thời gian lặp lại cảnh báo nếu vẫn chưa được giải quyết
  receiver: default-email-receiver

receivers:
  - name: 'default-email-receiver'
    email_configs:
    - to: 'recipient_email@example.com' # Email người nhận
      send_resolved: true # Gửi thông báo khi cảnh báo đã được giải quyết
      html: true # Gửi email dưới dạng HTML để có định dạng tốt hơn

4.3. Thiết lập dịch vụ Alertmanager với Systemd

sudo vim /etc/systemd/system/alertmanager.service

Nội dung tệp alertmanager.service. Đảm bảo cổng 9093 khớp với cấu hình trong prometheus.yml.

[Unit]
Description=Prometheus Alertmanager
After=network.target

[Service]
User=root
Group=root
ExecStart=/opt/alertmanager/alertmanager \
  --config.file=/opt/alertmanager/alertmanager.yml \
  --storage.path=/opt/alertmanager/data \
  --web.listen-address=":9093"
Restart=always
RestartSec=3s

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl start alertmanager
sudo systemctl enable alertmanager

Bạn có thể xác minh Alertmanager đang chạy bằng cách truy cập http://<Alertmanager_IP>:9093.

5. Mô phỏng và kiểm tra cảnh báo

Để kiểm tra hệ thống cảnh báo, bạn có thể chờ một cảnh báo thực sự kích hoạt hoặc sửa đổi một quy tắc để nó dễ dàng được kích hoạt.

5.1. Kích hoạt cảnh báo thủ công

Chúng ta có thể sửa đổi quy tắc cảnh báo dung lượng đĩa trong node-rule.yml để thiết lập ngưỡng thấp hơn (ví dụ: > 10%) nhằm mô phỏng một cảnh báo:

sudo vim /opt/prometheus/prometheus-2.37.6.linux-amd64/conf/rules/node-rule.yml

Tìm và sửa đổi quy tắc DiskCapacityHigh:

  - alert: DiskCapacityHigh
    expr: 100 - (node_filesystem_free_bytes{fstype=~"ext4|xfs"}/node_filesystem_size_bytes {fstype=~"ext4|xfs"}*100) > 10 # Thay 80 bằng 10
    for: 2s
    labels:
      severity: critical
    annotations:
      summary: "{{$labels.mountpoint}} Dung lượng đĩa sử dụng cao!"
      description: "{{$labels.mountpoint}} dung lượng đĩa sử dụng lớn hơn 10% (hiện tại:{{$value | humanizePercentage}})"

Sau khi thay đổi quy tắc, yêu cầu Prometheus tải lại cấu hình:

curl -X POST http://localhost:9090/-/reload

Trong vài giây, bạn sẽ thấy cảnh báo được kích hoạt trong giao diện Prometheus (mục "Alerts") và Alertmanager, đồng thời nhận được email cảnh báo.

5.2. Kiểm tra phục hồi cảnh báo

Để kiểm tra thông báo phục hồi cảnh báo, hãy hoàn nguyên thay đổi trong node-rule.yml về ngưỡng ban đầu (ví dụ: > 80%) và tải lại cấu hình Prometheus.

  - alert: DiskCapacityHigh
    expr: 100 - (node_filesystem_free_bytes{fstype=~"ext4|xfs"}/node_filesystem_size_bytes {fstype=~"ext4|xfs"}*100) > 80 # Thay 10 bằng 80
    for: 2s
    labels:
      severity: critical
    annotations:
      summary: "{{$labels.mountpoint}} Dung lượng đĩa sử dụng cao!"
      description: "{{$labels.mountpoint}} dung lượng đĩa sử dụng lớn hơn 80% (hiện tại:{{$value | humanizePercentage}})"
curl -X POST http://localhost:9090/-/reload

Alertmanager sẽ nhận thấy cảnh báo đã được giải quyết và gửi một email thông báo "đã phục hồi".

Thẻ: prometheus Grafana alertmanager monitoring Alerting

Đăng vào ngày 17 tháng 8 lúc 22:22