{"id":987,"date":"2026-08-27T22:39:27","date_gmt":"2026-08-27T22:39:27","guid":{"rendered":"https:\/\/virtualserversvps.com\/blog\/?p=987"},"modified":"2026-09-06T22:07:42","modified_gmt":"2026-09-06T22:07:42","slug":"vps-high-availability-keepalived-vrrp-failover","status":"publish","type":"post","link":"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/","title":{"rendered":"Building a Two-Node VPS Failover Cluster with Keepalived and VRRP"},"content":{"rendered":"<p class=\"wp-block-paragraph\">A single <a href=\"https:\/\/virtualserversvps.com\/\">VPS<\/a> is a single point of failure. Hardware failures, host crashes, and network outages all take your application offline. Keepalived uses the Virtual Router Redundancy Protocol (VRRP) to manage a floating IP address that automatically moves between two VPS nodes when one fails. This guide covers the complete setup: installation, configuration, health checks, and production-hardening steps.<\/p>\n<h2 class=\"wp-block-heading\">How VRRP Failover Works<\/h2>\n<p class=\"wp-block-paragraph\">VRRP elects one node as the MASTER. That node owns the floating IP address and responds to ARP requests for it. The MASTER sends heartbeat advertisements to the BACKUP node every second. If the BACKUP stops receiving those advertisements for three consecutive intervals, it assumes the MASTER is dead, promotes itself, and takes over the floating IP. Clients connect to the floating IP and never need to know which physical node is behind it.<\/p>\n<p class=\"wp-block-paragraph\">The key requirements are two VPS instances in the same layer-2 broadcast domain (same data center, same VLAN), and a spare public IP address that can be assigned to either node. Most providers offer floating IPs as an add-on service.<\/p>\n<h2 class=\"wp-block-heading\">Step 1: Network Preparation<\/h2>\n<p class=\"wp-block-paragraph\">Before installing Keepalived, verify that both VPS nodes can reach each other on their private or public interfaces and that VRRP traffic is allowed.<\/p>\n<pre class=\"wp-block-code\"><code># On both nodes, identify the interface for VRRP\nip addr show\n\n# Usually eth0 or ens3. Note the IP address and subnet.\n\n# Test connectivity between nodes\nping -c 3 &lt;other-node-ip&gt;\n\n# Verify VRRP protocol (112) is not blocked\n# On a modern system with nftables:\nsudo nft list ruleset | grep vrrp<\/code><\/pre>\n<p class=\"wp-block-paragraph\">If your VPS provider blocks multicast, you will use unicast mode \u2014 covered later in this guide.<\/p>\n<h2 class=\"wp-block-heading\">Step 2: Install Keepalived on Both Nodes<\/h2>\n<pre class=\"wp-block-code\"><code># Ubuntu\/Debian\nsudo apt update && sudo apt install keepalived -y\n\n# RHEL\/Rocky Linux\nsudo dnf install keepalived -y\n\n# Verify\nkeepalived --version\n# Should show version 2.2.x or later<\/code><\/pre>\n<h2 class=\"wp-block-heading\">Step 3: Configure the MASTER Node<\/h2>\n<p class=\"wp-block-paragraph\">Create <code>\/etc\/keepalived\/keepalived.conf<\/code> on the primary VPS:<\/p>\n<pre class=\"wp-block-code\"><code>global_defs {\n    router_id VPS_NODE_1\n    vrrp_skip_check_adv_addr\n    vrrp_garp_master_refresh 60\n}\n\nvrrp_script chk_service {\n    script \"\/etc\/keepalived\/check_service.sh\"\n    interval 2\n    weight -30\n    fall 2\n    rise 2\n}\n\nvrrp_instance VI_1 {\n    state MASTER\n    interface eth0\n    virtual_router_id 51\n    priority 100\n    advert_int 1\n\n    authentication {\n        auth_type PASS\n        auth_pass &lt;generate-a-random-password&gt;\n    }\n\n    virtual_ipaddress {\n        203.0.113.100\/24 dev eth0\n    }\n\n    track_script {\n        chk_service\n    }\n\n    notify_master \"\/etc\/keepalived\/notify.sh MASTER\"\n    notify_backup \"\/etc\/keepalived\/notify.sh BACKUP\"\n    notify_fault  \"\/etc\/keepalived\/notify.sh FAULT\"\n}<\/code><\/pre>\n<h2 class=\"wp-block-heading\">Step 4: Configure the BACKUP Node<\/h2>\n<p class=\"wp-block-paragraph\">The BACKUP configuration is nearly identical, with a lower priority and BACKUP state:<\/p>\n<pre class=\"wp-block-code\"><code>global_defs {\n    router_id VPS_NODE_2\n    vrrp_skip_check_adv_addr\n}\n\nvrrp_script chk_service {\n    script \"\/etc\/keepalived\/check_service.sh\"\n    interval 2\n    weight -30\n    fall 2\n    rise 2\n}\n\nvrrp_instance VI_1 {\n    state BACKUP\n    interface eth0\n    virtual_router_id 51\n    priority 50\n    advert_int 1\n\n    authentication {\n        auth_type PASS\n        auth_pass &lt;same-password-as-master&gt;\n    }\n\n    virtual_ipaddress {\n        203.0.113.100\/24 dev eth0\n    }\n\n    track_script {\n        chk_service\n    }\n\n    notify_master \"\/etc\/keepalived\/notify.sh MASTER\"\n    notify_backup \"\/etc\/keepalived\/notify.sh BACKUP\"\n    notify_fault  \"\/etc\/keepalived\/notify.sh FAULT\"\n}<\/code><\/pre>\n<h2 class=\"wp-block-heading\">Step 5: Health Check Script<\/h2>\n<p class=\"wp-block-paragraph\">The health check script determines whether the node is healthy enough to hold the floating IP. A simple but effective check tests whether your main service is running and responding:<\/p>\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\n# \/etc\/keepalived\/check_service.sh\n# Exit 0 = healthy, exit 1 = unhealthy\n\n# Check if nginx is running\nif ! systemctl is-active --quiet nginx; then\n    exit 1\nfi\n\n# Check if nginx responds on localhost\nif ! curl -sf --max-time 2 http:\/\/localhost:80\/health > \/dev\/null 2>&1; then\n    exit 1\nfi\n\nexit 0<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>sudo chmod +x \/etc\/keepalived\/check_service.sh<\/code><\/pre>\n<p class=\"wp-block-paragraph\">The weight of -30 means that when the check fails, the MASTER priority drops from 100 to 70. Since 70 is still above the BACKUP priority of 50, the MASTER retains the VIP unless two checks fail (dropping priority to 40, below the BACKUP). Adjust the weight and BACKUP priority to control how aggressively the cluster fails over.<\/p>\n<h2 class=\"wp-block-heading\">Step 6: Notification Script<\/h2>\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\n# \/etc\/keepalived\/notify.sh\nSTATE=$1\nNOW=$(date -Iseconds)\n\necho \"[$NOW] Keepalived state changed to: $STATE\" | systemd-cat -t keepalived\n\n# Send to a webhook (Discord, Slack, etc.)\ncurl -s -X POST \"https:\/\/hooks.slack.com\/services\/YOUR\/WEBHOOK\/URL\" \\\n    -H \"Content-Type: application\/json\" \\\n    -d \"{\\\"text\\\":\\\"VPS failover: Node $(hostname) is now $STATE\\\"}\" \\\n    > \/dev\/null 2>&1 || true<\/code><\/pre>\n<pre class=\"wp-block-code\"><code>sudo chmod +x \/etc\/keepalived\/notify.sh<\/code><\/pre>\n<h2 class=\"wp-block-heading\">Step 7: Start and Test the Cluster<\/h2>\n<pre class=\"wp-block-code\"><code># Start Keepalived on both nodes\nsudo systemctl enable --now keepalived\n\n# Check status\nsudo systemctl status keepalived\n\n# Verify which node holds the VIP\nip addr show eth0 | grep 203.0.113.100\n\n# Watch the logs during failover\nsudo journalctl -u keepalived -f<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Test the failover by stopping Keepalived on the MASTER:<\/p>\n<pre class=\"wp-block-code\"><code># On the MASTER: simulate failure\nsudo systemctl stop keepalived\n\n# On the BACKUP: check that the VIP moved\nip addr show eth0 | grep 203.0.113.100\n# Should show the VIP now<\/code><\/pre>\n<p class=\"wp-block-paragraph\">When you restart Keepalived on the original MASTER, it reclaims the VIP because its priority is higher.<\/p>\n<h2 class=\"wp-block-heading\">Handling VPS Provider Limitations<\/h2>\n<ul class=\"wp-block-list\">\n<li><strong>Multicast blocked:<\/strong> Add <code>unicast_peer { &lt;peer-ip&gt;; }<\/code> inside the <code>vrrp_instance<\/code> block on both nodes. This sends VRRP advertisements directly to the peer IP instead of multicast address 224.0.0.18.<\/li>\n<li><strong>Floating IP not offered:<\/strong> Ask your provider if they support bringing your own IP or if they have an API to reassign IPs. Some providers require an API call rather than VRRP for IP failover.<\/li>\n<li><strong>ARP cache delays:<\/strong> After failover, the floating IP is associated with a new MAC address. Keepalived sends gratuitous ARP, but some switches and routers have ARP suppression. The <code>vrrp_garp_master_refresh 60<\/code> directive sends periodic ARP refreshes to compensate.<\/li>\n<li><strong>Split-brain prevention:<\/strong> If the network link between nodes fails but both nodes remain up, each thinks the other is dead and both claim the VIP. Add a <code>vrrp_script<\/code> that pings the default gateway \u2014 if the gateway is unreachable, the node should drop to FAULT state.<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">Going Further: Active-Active with Multiple VRRP Instances<\/h2>\n<p class=\"wp-block-paragraph\">With two floating IPs and two VRRP instances, you can run both nodes as active servers. Node A is MASTER for VIP1 and BACKUP for VIP2. Node B is BACKUP for VIP1 and MASTER for VIP2. DNS round-robin or a load balancer distributes traffic across both VIPs. If either node fails, the other takes over both IPs. This doubles your capacity during normal operation while maintaining full redundancy.<\/p>\n<p class=\"wp-block-paragraph\">For a deeper look at VPS plans that support floating IPs and high-availability setups, visit our <a href=\"https:\/\/virtualserversvps.com\/\">VPS hosting comparison<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A single VPS is a single point of failure. Hardware failures, host crashes, and network outages all take your application offline. Keepalived uses the Virtual Router Redundancy Protocol (VRRP) to&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":1,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-987","post","type-post","status-publish","format-standard","hentry","category-vps-guides-tutorials"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Building a Two-Node VPS Failover Cluster with Keepalived and VRRP - Virtual Servers VPS Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building a Two-Node VPS Failover Cluster with Keepalived and VRRP\" \/>\n<meta property=\"og:description\" content=\"Building a Two-Node VPS Failover Cluster with Keepalived and VRRP\" \/>\n<meta property=\"og:url\" content=\"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/\" \/>\n<meta property=\"og:site_name\" content=\"Virtual Servers VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-27T22:39:27+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-06T22:07:42+00:00\" \/>\n<meta name=\"author\" content=\"Virtual-Servers-Vps-Editor\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Virtual-Servers-Vps-Editor\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/\",\"name\":\"Building a Two-Node VPS Failover Cluster with Keepalived and VRRP - Virtual Servers VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\"},\"datePublished\":\"2026-08-27T22:39:27+00:00\",\"dateModified\":\"2026-09-06T22:07:42+00:00\",\"author\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\"},\"breadcrumb\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/virtualserversvps.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building a Two-Node VPS Failover Cluster with Keepalived and VRRP\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/\",\"name\":\"Virtual Servers VPS Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\",\"name\":\"Virtual-Servers-Vps-Editor\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"caption\":\"Virtual-Servers-Vps-Editor\"},\"sameAs\":[\"https:\/\/virtualserversvps.com\/blog\"],\"url\":\"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Building a Two-Node VPS Failover Cluster with Keepalived and VRRP - Virtual Servers VPS Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/","og_locale":"en_US","og_type":"article","og_title":"Building a Two-Node VPS Failover Cluster with Keepalived and VRRP","og_description":"Building a Two-Node VPS Failover Cluster with Keepalived and VRRP","og_url":"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/","og_site_name":"Virtual Servers VPS Blog","article_published_time":"2026-08-27T22:39:27+00:00","article_modified_time":"2026-09-06T22:07:42+00:00","author":"Virtual-Servers-Vps-Editor","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Virtual-Servers-Vps-Editor","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/","url":"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/","name":"Building a Two-Node VPS Failover Cluster with Keepalived and VRRP - Virtual Servers VPS Blog","isPartOf":{"@id":"https:\/\/virtualserversvps.com\/blog\/#website"},"datePublished":"2026-08-27T22:39:27+00:00","dateModified":"2026-09-06T22:07:42+00:00","author":{"@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0"},"breadcrumb":{"@id":"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/virtualserversvps.com\/blog\/vps-high-availability-keepalived-vrrp-failover\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/virtualserversvps.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Building a Two-Node VPS Failover Cluster with Keepalived and VRRP"}]},{"@type":"WebSite","@id":"https:\/\/virtualserversvps.com\/blog\/#website","url":"https:\/\/virtualserversvps.com\/blog\/","name":"Virtual Servers VPS Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0","name":"Virtual-Servers-Vps-Editor","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","caption":"Virtual-Servers-Vps-Editor"},"sameAs":["https:\/\/virtualserversvps.com\/blog"],"url":"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/"}]}},"_links":{"self":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/987","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/comments?post=987"}],"version-history":[{"count":2,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/987\/revisions"}],"predecessor-version":[{"id":1063,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/987\/revisions\/1063"}],"wp:attachment":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/media?parent=987"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/categories?post=987"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/tags?post=987"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}