Home Assistant add-on for Keepalived loadbalancing and high-availability virtual IPs using Virtual Router Redundancy Protocol (VRRP). A common use case is running a DNS server on the Home Assistant host, such as AdGuard Home or PiHole, as well as a second instance on another server.
This currently wraps the Docker Keepalived package shawly/docker-keepalived, but that may change in the future if there is a more supported Docker Keepalived project.
If you have trouble with installation and configuration, visit the HA keepalived discussion group to ask questions. The developers are just volunteers from the community and do not provide any support.
If you have bug fixes or code improvements, please submit Pull Requests with your tested changes and the developers will review!
To install this in Home Assistant:
-
Go to the "Add-On Store" on your Home Assistant server, add this repository URL:
https://github.com/rsnodgrass/hassio-addons
-
Find "Keepalived" in the list of add-ons and click Install
To setup the Keepalived HA add-on, your custom configuration file needs to exist on the Home Assistant host in /config/keepalived.conf
. See Keepalived docs for how to properly configure in various configurations for DNS, reverse proxies, etc.
The following keepalived.conf
example shows a possible configuration for a highly available DNS server cluster using the Adguard Home add-on for Home Assistant, in my case running on a Raspberry Pi 5.
# /config/keepalived.conf for DNS running on Home Assistant (e.g. Adguard or PiHole DNS)
global_defs {
router_id dns-homeassistant # hostname is used by default
}
vrrp_instance dns_vip {
state MASTER # Home Assistant host is setup as primary
virtual_router_id 53 # convention to prefer port as the vrid (53=DNS)
priority 100 # priority on all secondary (BACKUP) must < the primary DNS server (aka MASTER)
interface end0
virtual_ipaddress {
192.168.1.2/24 dev end0 # MUST match interface above (otherwise listens on ALL interfaces)
}
authentication {
auth_type PASS
auth_pass rand0m_passw0rd
}
}
# UDP DNS lookups
virtual_server 192.168.1.2 53 {
protocol UDP
delay_loop 5
lb_algo wrr # weighted round robin
real_server 192.168.1.22 53 {
weight 100
DNS_CHECK {
name example.com
}
}
real_server 192.168.1.33 53 {
weight 100
DNS_CHECK {
name example.com
}
}
}
# TCP DoH DNS lookups
virtual_server 192.168.1.2 53 {
protocol TCP
delay_loop 5
lb_algo wrr # weighted round robin
real_server 192.168.1.22 53 {
weight 100
TCP_CHECK {
connect_timeout 3
connect_port 53
}
}
real_server 192.168.1.33 53 {
weight 100
TCP_CHECK {
connect_timeout 3
connect_port 53
}
}
}
Once installed and running, if you go to Settings > System > Network > Configure network interface
in Home Assistant, the IP address for any Keepalived virtual interfaces created in keepalived.conf
should be listed.
Once an add-on/daemon has started, it generally cannot listen to a new interface that is created (unless it is written to proactively probe for new interfaces and bind a new listener).
For example, the AdGuard add-on only listens to host interfaces that exist at the point in time AdGuard starts. Thus, the AdGuard DNS server should always be started AFTER keepalived is already running.
One advanced option is to auto-restart an add on whenever Keepalived starts. In this example for AdGuard Home:
-
Enable the sensor that can be enabled to determine if an addon is running. Home Assistant doesn't enable these by default. Go to Settings → Devices & Services → Supervisor → Entities then search for
binary_sensor.keepalived_running
, edit the sensor, and click Enable! -
Add this automation:
automation:
- alias: "Restart AdGuard after Keepalived Add-on Started"
id: restart_adguard_after_keepalived
trigger:
- platform: state
entity_id: binary_sensor.keepalived_running
from: 'off'
to: 'on'
for: 00:00:05
actions:
- service: hassio.addon_restart
data:
addon: "a0d7b954_adguard"
To avoid IP address conflicts on a LAN with DHCP setup, either set the keepalived IP address outside of the managed IP range OR create a DHCP reservation for a fake device MAC so that the IP address is not assigned to another device.
For example, create a reservation for the MAC 00:00:00:DB:DB:DB
within the DHCP server for the keepalived interface. In the example keepalived.conf
above this means creating a reservation for 192.168.1.2
.
- https://github.com/shawly/docker-keepalived
- Philipp Schmitt for a similar Home Assistant add that uses the the older, no-longer maintained osixia/docker-keepalived.