Mười hai bài xây dựng

Một bộ giám sát theo dõi hạ tầng của chính bạn

Prometheus, các exporter và Alertmanager trên nhiều điểm đặt máy, thu thập qua một tunnel riêng, với các cảnh báo được kích hoạt trước khi ổ đĩa đầy thay vì sau đó.

Cái này dựng nên cái gì

Một instance nhỏ thu thập dữ liệu từ mọi máy khác bạn sở hữu, qua một tunnel riêng tư, và gửi mail cho bạn khi có gì đó sắp hỏng. Node metrics, blackbox probes giữa các site, alert rules với ngưỡng hợp lý, và một cấu hình Alertmanager gom nhóm thông báo thay vì gửi bốn trăm cái lúc ba giờ sáng.

Không có dashboard trong bản dựng này. Dashboards thì dễ chịu và chúng không phải là giám sát; một cái đồ thị không ai nhìn chưa bao giờ đánh thức ai dậy. Thêm vào sau nếu bạn muốn, trên cùng một nguồn dữ liệu.

Trước khi bắt đầu

  • Một R-4 cho monitor. Một trăm node ở khoảng thời gian mười lăm giây là vài trăm nghìn mẫu mỗi phút, cái này xử lý mà không cần để ý.
  • Đặt nó ở nơi mà hạ tầng của bạn không nằm. Bất kỳ monitor nào dùng chung tòa nhà với mọi thứ nó theo dõi sẽ giữ im lặng đáng khen ngợi vào đúng ngày bạn cần nó lên tiếng. Nếu hạ tầng của bạn ở châu Âu, Toronto hoặc Singapore là nơi hợp lý cho nó.
  • Một tunnel đến mỗi node được giám sát, từ hướng dẫn WireGuard. Exporters tiết lộ rất nhiều về một máy và không nên xuất hiện ở gần interface công cộng.

1. Trên mỗi node được giám sát

apt update && apt install -y prometheus-node-exporter
mkdir -p /etc/systemd/system/prometheus-node-exporter.service.d
cat > /etc/systemd/system/prometheus-node-exporter.service.d/bind.conf <<EOF
[Service]
Environment=ARGS=--web.listen-address=10.7.0.11:9100 --collector.systemd --collector.processes
EOF
systemctl daemon-reload && systemctl restart prometheus-node-exporter
ss -ltn | grep 9100

Thay bằng địa chỉ tunnel riêng của từng node. Bind vào tunnel thay vì bind vào tất cả có nghĩa là tường lửa là tuyến phòng thủ thứ hai chứ không phải là tuyến duy nhất.

2. Trên monitor

apt install -y prometheus prometheus-alertmanager prometheus-blackbox-exporter

Viết /etc/prometheus/prometheus.yml:

global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    fleet: main

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['127.0.0.1:9093']

rule_files:
  - /etc/prometheus/rules/*.yml

scrape_configs:
  - job_name: nodes
    file_sd_configs:
      - files: ['/etc/prometheus/targets/*.yml']

  - job_name: probe_https
    metrics_path: /probe
    params:
      module: [http_2xx]
    static_configs:
      - targets:
          - https://app.example.com/health
          - https://cloud.example.com/status.php
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: 127.0.0.1:9115

File-based discovery thay vì danh sách tĩnh đáng giá thư mục phụ thêm. Thêm một node chỉ là một file, và file đó có thể được tạo bởi bất cứ thứ gì cấp phát máy của bạn. /etc/prometheus/targets/ams.yml:

- targets: ['10.7.0.11:9100']
  labels: { site: AMS-01, role: web }
- targets: ['10.7.0.12:9100']
  labels: { site: AMS-01, role: db }

Những label đó làm cho cảnh báo dễ đọc hơn về sau. Một cảnh báo nói db in AMS-01 có thể hành động được; cái nói 10.7.0.12 đưa bạn đến một bảng tính.

3. Các rule đáng có

/etc/prometheus/rules/fleet.yml:

groups:
  - name: fleet
    rules:
      - alert: NodeDown
        expr: up{job="nodes"} == 0
        for: 3m
        labels: { severity: page }
        annotations:
          summary: "{{ $labels.instance }} in {{ $labels.site }} stopped answering"

      - alert: DiskFillingUp
        expr: predict_linear(node_filesystem_avail_bytes{fstype=~"ext4|xfs|zfs|btrfs"}[6h], 4*3600) < 0
        for: 30m
        labels: { severity: page }
        annotations:
          summary: "{{ $labels.instance }} fills {{ $labels.mountpoint }} within four hours"

      - alert: MemoryPressure
        expr: node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes < 0.10
        for: 15m
        labels: { severity: warn }

      - alert: IOWaitHigh
        expr: avg by (instance) (rate(node_cpu_seconds_total{mode="iowait"}[5m])) > 0.25
        for: 20m
        labels: { severity: warn }

      - alert: CertificateExpiring
        expr: probe_ssl_earliest_cert_expiry - time() < 10*86400
        labels: { severity: warn }

      - alert: ProbeFailing
        expr: probe_success == 0
        for: 5m
        labels: { severity: page }

predict_linear là rule đáng giá nhất của bản dựng này. Một ngưỡng trên dung lượng trống cho bạn biết một đĩa đầy; một xu hướng sáu giờ ngoại suy về phía trước cho bạn biết nó sẽ đầy vào khoảng bốn giờ chiều nay, đó là một vấn đề bạn vẫn có thể giải quyết một cách bình tĩnh. Cảnh báo đĩa dựa trên phần trăm cố định hoặc là ồn ào trên ổ nhỏ hoặc vô dụng trên ổ lớn.

4. Alertmanager

route:
  receiver: mail
  group_by: [alertname, site]
  group_wait: 45s
  group_interval: 5m
  repeat_interval: 12h
  routes:
    - matchers: [severity="warn"]
      repeat_interval: 72h

inhibit_rules:
  - source_matchers: [alertname="NodeDown"]
    target_matchers: [severity="warn"]
    equal: [instance]

receivers:
  - name: mail
    email_configs:
      - to: [email protected]
        from: [email protected]
        smarthost: mail.example.com:587
        auth_username: [email protected]
        auth_password: "<the mailbox password>"

Rule inhibit là sự khác biệt giữa một tin nhắn và bốn mươi. Khi một node xuống, mọi cảnh báo về node đó bị ức chế, vì bạn đã biết: node đó xuống.

Gom nhóm theo alertnamesite có nghĩa là một site mất điện toàn bộ tạo ra một email liệt kê mọi máy, thay vì một email mỗi máy. Máy chủ mail đó là cái từ hướng dẫn mail, và để cho đường cảnh báo của bạn phụ thuộc vào hạ tầng mà bạn cũng giám sát là một sự đánh đổi đã biết; một receiver thứ hai trỏ tới một webhook ở nơi khác là bảo hiểm rẻ.

systemctl enable --now prometheus prometheus-alertmanager prometheus-blackbox-exporter

Retention đáng được đặt một cách có chủ đích. Chín mươi ngày của một trăm node là vài chục gigabyte:

echo 'ARGS="--storage.tsdb.retention.time=90d --storage.tsdb.retention.size=40GB"' > /etc/default/prometheus
systemctl restart prometheus

Xác minh nó

Cú pháp trước, vì một file rules có lỗi chính tả sẽ thất bại âm thầm khi tải và bạn sẽ phát hiện ra trong lúc sự cố:

promtool check config /etc/prometheus/prometheus.yml
promtool check rules /etc/prometheus/rules/fleet.yml

Sau đó xác nhận mọi target đang được thu thập:

curl -s http://127.0.0.1:9090/api/v1/targets | grep -o "\"health\":\"[a-z]*\"" | sort | uniq -c

Mọi target nên báo cáo up. Một cái báo cáo down hoặc là một rule tường lửa hoặc là exporter bind vào sai địa chỉ.

Bây giờ thử nghiệm duy nhất chứng minh cả chuỗi hoạt động, đó là cố ý làm hỏng một cái gì đó. Trên bất kỳ node được giám sát nào:

systemctl stop prometheus-node-exporter

Ba phút sau cảnh báo sẽ ở trạng thái pending, rồi firing. Xem nó chuyển:

curl -s http://127.0.0.1:9090/api/v1/alerts | head -c 400
amtool --alertmanager.url=http://127.0.0.1:9093 alert query

Trong khoảng một phút sau khi firing, mail đến. Nếu cảnh báo firing nhưng không có mail xuất hiện, vấn đề là thông tin đăng nhập smarthost, và journalctl -u prometheus-alertmanager sẽ nói rõ điều đó. Khởi động lại exporter và xác nhận bạn cũng nhận được thông báo resolved, vì một hệ thống cảnh báo không bao giờ báo cho bạn biết mọi thứ tốt hơn sẽ huấn luyện bạn bỏ qua nó.

systemctl start prometheus-node-exporter

Sau đó

Thêm blackbox probes giữa các site, từ mỗi site đến mỗi site khác, và bạn có một ma trận độ trễ của riêng hạ tầng của mình, hữu ích hơn nhiều trong lúc sự cố so với bất kỳ trang trạng thái nào. Của chúng tôi ở trạng thái, và looking glass trả lời nửa còn lại của câu hỏi khi một tuyến đường trông có vẻ sai.

Sẵn sàng khi bạn cần

Chọn thành phố. Chọn kích thước. Thanh toán bằng coin.

Không có biểu mẫu về bạn là ai, không chờ đợi con người phê duyệt, không gọi điện thoại để xác minh bất cứ điều gì. Hóa đơn được thanh toán và thông tin đăng nhập sẽ vào hộp thư của bạn.