Files
hermes-skills/skills/devops/ops-portal-and-collector/references/bulk-node-exporter-install.md
T

2.3 KiB

Bulk node_exporter Install — July 2026 Rollout

Server inventory

All 9 Hetzner servers received node_exporter v1.8.2 in a single session:

Hostname IP Status
app1-bu.itpropartner.com 5.161.114.8 Running
ai.itpropartner.com 178.156.167.181 Running
hudu.itpropartner.com 178.156.130.130 Running
(unifi) 178.156.131.57 Running
unms.forefrontwireless.com 5.161.225.131 Running
wphost02 5.161.62.38 Running
app1.itpropartner.com 87.99.144.163 Running
(docker) 178.156.168.35 Running
(fleettrack360) 178.156.149.32 Running

Batch install pattern

Write two scripts:

  1. install-node-exporter.sh — self-contained script that downloads, installs binary, creates systemd unit, enables/starts. The existing scripts/install-node-exporter.sh in this skill works.

  2. Wrapper script — iterates over a list and runs SCP + SSH for each:

#!/bin/bash
SERVERS=(
  "hostname1:1.2.3.4"
  "hostname2:5.6.7.8"
)
KEY="/root/.ssh/itpp-infra"
SCRIPT="/tmp/install-node-exporter.sh"

for entry in "${SERVERS[@]}"; do
  hostname="${entry%%:*}"
  ip="${entry##*:}"
  echo "=== Installing on $hostname ($ip) ==="
  scp -o StrictHostKeyChecking=no -i "$KEY" "$SCRIPT" "root@$ip:/tmp/"
  ssh -o StrictHostKeyChecking=no -i "$KEY" "root@$ip" "bash /tmp/install-node-exporter.sh"
  echo "✓ $hostname"
done

Verifying all targets in Prometheus

After the config is updated and Prometheus reloaded:

curl -s http://127.0.0.1:9090/api/v1/targets | python3 -c \
  "import json,sys;d=json.load(sys.stdin);[print(t['labels']['instance'],t['health']) for t in d['data']['activeTargets']]"

Pitfalls

  • Security scanners blocking raw IPs in SSH/SCP commands. Using hostnames where available bypasses false-positive security warnings.
  • All 9 installs can run sequentially in ~90 seconds total — no parallelism needed.
  • UFW/firewall must allow incoming port 9100 from Core's IP, or Prometheus must scrape via hostname/SSH tunnel. The existing servers had no restrictive UFW rules blocking port 9100.
  • node_exporter listens on all interfaces by default (0.0.0.0:9100). If restricting to localhost, add --web.listen-address=127.0.0.1:9100 to ExecStart and scrape via a local proxy or Tailscale.