Zwölf Builds

Ein Monitoring-Stack für die eigene Flotte

Prometheus, Exporters und Alertmanager über mehrere Standorte, gescraped durch einen privaten Tunnel, mit Alarmen, die feuern, bevor eine Platte voll ist und nicht danach.

Was dabei herauskommt

Eine kleine Instanz, die jede andere Maschine, die Sie besitzen, über einen privaten Tunnel überwacht und Ihnen eine E-Mail schickt, wenn etwas kurz davor ist, kaputtzugehen. Node-Metriken, Blackbox-Probes zwischen Standorten, Alarmregeln mit sinnvollen Schwellenwerten und eine Alertmanager-Konfiguration, die Benachrichtigungen gruppiert, statt Ihnen um drei Uhr morgens vierhundert davon zu schicken.

In diesem Aufbau gibt es kein Dashboard. Dashboards sind angenehm, aber sie sind kein Monitoring; ein Diagramm, das niemand ansieht, hat noch nie jemanden geweckt. Fügen Sie später eines hinzu, wenn Sie möchten, auf der Grundlage derselben Daten.

Bevor Sie beginnen

  • Eine R-4 für den Monitor. Hundert Knoten im Fünfzehn-Sekunden-Intervall ergeben einige hunderttausend Stichproben pro Minute, was diese Instanz problemlos bewältigt.
  • Platzieren Sie sie nicht dort, wo Ihre Flotte ist. Ein Monitor, der sich dasselbe Gebäude mit allem teilt, was er beobachtet, bleibt ausgerechnet an dem Tag bewundernswert ruhig, an dem er schreien soll. Wenn Ihr Bestand europäisch ist, ist Toronto oder Singapur der sinnvolle Ort dafür.
  • Ein Tunnel zu jedem überwachten Knoten, gemäß der WireGuard-Anleitung. Exporteure legen viel über eine Maschine offen und gehören in die Nähe keiner öffentlichen Schnittstelle.

1. Auf jedem überwachten Knoten

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

Setzen Sie die jeweilige Tunneladresse des Knotens ein. Die Bindung an den Tunnel statt an alles bedeutet, dass die Firewall eine zweite Verteidigungslinie ist und nicht die einzige.

2. Auf dem Monitor

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

Schreiben Sie /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

Dateibasierte Ermittlung statt einer statischen Liste ist das zusätzliche Verzeichnis wert. Das Hinzufügen eines Knotens wird zu einer Datei, und die Datei kann von dem geschrieben werden, was auch immer Ihre Maschinen provisioniert. /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 }

Diese Labels machen Warnmeldungen später lesbar. Eine Warnung, die db in AMS-01 sagt, ist umsetzbar; eine, die 10.7.0.12 sagt, schickt Sie zu einer Tabellenkalkulation.

3. Regeln, die sich lohnen

/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 ist die Regel, die diesen Aufbau seinen Wert verdient. Ein Schwellenwert für freien Speicher sagt Ihnen, dass eine Festplatte voll ist; ein über sechs Stunden extrapolierter Trend sagt Ihnen, dass sie heute Nachmittag gegen vier Uhr voll sein wird – ein Problem, das Sie noch in Ruhe lösen können. Festplattenwarnungen auf Basis eines festen Prozentsatzes sind entweder auf kleinen Datenträgern laut oder auf großen nutzlos.

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>"

Die Inhibit-Regel ist der Unterschied zwischen einer Nachricht und vierzig. Wenn ein Knoten ausfällt, werden alle Warnungen zu diesem Knoten unterdrückt, denn Sie wissen es bereits: Der Knoten ist ausgefallen.

Die Gruppierung nach alertname und site bedeutet, dass ein Stromausfall an einem gesamten Standort eine E-Mail erzeugt, die jede Maschine auflistet, statt einer E-Mail pro Maschine. Der Mailserver ist der aus der Mail-Anleitung, und die Tatsache, dass Ihr Alarmierungsweg von Infrastruktur abhängt, die Sie ebenfalls überwachen, ist ein bekannter Kompromiss; ein zweiter Empfänger, der auf einen Webhook woanders zeigt, ist eine billige Versicherung.

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

Die Aufbewahrungsdauer sollte man bewusst festlegen. Neunzig Tage von hundert Knoten sind einige zig Gigabyte:

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

Überprüfen

Zuerst die Syntax, denn eine Regeldatei mit einem Tippfehler schlägt beim Laden still fehl, und Sie finden es während des Vorfalls heraus:

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

Dann bestätigen, dass jedes Ziel gescraped wird:

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

Jedes Ziel sollte up melden. Eines, das down meldet, ist entweder eine Firewall-Regel oder ein Exporter, der an die falsche Adresse gebunden ist.

Nun der einzige Test, der die ganze Kette beweist: etwas absichtlich kaputtzumachen. Auf einem beliebigen überwachten Knoten:

systemctl stop prometheus-node-exporter

Drei Minuten später sollte die Warnung pending sein, dann firing. Beobachten Sie, wie sie sich bewegt:

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

Innerhalb von etwa einer Minute nach dem Auslösen trifft die E-Mail ein. Wenn die Warnung auslöst, aber keine E-Mail erscheint, liegt das Problem an den Smarthost-Zugangsdaten, und journalctl -u prometheus-alertmanager wird das klar sagen. Starten Sie den Exporter erneut und bestätigen Sie, dass Sie auch die resolved-Benachrichtigung erhalten, denn ein Alarmsystem, das Ihnen nie sagt, dass es besser ist, trainiert Sie, es zu ignorieren.

systemctl start prometheus-node-exporter

Danach

Fügen Sie Blackbox-Probes zwischen Standorten hinzu, von jedem Standort zu jedem anderen, und Sie erhalten eine Latenzmatrix Ihres eigenen Bestands, die bei einem Vorfall weitaus nützlicher ist als jede Statusseite. Unsere befindet sich unter status, und der Looking Glass beantwortet die andere Hälfte der Frage, wenn eine Route falsch aussieht.

Bereit, wenn Sie es sind

Wählen Sie eine Stadt. Wählen Sie eine Größe. Bezahlen Sie in Coins.

Keine Formulare darüber, wer Sie sind, kein Warten auf einen Menschen, der Sie genehmigt, kein Anruf zur Verifizierung. Die Rechnung wird beglichen, und die Zugangsdaten landen in Ihrem Posteingang.