Setting up a High Availability (HA) pair for Pi-hole using Keepalived is surprisingly simple because it leverages a standard Linux tool designed for exactly this kind of network redundancy.
Let’s see Keepalived in action. Imagine two identical Pi-hole servers, pihole-a and pihole-b. We want a single IP address, the "floating IP" (let’s use 192.168.1.100), to always be managed by one of these servers. If pihole-a goes down, pihole-b should automatically take over 192.168.1.100.
Here’s a minimal keepalived.conf for pihole-a:
vrrp_script check_pihole {
script "/usr/local/bin/pihole status"
interval 2
weight 20
fall 2
rise 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass mysecretpassword
}
virtual_ipaddress {
192.168.1.100/24 dev eth0
}
track_script {
check_pihole
}
}
And for pihole-b, it’s almost identical, but with a crucial difference in priority:
vrrp_script check_pihole {
script "/usr/local/bin/pihole status"
interval 2
weight 20
fall 2
rise 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 90 # Lower priority for the backup node
advert_int 1
authentication {
auth_type PASS
auth_pass mysecretpassword
}
virtual_ipaddress {
192.168.1.100/24 dev eth0
}
track_script {
check_pihole
}
}
The problem this solves is single points of failure in DNS resolution. If your primary Pi-hole goes offline for maintenance or hardware failure, your network stops resolving domain names. Keepalived, using the Virtual Router Redundancy Protocol (VRRP), ensures that a secondary Pi-hole seamlessly takes over the responsibility of serving DNS requests via the floating IP.
Internally, Keepalived works by having nodes in a VRRP group (identified by virtual_router_id) send out multicast advertisements on the local network. The node with the highest priority is elected the MASTER and claims the virtual_ipaddress. If the MASTER stops sending advertisements (because it crashed or lost network connectivity), the other nodes detect this absence and the next highest priority node transitions to MASTER, acquiring the floating IP. The vrrp_script adds a layer of intelligence: it doesn’t just rely on the node being "up," but also checks if the Pi-hole service itself is running. If Pi-hole crashes on the MASTER, the script fails, causing the MASTER to relinquish the floating IP.
You control this setup primarily through the keepalived.conf file. Key parameters include:
state:MASTERorBACKUP. The initial state. The highest priority node will transition toMASTER.interface: The network interface where VRRP advertisements will be sent and on which the virtual IP will be bound.virtual_router_id: A unique number (0-255) for this VRRP group on your network. All nodes in the HA pair must use the same ID.priority: A number determining which node becomes MASTER. Higher is better.authentication: A simple password to ensure only authorized nodes participate in the VRRP group.virtual_ipaddress: The IP address and subnet mask that clients will use and that will float between nodes.vrrp_script: Allows you to define custom health checks. Theweightparameter adds or subtracts from the node’s priority based on the script’s success or failure.
The track_script directive links the health check to the VRRP instance. If check_pihole fails (returns non-zero), the priority of that node is reduced by the script’s weight. If the priority drops below that of a backup node, the backup will take over.
When clients in your network are configured to use the floating IP (192.168.1.100) as their DNS server, they are oblivious to the failover. As soon as the MASTER node becomes unreachable, the backup node picks up the floating IP, and clients, after their ARP cache times out (typically a few minutes, or sooner if they re-request DHCP), will start sending DNS queries to the new MASTER.
What most people overlook is the importance of the authentication section. Without it, any machine on the network that happens to be running Keepalived with the same virtual_router_id could potentially join your VRRP group and try to claim the floating IP, leading to IP conflicts and network chaos.
Once this is set up, the next logical step is to consider how to manage Pi-hole configuration across both nodes, which often leads to exploring solutions like Ansible for automated configuration deployment.