Wat dit bouwt
Een kleine instantie die iedere andere machine die je bezit scrapet via een privétunnel, en je mailt wanneer er iets op het punt staat te breken. Node-metrieken, blackbox-probes tussen locaties, alertregels met verstandige drempelwaarden, en een Alertmanager-configuratie die meldingen groepeert in plaats van je er om drie uur 's nachts vierhonderd te sturen.
Er is geen dashboard in deze build. Dashboards zijn prettig en ze zijn geen monitoring; een grafiek waar niemand naar kijkt heeft nog nooit iemand wakker gemaakt. Voeg er later een toe als je wilt, bovenop dezelfde data.
Voordat je begint
- Een R-4 voor de monitor. Honderd nodes met intervallen van vijftien seconden is een paar honderdduizend samples per minuut, wat dit zonder problemen aankan.
- Zet hem op een plek waar je fleet niet is. Elke monitor die een gebouw deelt met alles wat hij bewaakt, blijft bewonderenswaardig stil op precies de dag dat je wilt dat hij schreeuwt. Als je estate Europees is, is Toronto of Singapore de verstandige plek ervoor.
- Een tunnel naar elke bewaakte node, vanuit de WireGuard-gids. Exporters leggen veel bloot over een machine en horen nergens in de buurt van een publieke interface te komen.
1. Op elke bewaakte node
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 9100Vervang het eigen tunneladres van elke node. Binden aan de tunnel in plaats van aan alles betekent dat de firewall een tweede verdedigingslinie is in plaats van de enige.
2. Op de monitor
apt install -y prometheus prometheus-alertmanager prometheus-blackbox-exporterSchrijf /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:9115Bestandsgebaseerde discovery in plaats van een statische lijst is de extra directory waard. Een node toevoegen wordt één bestand, en dat bestand kan geschreven worden door wat je machines ook provisiont. /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 }Die labels zijn wat alerts later leesbaar maakt. Een alert die db in AMS-01 zegt is actiegericht; een die 10.7.0.12 zegt stuurt je naar een spreadsheet.
3. Regels die de moeite waard zijn
/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 is de regel die deze build de moeite waard maakt. Een drempelwaarde op vrije ruimte vertelt je dat een disk vol is; een zeshonderd uur durende trend geëxtrapoleerd naar de toekomst vertelt je dat hij rond vier uur vanmiddag vol zal zijn, wat een probleem is dat je nog rustig kunt oplossen. Disk-alerts op basis van een vast percentage zijn óf luidruchtig op kleine volumes óf nutteloos op grote.
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>"De inhibit-regel is het verschil tussen één bericht en veertig. Wanneer een node uitvalt, wordt elke waarschuwing over die node onderdrukt, want je weet het al: de node is uit.
Groeperen op alertname en site betekent dat een hele locatie die stroom verliest één mail oplevert met elke machine erin, in plaats van één mail per machine. Die mailserver is die uit de mailgids, en het feit dat je alerting-pad afhangt van infrastructuur die je ook bewaakt is een bekend compromis; een tweede receiver die naar een webhook elders wijst is goedkope verzekering.
systemctl enable --now prometheus prometheus-alertmanager prometheus-blackbox-exporterRetentie is het waard om bewust in te stellen. Negentig dagen van honderd nodes is een paar tientallen gigabytes:
echo 'ARGS="--storage.tsdb.retention.time=90d --storage.tsdb.retention.size=40GB"' > /etc/default/prometheus
systemctl restart prometheusVerifieer het
Eerst syntaxis, want een regelsbestand met een typfout faalt stil bij het laden en je komt erachter tijdens de incident:
promtool check config /etc/prometheus/prometheus.yml
promtool check rules /etc/prometheus/rules/fleet.ymlBevestig dan dat elke target wordt gescraped:
curl -s http://127.0.0.1:9090/api/v1/targets | grep -o "\"health\":\"[a-z]*\"" | sort | uniq -cElke target zou up moeten rapporteren. Een die down rapporteert is ofwel een firewallregel of een exporter die aan het verkeerde adres gebonden is.
Nu de enige test die bewijst dat de hele keten werkt, namelijk om expres iets te breken. Op elke bewaakte node:
systemctl stop prometheus-node-exporterDrie minuten later zou de alert pending moeten zijn, en daarna firing. Kijk hoe hij beweegt:
curl -s http://127.0.0.1:9090/api/v1/alerts | head -c 400
amtool --alertmanager.url=http://127.0.0.1:9093 alert queryBinnen ongeveer een minuut na firing komt de mail aan. Als de alert vuurt maar er komt geen mail, dan is het probleem de smarthost-referenties, en journalctl -u prometheus-alertmanager zal dat duidelijk zeggen. Start de exporter weer en bevestig dat je ook de resolved-melding ontvangt, want een alertingsysteem dat je nooit vertelt dat dingen beter gaan, traint je om het te negeren.
systemctl start prometheus-node-exporterAchteraf
Voeg blackbox-probes toe tussen locaties, van elke locatie naar elke andere locatie, en je krijgt een latentiematrix van je eigen estate die veel nuttiger is tijdens een incident dan welke statuspagina dan ook. Onze staat op status, en de looking glass beantwoordt de andere helft van de vraag wanneer een route er verkeerd uitziet.