Files
netbird-telegraf-installer/README.md
T

267 lines
14 KiB
Markdown

# netbird-telegraf-installer
Ein Befehl, und eine Node liefert Metriken + Logs an die zentrale Observability auf dem imac.
Der Ausgang läuft über den **NetBird-Reverse-Proxy** (`imac-prometheus.x05.idx.wf`, `imac-loki.x05.idx.wf`)
mit **Bearer-Token** — dadurch funktioniert der Installer auch auf Maschinen, die **kein NetBird-Peer** sind
(Büro-LAN, Kundenlaptop, CGNAT, VM ohne Client).
## Auto-Updater und Force-Updater
Der Installer hält sich auf den Nodes selbst aktuell.
### Prüfen
```sh
sh install.sh --version # installierte + verfügbare Version
sh install.sh --check # Exit 0 = aktuell, Exit 10 = Update verfügbar
```
Beides braucht **keinen Token** und **kein root** — gut für Monitoring-Checks.
### Auto-Updater (systemd-Timer)
```sh
sh install.sh --name <node> --token <T> --install-update-timer daily
sh install.sh --name <node> --token <T> --install-update-timer 30min
sh install.sh --name <node> --token <T> --install-update-timer weekly
```
Legt `telegraf-installer-update.timer` an (Default `daily` 04:30, ±15 min Streuung).
Der Lauf ist billig: Es werden nur `VERSION` und der SHA des Installers verglichen.
Erst bei Abweichung lädt er den Installer und ruft sich mit `--update-only` auf.
Log: `/var/log/telegraf-installer-update.log`.
`--update-only` fasst **nur** `telegraf.d/`-Konfs und Hilfsscripts an: kein
Paket-Update, `/etc/default/telegraf` (und damit der Token) bleibt unberührt,
kein Neustart wenn sich nichts geändert hat.
Warum Version **und** Hash: Die `VERSION` erkennt neue Auslieferungen, der SHA
auch Korrekturen ohne Versionssprung (z. B. ein Fix an `journal-tail.sh`).
Ohne den Hash bliebe eine Node mit fehlerhaftem Script stehen.
### Force-Updater
```sh
sh install.sh --force-update --name <node> --token <T>
```
Schreibt Konfs und Scripts **immer** neu, sichert sie vorher nach
`/var/backups/telegraf-<zeitstempel>/` und startet den Dienst neu. Schlägt der
Konfig-Test fehl, wird automatisch zurückgerollt. Idempotent — mehrfaches
Ausführen ist folgenlos. Das Werkzeug nach einem kaputten Update oder wenn
jemand Dateien von Hand verändert hat.
Entfernen: `sh install.sh --remove-update-timer`
### Windows
```powershell
.\install.ps1 -Name <node> -Token <T> -Check # Versionsvergleich
.\install.ps1 -Name <node> -Token <T> -InstallUpdateTask # taeglich
.\install.ps1 -Name <node> -Token <T> -InstallUpdateTask -UpdateInterval hourly
.\install.ps1 -Name <node> -Token <T> -ForceUpdate
.\install.ps1 -RemoveUpdateTask
```
Die Aufgabe `\NetBirdTelegraf\Update` läuft mit denselben Semantiken
(Version + Hash, nur bei Änderung). Log:
`%ProgramData%\netbird-telegraf\update.log`.
### Marker auf der Node
| Datei | Inhalt |
|---|---|
| `/etc/telegraf/CONFIG_VERSION` | zuletzt installierte Repo-Version |
| `/etc/telegraf/INSTALLER_SHA` | SHA256 des Installers zum Installationszeitpunkt |
| `/etc/telegraf/REPO_RAW` | genutzte Repo-Quelle (GitHub-Mirror, Testserver) |
`REPO_RAW` ist per Umgebungsvariable überschreibbar — nützlich für Tests,
Mirrors oder einen eigenen Fork.
### Docker-Nodes (kein journalctl im Image)
Läuft Telegraf als **Container** (offizielles `telegraf`-Image), ist der Journal-Weg nicht möglich: das Image ist Debian ohne `systemd` und hat **kein `journalctl`**; `/hostfs` ist zudem read-only. Dafür gibt es `scripts/syslog-tail.sh` — es liest die **Syslog-Dateien des Hosts** unter `/hostfs/var/log/`.
**Drei Fallstricke, die alle still scheitern** (kein `E!`, das Panel bleibt einfach leer):
1. **`--config-directory` muss im Command stehen.** Der Standard-CMD im Image ist nur `telegraf` und liest ausschließlich `/etc/telegraf/telegraf.conf`. Alles in `telegraf.d/` wird ohne diesen Schalter **ignoriert**. In `docker-compose.yml`:
```yaml
command: --config /etc/telegraf/telegraf.conf --config-directory /etc/telegraf/telegraf.d
```
2. **Gruppe `adm` ergänzen** (`group_add: ["4"]`). Der Entrypoint des Images setzt Telegraf per `setpriv` auf **uid 999** — unabhängig von `user:` im Compose. `/var/log/syslog` gehört Gruppe `adm` (Modus 640), als uid 999 also nicht lesbar. Ohne `adm` gibt das Script nichts aus.
3. **State-Verzeichnis muss schreibbar sein** (`SYSLOG_STATE_DIR`). Voreinstellung ist `/tmp/telegraf-syslog`. Zeigt es auf ein nicht schreibbares Verzeichnis (z. B. `/var/lib/...` als uid 999), kann der Offset nie gespeichert werden — das Script landet bei **jedem** Lauf im Erstanlauf-Zweig und liefert dauerhaft nichts. Seit der aktuellen Version warnt es in dem Fall auf stderr.
**Output-Filter mitziehen:** `outputs.loki` filtert per `namepass`. Enthält der Block `namepass = ["docker_log"]`, wird das `journal`-Measurement verworfen und die System-Logs kommen nie an — auch wenn der Input läuft. `journal` ergänzen; im Remote-Write-Output gehört es in `namedrop` (Logs haben in Prometheus nichts zu suchen).
**Kein Zeitstempel im erzeugten Line Protocol.** Die Syslog-Zeit ist lokal (`+02:00`), `mawk` (Standard im Image) kennt keine Zeitzonen-Offsets — selbst berechnete Werte lagen 2 h in der Zukunft und Loki wies jeden Push ab: `has timestamp too new`. Ohne Zeitstempel stempelt Telegraf beim Einsammeln.
## System-Logs (PVE und Nicht-Docker-Hosts)
Bis Version dieses Abschnitts lieferten nur **Docker-Container** Logs nach Loki
(`inputs.docker_log`) — PVE-Knoten und alle Hosts ohne Docker also gar nichts.
Jetzt werden zusätzlich **journald-Logs** übertragen.
**Wie:** `scripts/journal-tail.sh` liest `journalctl -o json` inkrementell und
gibt Influx Line Protocol aus (`inputs.exec`). Der Cursor steckt in jeder
Journal-Zeile (`__CURSOR`) und wird in `/var/lib/telegraf-journal/cursor`
gespeichert — keine Duplikate, kein Verlust bei Neustart oder Rotation.
**Warum nicht `inputs.journal`:** Das Plugin existiert in den offiziellen
Telegraf-Builds **nicht** (Docker-Image und InfluxData-Debian-Paket 1.40
geprüft; es braucht einen Build mit systemd-Headern).
**Warum nicht `/var/log/syslog`:** Auf PVE (Debian ohne rsyslog) existiert die
Datei nicht. `ls /var/log/` zeigt dort `journal/`, `pve/`, `pveproxy/`,
`pve-firewall.log`, `ceph/`, `corosync/` — aber kein `syslog`.
**Feintuning** in `/etc/default/telegraf`:
| Variable | Default | Bedeutung |
|---|---|---|
| `JOURNAL_PRIORITY` | `warning` | `warning`, `err`, `info`, `debug` |
| `JOURNAL_MAX_LINES` | `500` | Obergrenze pro Lauf (Flutschutz) |
| `JOURNAL_BUDGET` | `15` | Sekunden, die `journalctl` lesen darf |
| `JOURNAL_SINCE` | — | nur beim **ersten** Lauf, z. B. `-1h` |
Standardmäßig werden **Warnungen und schlimmer** übertragen. Für Debugging
`JOURNAL_PRIORITY=info` setzen und Telegraf neu starten.
**Labels in Loki:** `unit` (z. B. `pvedaemon.service`), `ident`, `priority`,
`jhost` (Journal-Hostname), dazu `host`/`node` von Telegraf. Das `jhost`-Label
heißt bewusst nicht `host` — dieser Name gehört Telegrafs global_tag, sonst
filtert das Dashboard nach dem falschen Knoten.
## Der Token — zuerst lesen
Jeder Aufruf braucht `--token <TOKEN>`. Ohne Token bricht das Script mit
`FEHLER: Kein Token: --token <Bearer-Token> angeben` ab.
Den Token legt man im NetBird-Dashboard an: **`https://x05.idx.wf` → Reverse Proxy →
Service `imac-prometheus` → Authentication → Header → Preset „Bearer Token"**.
Für `imac-loki` denselben Wert eintragen (oder einen zweiten, dann aber getrennt halten).
Token nie in dieses Repo schreiben — er landet ausschließlich in `/etc/default/telegraf` (Modus 0600) auf der Zielmaschine.
## Linux — Debian, Ubuntu, Proxmox VE, RHEL/Rocky/Alma/Fedora, Alpine, sonstige
```sh
curl -fsSL https://gitea.m-m.bio/mm/netbird-telegraf-installer/raw/branch/main/install.sh \
| sudo sh -s -- --name <node-name> --token <BEARER-TOKEN>
```
| Option | Bedeutung |
|---|---|
| `--name <n>` | Node-Name im Dashboard (Default: `hostname -s`) |
| `--token <t>` | **Pflicht.** Bearer-Token des Reverse-Proxys |
| `--collector <ip>` | Direktweg innerhalb des NetBird statt Reverse Proxy (z. B. `100.83.134.46`); braucht dann keinen Token-Zwang, aber die Node muss Peer sein |
| `--role proxmox\|apache\|docker\|none` | Zusatz-Profil; Default `auto` erkennt Proxmox, Docker und Apache selbst |
| `--apache-log <pfad>` | Access-Log (Default `/var/log/apache2/access.log`) |
| `--uninstall` | alles entfernen |
**Root-Rechte:** Das Script braucht sie (Dienst, `/etc/telegraf`). Auf PVE, in LXC-Containern und überall, wo du schon root bist: **kein `sudo`** — es ist dort oft nicht installiert. Auf normalen Desktops/Servern mit eigenem Benutzer: `| sudo sh -s -- …`.
Ablauf: Paketquelle von InfluxData (apt/dnf/apk) oder statisches Binary (amd64/arm64/armv7) → `/etc/telegraf/telegraf.conf` + `telegraf.d/` aus diesem Repo → `/etc/default/telegraf` mit NODE_NAME, PROM_URL, LOKI_URL, TELEGRAF_TOKEN → systemd-Dienst `telegraf`, enabled, Konfig-Test vor dem Start.
### Direktweg (Node ist NetBird-Peer)
```sh
curl -fsSL …/install.sh | sudo sh -s -- --name <node> --token <TOKEN> --collector 100.83.134.46
```
### Proxmox VE
**Kein API-Token nötig.** Der Installer nutzt `pvesh` direkt (Telegraf läuft für diese Rolle
als root — das Drop-in `10-proxmox-root.conf` setzt das). Damit entfällt die gesamte
Token-/ACL-Thematik.
> Warum nicht `inputs.proxmox`? Das Plugin fragt als Erstes `/nodes/<node>/dns` ab und
> braucht dort `Sys.Audit`. Schlägt das fehl, liefert es **komplett nichts** — ohne
> Logmeldung. Mehrere ACL-Versuche (`PVEAuditor` auf `/`, auf `/nodes`, auf `/nodes/<node>`,
> eigene Rolle mit `Sys.Audit`) blieben auf PVE 8 mit `403` erfolglos.
Dann auf **jedem PVE-Knoten** (auf dem Host selbst, nicht in einer VM).
**Auf PVE gibt es kein `sudo`** — du bist dort bereits root, also ohne `sudo`:
```sh
curl -fsSL https://gitea.m-m.bio/mm/netbird-telegraf-installer/raw/branch/main/install.sh \
| sh -s -- --name <PVE-KNOTENNAME> --token <BEARER-TOKEN> --role proxmox
```
> Auf Debian/Ubuntu/Normalnutzer dagegen `| sudo sh -s -- …` verwenden. Das Script prüft `id -u` selbst und bricht mit klarer Meldung ab, wenn es nicht root ist.
Der Installer erkennt den PVE-Knoten selbst (`pvesh get /nodes`) und legt das systemd-Drop-in
`10-proxmox-root.conf` an — Telegraf läuft für diese Rolle als **root**, weil `pvesh` root verlangt.
Liefert pro Gast: `proxmox_vm_cpu_usage_percent`, `_cpu_cores`, `_mem_bytes`, `_mem_max_bytes`,
`_mem_usage_percent`, `_swap_bytes`, `_disk_bytes`, `_disk_max_bytes`, `_diskread/_diskwrite_bytes_total`,
`_net_in/_net_out_bytes_total`, `_uptime_seconds`, `_running` — je mit `vmid`, `name`, `node`, `type`, `status`.
Plus die normalen Host-Metriken des Knotens.
> **Wenn nach der Installation keine VM-Metriken kommen:** `systemctl cat telegraf | grep User` muss
> `User=root` zeigen. Vorher prüfen: `pvesh get /cluster/resources --output-format json` muss als root
> Daten liefern. Als Nicht-root gibt `pvesh` nur `ipcc_send_rec[...] failed` aus — ohne Fehler im Log.
### Apache
Wird automatisch erkannt (`apache2ctl`/`httpd`). Access-Log geht roh nach Loki. Für Request-Metriken `inputs.apache` in `telegraf/apache.conf` einschalten (braucht mod_status).
## Windows — PowerShell als Administrator
```powershell
Set-ExecutionPolicy Bypass -Scope Process -Force
& ([scriptblock]::Create((iwr -useb https://gitea.m-m.bio/mm/netbird-telegraf-installer/raw/branch/main/install.ps1))) -Name ROG -Token <BEARER-TOKEN>
```
Installiert nach `C:\Program Files\Telegraf`, Dienst `telegraf`; liefert CPU/RAM/Disk/Net/Dienste + Eventlog (Warnung/Fehler). `-Uninstall` entfernt alles.
## GPU-Metriken
| Hersteller | Erkennung | Metriken |
|---|---|---|
| NVIDIA | `nvidia-smi -L` funktioniert | Auslastung, VRAM, Temperatur, Leistung, Takte, P-State |
| AMD | `rocm-smi` vorhanden | Auslastung, Temperatur, Leistung, VRAM (via `scripts/gpu-rocm.sh`) |
| Intel | `/dev/dri/renderD128` | Hinweis im Log — `intel_gpu_top` wird nicht automatisch erfasst |
AMD liefert sieben Metriken (Auslastung, VRAM genutzt/gesamt, Temperatur edge/junction/memory, Leistung). NVIDIA entsprechend über `inputs.nvidia_smi`.
Im Dashboard: Row **GPU** (Auslastung, Speicher, Temperatur, Leistung). Leere Panels heißen: keine GPU-Node im Mesh.
**Beim Aktualisieren des AMD-Scripts** (falls `rocm-smi` seine Spalten ändert) beide Dateien neu holen — Script **und** Conf, und `data_format` muss `prometheus` bleiben:
```sh
sudo curl -fsSL …/scripts/gpu-rocm.sh | sudo tee /etc/telegraf/gpu-rocm.sh >/dev/null
sudo chmod +x /etc/telegraf/gpu-rocm.sh
sudo sh -c 'cat > /etc/telegraf/telegraf.d/gpu.conf <<EOF
[[inputs.exec]]
interval = "30s"
timeout = "20s"
data_format = "prometheus"
commands = ["/etc/telegraf/gpu-rocm.sh"]
EOF'
sudo systemctl restart telegraf
```
Im Docker-Betrieb muss der Treiber im Container verfügbar sein (`nvidia-container-toolkit` bzw. `--device /dev/dri`); als systemd-Dienst ist das automatisch der Fall.
## Prüfen
```sh
TOKEN=<BEARER-TOKEN>
curl -s -H "Authorization: Bearer $TOKEN" \
"https://imac-prometheus.x05.idx.wf/api/v1/query?query=system_uptime{node=\"<node-name>\"}"
journalctl -u telegraf -f
```
Im Grafana-Dashboard „NetBird Observability — Overview“ erscheint die Node automatisch im Node-Filter.
Grafana selbst: `http://100.83.134.46:3000` (nur im NetBird, Login `admin`).
## Docker-Host ohne root
Wer kein sudo hat, aber in der Gruppe `docker` ist: Container-Variante aus
[netbird-observability/stacks/telegraf-node](https://gitea.m-m.bio/mm/netbird-observability) (privates Repo).
Dort ist `network_mode: host` gesetzt — ohne das sieht Telegraf nur `lo`+`eth0` statt der echten Interfaces.
## Sicherheit
- Der Proxy verlangt Bearer-Token; das Header wird vor dem Weiterleiten entfernt und liegt damit nicht bei Prometheus/Loki.
- Telegraf läuft als Benutzer `telegraf` (Docker-Socket read-only via Gruppe `docker`, Apache-Logs via Gruppe `adm`).
- **Ausnahme `--role proxmox`:** systemd-Drop-in setzt `User=root`, weil `pvesh` root benötigt. Nur auf PVE-Hosts, wo du ohnehin root bist.
- Dieses Repo ist öffentlich und enthält keine Secrets.