User Tools

Site Tools


network:pihole_npm

Pi-hole High Availability (HA) Architecture

This page documents the complete high-availability DNS filtering solution used in the TorresVault network. The setup provides fault-tolerant DNS, automatic sync, and a floating VIP so clients always reach a working Pi-hole instance.


Overview

Two Pi-hole servers provide DNS filtering:

  • PiHole1 – 192.168.1.2
  • PiHole2 – 192.168.1.4
  • VIP (Virtual IP) – 192.168.1.5 (clients use this)

High availability is provided by:

  • Keepalived for virtual IP failover
  • Orbital-Sync (Docker) for Pi-hole configuration synchronization
  • Unifi DHCP providing the VIP (192.168.1.5) as the primary DNS server
  • Both Pi-holes fully running at all times, but only one holds the VIP

This ensures:

  • Zero downtime if a Pi-hole reboots
  • Identical configs on both systems
  • DNS continuity for all VLANs

Network Layout

Component Hostname IP Address Role
Pi-hole 1 pihole 192.168.1.2 Primary Pi-hole, may own VIP
Pi-hole 2 pihole2 192.168.1.4 Secondary Pi-hole, may own VIP
DNS VIP n/a 192.168.1.5 Floating IP assigned via Keepalived
DHCP Server UCG Max 192.168.1.1 Hands out DNS = 192.168.1.5

Keepalived Configuration

Both Pi-holes run `keepalived` and use VRRP.

Pi-hole1 (/etc/keepalived/keepalived.conf)

vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 200 advert_int 1 authentication { auth_type PASS auth_pass torresvault } virtual_ipaddress { 192.168.1.5/24 } }

Pi-hole2 (/etc/keepalived/keepalived.conf)

vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass torresvault } virtual_ipaddress { 192.168.1.5/24 } }

Keepalived automatically transfers 192.168.1.5 to the healthy node.


Orbital-Sync (Pi-hole Sync)

Orbital-Sync keeps:

  • Adlists
  • Whitelists
  • Blacklists
  • Regex filters
  • DHCP settings
  • Groups
  • Clients

…identical on both Pi-holes.

Docker Compose

Located at `/home/nathan/orbital-sync/docker-compose.yml`

version: β€œ3” services: orbital-sync: image: mattwebbio/orbital-sync:latest container_name: orbital-sync volumes: - ./config.yml:/config.yml:ro restart: unless-stopped

Config File (config.yml)

primaryHost: baseUrl: http://192.168.1.2

secondaryHosts:

baseUrl: http://192.168.1.4

sync: intervalMinutes: 15 adlists: true whitelist: true blacklist: true regexWhitelist: true regexBlacklist: true groups: true clients: true localDns: true cname: true


Sync Interval

Orbital-sync runs automatically:

  • Every 15 minutes
  • Sync direction: 192.168.1.2 β†’ 192.168.1.4

It detects changes on either Pi-hole and ensures both match.

Manual Sync Command

docker exec orbital-sync npm run sync

OR restart the container:

docker restart orbital-sync


Failover Behavior

Example Scenario

  • Pi-hole1 goes offline
  • Keepalived detects failure
  • Pi-hole2 takes VIP 192.168.1.5
  • Clients never notice β€” all DNS continues normally
  • When Pi-hole1 recovers, it becomes BACKUP

Failover time: typically 1–2 seconds.


How to Test HA

1. Open a terminal on Pi-hole1 2. Run:

sudo systemctl stop keepalived

3. The VIP should instantly move:

  • Pi-hole2 now shows: `hostname: PiHole2`
  • And `ip addr` confirms `192.168.1.5`

4. Restart keepalived:

sudo systemctl start keepalived


Troubleshooting

Common issues:

  • VIP not moving β†’ check keepalived config
  • Orbital-sync errors β†’ config.yml path or permissions
  • Docker needing `sudo` β†’ add user to docker group
  • Regex rules not syncing β†’ ensure regex sync is enabled
  • Pi-hole showing uneven stats β†’ normal; traffic is not load-balanced, only HA

network/pihole_npm.txt Β· Last modified: by nathna

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki