Health-check scripts driven by the Patroni API
Keepalived is steered by short shell scripts that query the local Patroni REST API on http://127.0.0.1:8008 and exit non-zero when the node does not hold the expected role. The leader check reads .role from the /patroni endpoint and exits 0 only when it equals leader:
PATRONI_API_URL="http://127.0.0.1:8008"
role=$(curl -s $PATRONI_API_URL/patroni | jq -r .role)
if [ "$role" == "leader" ]; then exit 0; else exit 1; fi
A second script applies the same pattern for the replica role, exiting 0 on replica and 1 otherwise. Both are placed under /etc/keepalived/scripts/ (check_leader.sh, check_replica.sh).
Registering the checks with keepalived
Each script is wrapped in a vrrp_script block in /etc/keepalived/keepalived.conf, with identical timing: a 5-second interval, a 3-second timeout, and 2 failures or successes required to move the state:
check_leader— points at/etc/keepalived/scripts/check_leader.shcheck_replica— points at/etc/keepalived/scripts/check_replica.sh
Two VRRP instances, two virtual addresses
The configuration defines separate instances for the leader and replica roles, both starting in state BACKUP on eth0 with priority 100 and a 1-second advertisement interval, and both using PASS authentication.
VI_1carries the leader VIP192.168.1.10(virtual_router_id 51) and trackscheck_leader; its notify hooks arenotify_master.sh,notify_backup.shandnotify_fault.sh.VI_2carries the replica VIP192.168.1.20(virtual_router_id 52) and trackscheck_replica; its hooks arenotify_replica_master.sh,notify_replica_backup.shandnotify_replica_fault.sh.
Notify hooks
The notify scripts bound to each instance can be as small as a logging call, or extended to send a message elsewhere — for example a curl to a Slack channel:
#!/bin/bash
echo "VIP switched to leader" | logger



