2026-04-26 16:15:21 +00:00
2026-04-26 16:15:21 +00:00
2026-04-26 15:19:21 +00:00
2026-04-26 16:06:50 +00:00
2026-04-26 16:10:11 +00:00

🧠 Pi-hole High Availability Cluster (Keepalived)

📖 Überblick

Dieses Setup implementiert ein hochverfügbares DNS-System basierend auf zwei Pi-hole Instanzen und Keepalived (VRRP).

Ziel:

  • Automatischer Failover bei Fehlern
  • Gemeinsame virtuelle IP (VIP)
  • Health-basierter Switch (nicht nur “Host down”)
  • Telegram-Benachrichtigung bei Zustandsänderungen
  • Monitoring über Uptime Kuma

🏗️ Architektur

Clients
   │
   ▼
VIP (192.168.178.10)
   │
   ├── Pi-hole MASTER (pinguAurum)
   └── Pi-hole BACKUP (pinguArgentum)
  • Clients nutzen nur die VIP
  • Keepalived entscheidet, welcher Node aktiv ist

🌐 Netzwerk

Komponente IP
VIP 192.168.178.10
Master 192.168.178.2
Backup 192.168.178.3

👉 Fritzbox DNS:

192.168.178.10
192.168.178.10

📦 Installation

Auf beiden Nodes:

apt update
apt install keepalived dnsutils -y

⚙️ Konfiguration

📁 /etc/keepalived/keepalived.conf

MASTER

vrrp_script chk_pihole {
    script "/usr/local/bin/check_pihole.sh"
    interval 2
    weight -100
    fall 2
    rise 2
}

vrrp_instance VI_PIHole {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass CHANGE_ME_SECURE
    }

    virtual_ipaddress {
        192.168.178.10
    }

    track_script {
        chk_pihole
    }

    notify_master "/usr/local/bin/failover.sh MASTER"
    notify_backup "/usr/local/bin/failover.sh BACKUP"
    notify_fault  "/usr/local/bin/failover.sh FAULT"
}

BACKUP

Unterschied:

state BACKUP
priority 100
nopreempt

🧪 Health Check

📁 /usr/local/bin/check_pihole.sh

#!/bin/bash

# 1. FTL muss laufen
systemctl is-active --quiet pihole-FTL || exit 1

# 2. DNS muss antworten
dig google.com @127.0.0.1 +time=1 +tries=1 +short | grep -q . || exit 1

# 3. Blocking muss funktionieren
dig doubleclick.net @127.0.0.1 +time=1 +tries=1 +short | grep -Eq "0.0.0.0|::" || exit 1

# 4. NTP muss synchron sein
timedatectl | grep -q "synchronized: yes" || exit 1

# 5. Blocking darf nicht deaktiviert sein
pihole status | grep -q "blocking enabled" || exit 1

exit 0
chmod +x /usr/local/bin/check_pihole.sh

📡 Telegram Benachrichtigung

📁 /usr/local/bin/failover.sh

#!/bin/bash

STATE=$1
HOST=$(hostname)

TOKEN="YOUR_TOKEN"
CHAT_ID="YOUR_CHAT_ID"

curl -s -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
  -d chat_id="${CHAT_ID}" \
  -d text="🧠 Pi-hole Cluster Event:
Host: ${HOST}
State: ${STATE}"
chmod +x /usr/local/bin/failover.sh

▶️ Service starten

systemctl enable keepalived
systemctl restart keepalived

🧪 Tests

VIP vorhanden?

ip a | grep 192.168.178.10

DNS funktioniert?

nslookup google.com 192.168.178.10

Blocking funktioniert?

nslookup doubleclick.net 192.168.178.10

🔥 Failover testen

systemctl stop pihole-FTL

Erwartung:

  • Backup übernimmt VIP
  • Telegram Nachricht wird gesendet

📊 Monitoring (Uptime Kuma)

Empfohlene Checks:

1. VIP DNS

  • 192.168.178.10
  • Domain: google.com

2. VIP Blocking

  • Domain: doubleclick.net
  • Erwartung: 0.0.0.0

3. Einzelne Nodes

  • 192.168.178.2
  • 192.168.178.3

⚠️ Typische Probleme

Problem Ursache
Kein Failover Gewicht zu gering
Keine Telegram Alerts notify_* außerhalb der Instance
Werbung trotz Pi-hole Client nutzt anderen DNS
Handy ignoriert Pi-hole Private DNS / IPv6

🧠 Designentscheidungen

  • Aggressiver Failover (auch bei Soft-Errors)
  • VIP statt Multi-DNS
  • Health-basiertes Routing
  • Kein echter Cluster-State (bewusst simpel gehalten)

🚀 Mögliche Erweiterungen

  • Gravity Sync (Blocklisten synchronisieren)
  • Config Sync zwischen Nodes
  • Firewall-Regeln gegen externen DNS
  • API-basierter Health Check
  • GitOps Deployment über Gitea

🧩 Fazit

Dieses Setup bietet:

  • Hohe Verfügbarkeit
  • Schnellen Failover (<2 Sekunden)
  • Transparente Zustandsüberwachung
  • Automatische Fehlerreaktion

Status: 🟢 Stabil Failover: 🟢 Funktioniert Monitoring: 🟢 Aktiv Alerts: 🟢 Telegram integriert


S
Description
No description provided
Readme 34 KiB
Languages
Shell 100%