当你的软件即服务(SaaS)产品需要满足 99.99% 的服务等级协议(SLA)时,基础设施必须能够自动吸收故障。99.99% 的 SLA 每年只允许大约 52 分钟 36 秒的停机时间。如果主负载均衡器在周日凌晨 2 点发生故障,系统需要在几秒内恢复,远早于工程师介入的时间。

有经验的 Linux 基础设施管理员可以在为需要高可用、无中断运行的 SaaS 应用提供托管 IT 服务时使用此架构。该架构由三个组件组成:

  • NGINX - 在两个(或更多)Web 服务器上提供你的应用
  • HAProxy - 通过健康检查将流量分发到这些 Web 服务器
  • Keepalived - 运行在两个负载均衡节点上,共享一个浮动(虚拟)IP 地址,通过 VRRP 实现自动故障转移

它们共同提供自动故障转移和弹性负载均衡,旨在最大限度地减少服务中断。

在本指南中,我们将解释如何从头构建整个架构。该架构由两个负载均衡器共享一个浮动 IP 地址,并在它们之间自动故障转移,位于两个 Web 服务器之前。

本文中的命令和配置文件已在 Ubuntu 26.04 LTS("Resolute Raccoon") 上测试,并且也可以在 Ubuntu 24.04 LTS("Noble Numbat") 上原样使用。

到本指南结束时,你将拥有一个高可用的 SaaS 基础设施,旨在最大限度地减少停机时间,并支持面向 99.99% SLA 的应用。

架构概述

                 +---------------------+
                 |   Client (curl)     |
                 +----------+----------+
                            |
                            | 访问浮动 IP 192.168.1.100
                            |
                 +----------v----------+
                 |   Floating IP      |
                 |   192.168.1.100    |
                 +----------+----------+
                            |
              +-------------+-------------+
              |                           |
     +--------v--------+       +--------v--------+
     |   node-lb01     |       |   node-lb02     |
     |  Keepalived     |       |  Keepalived     |
     |  HAProxy        |       |  HAProxy        |
     +--------+--------+       +--------+--------+
              |                           |
              +-------------+-------------+
                            |
              +-------------+-------------+
              |                           |
     +--------v--------+       +--------v--------+
     |   web01         |       |   web02         |
     |   NGINX         |       |   NGINX         |
     +-----------------+       +-----------------+

工作原理:

  1. Keepalived 在两个负载均衡器上运行,并使用 VRRP(虚拟路由冗余协议) 选举一个节点为 MASTER。MASTER 持有浮动 IP 192.168.1.100。
  2. HAProxy 始终在两个负载均衡器上运行,监听浮动 IP,并根据健康检查将流量转发到 web01 和 web02。
  3. 如果 node-lb01 发生故障(崩溃、网络中断、HAProxy 进程死亡),node-lb02 上的 Keepalived 会检测到缺少 VRRP 通告,并将自己提升为 MASTER,在 1-3 秒内接管浮动 IP。
  4. web01 和 web02 上的 NGINX 提供实际应用。HAProxy 持续检查它们的健康状态,并自动将故障节点从轮询中移除。

拓扑

主机名 IP 地址 角色
node-lb01 192.168.1.11 负载均衡器(MASTER)
node-lb02 192.168.1.12 负载均衡器(BACKUP)
web01 192.168.1.21 Web 服务器
web02 192.168.1.22 Web 服务器
浮动 IP 192.168.1.100 虚拟 IP

先决条件

  • 五台 Ubuntu 26.04 LTS(或 24.04 LTS)机器或虚拟机,与上表匹配,所有机器位于同一二层网络(VRRP 依赖多播/广播,因此两个负载均衡节点必须共享一个子网)。
  • 所有机器上的 root 或 sudo 访问权限。
  • 防火墙规则允许:
    • 从客户端到浮动 IP 的端口 80/443
    • 从负载均衡节点到 Web 服务器的端口 80
    • 两个负载均衡节点之间的协议 VRRP(IP 协议 112)和多播地址 224.0.0.18
  • 熟悉 systemd 和通过 SSH 编辑配置文件。

Ubuntu 26.04 自带 UFW(底层由 nftables 支持),但默认禁用,因此在你启用它之前不会干扰任何东西。如果你确实想启用它,以下是匹配此拓扑的规则。在启用 UFW 之前在相应主机上运行,以免 SSH 锁定自己:

# 在 node-lb01 和 node-lb02 上
sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp
sudo ufw allow from 192.168.1.0/24 to any port 80 proto tcp
sudo ufw allow from 192.168.1.0/24 to any port 443 proto tcp
sudo ufw allow from 192.168.1.0/24 to any port 8080 proto tcp  # HAProxy stats
sudo ufw allow proto 112 from 192.168.1.11 to 192.168.1.12
sudo ufw allow proto 112 from 192.168.1.12 to 192.168.1.11
sudo ufw allow from 224.0.0.18 to any proto 112
sudo ufw enable

如果你的两个负载均衡器是云虚拟机(AWS、Azure、GCP 等)而不是裸机或本地虚拟机,请先阅读第 6 部分中关于单播 VRRP 的说明。大多数云网络默认会静默丢弃 VRRP 使用的多播流量,Keepalived 看起来正常工作,但实际上永远不会故障转移。

第 1 部分:设置 Web 服务器(web01、web02)

在 web01 和 web02 上都运行本节内容。

1.1 更新系统并安装 NGINX

sudo apt update
sudo apt install nginx -y

1.2 确认 NGINX 正在运行

sudo systemctl status nginx
sudo systemctl enable nginx

1.3 创建区分测试页面

这可以让你稍后直观地确认 HAProxy 是否正确负载均衡。在每个主机上运行相应的命令。

在 web01 上:

echo "Response from web01" | sudo tee /var/www/html/index.html

在 web02 上:

echo "Response from web02" | sudo tee /var/www/html/index.html

1.4 添加轻量级健康检查端点

HAProxy 将轮询此路径以确定后端是否健康。将其与应用根路径分开,意味着你可以独立于应用逻辑返回受控的 200/503 响应。

sudo tee /var/www/html/health <<'EOF'
ok
EOF

从另一台机器验证:

curl http://192.168.1.21/health
curl http://192.168.1.22/health

两者都应返回 ok。

第 2 部分:设置 HAProxy(node-lb01、node-lb02)

在两个负载均衡节点上都运行本节内容。两个节点上的配置相同。

2.1 安装 HAProxy

sudo apt update
sudo apt install haproxy -y

Ubuntu 26.04 的默认仓库直接提供 HAProxy 3.0,对于本指南来说足够新(Ubuntu 24.04 提供 HAProxy 2.6,也可以与下面的配置配合使用)。因此,不需要 PPA 或第三方仓库。

验证你得到的版本:

haproxy -v

或者:

haproxy -vv | grep -E "HAProxy|version"

示例输出:

HAProxy version 3.0.0-1ubuntu1
Copyright (C) 2000-2024 Willy Tarreau - [email protected]

2.2 配置 HAProxy

备份默认配置,然后替换它:

sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
sudo tee /etc/haproxy/haproxy.cfg <<'EOF'
global
    log /dev/log local0
    log /dev/log local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

defaults
    log global
    mode http
    option httplog
    option dontlognull
    timeout connect 5000
    timeout client 50000
    timeout server 50000

frontend http_front
    bind 192.168.1.100:80
    stats uri /haproxy?stats
    default_backend web_servers

backend web_servers
    balance roundrobin
    option httpchk GET /health
    server web01 192.168.1.21:80 check fall 3 rise 2 inter 2s
    server web02 192.168.1.22:80 check fall 3 rise 2 inter 2s
EOF

关于此配置的说明:

  • bind 192.168.1.100:80 - HAProxy 绑定到浮动 IP,而不是节点自身的 IP。这意味着 HAProxy 需要 net.ipv4.ip_nonlocal_bind(见下文),因为浮动 IP 不会出现在 BACKUP 节点的接口上。
  • option httpchk 配合 check fall 3 rise 2 inter 2s - 后端在连续 3 次检查失败后被标记为 down,在连续 2 次成功后标记为 healthy,每 2 秒检查一次。这避免了单个丢包导致的抖动。
  • 在部署到任何类似生产环境之前,更改 stats 页面密码。
  • option httpchk(方法 + URI,不附加额外内容)在 HAProxy 3.0 中仍然完全支持,并且是基本检查的最简单形式。如果你以后想向检查请求添加自定义标头或特定 HTTP 版本,请使用较新的 http-check send 语法。将额外细节塞到 option httpchk 行末尾已弃用,并会抛出配置警告。

2.3 允许 HAProxy 绑定到非本地 IP

由于浮动 IP 仅物理存在于当前 MASTER 节点上,两个节点都需要提前获得绑定它的权限:

sudo sysctl -w net.ipv4.ip_nonlocal_bind=1

要使此设置在重启后仍然有效,请将其添加到 /etc/sysctl.conf:

echo "net.ipv4.ip_nonlocal_bind=1" | sudo tee -a /etc/sysctl.conf

2.4 验证并启动 HAProxy

sudo haproxy -c -f /etc/haproxy/haproxy.cfg
sudo systemctl restart haproxy
sudo systemctl enable haproxy

接下来,我们将在两个负载均衡器上设置 Keepalived。

第 3 部分:设置 Keepalived(node-lb01、node-lb02)

3.1 安装 Keepalived

在两个节点上:

sudo apt install keepalived -y

3.2 创建健康检查脚本

Keepalived 只应在节点上的 HAProxy 实际存活时通告浮动 IP。

在两个节点上创建此脚本:

sudo tee /etc/keepalived/check_haproxy.sh <<'EOF'
#!/bin/bash
if systemctl status haproxy | grep -q "active (running)"; then
    exit 0
else
    exit 1
fi
EOF

使其可执行:

sudo chmod +x /etc/keepalived/check_haproxy.sh

3.3 在 node-lb01(MASTER)上配置 Keepalived

为 Master 节点创建 keepalived 配置文件:

sudo tee /etc/keepalived/keepalived.conf <<'EOF'
global_defs {
    router_id LVS_DEVEL
}

vrrp_script check_haproxy {
    script "/etc/keepalived/check_haproxy.sh"
    interval 2
    weight -20
    fall 3
    rise 2
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 101
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1234
    }
    virtual_ipaddress {
        192.168.1.100
    }
    track_script {
        check_haproxy
    }
}
EOF

将 eth0 替换为你的实际网络接口名称。你可以使用 ip link 命令检查。在许多云镜像上,这是 ens5、ens33 或类似名称。

3.4 在 node-lb02(BACKUP)上配置 Keepalived

在第二个节点上使用相同的文件,但有两处不同:state BACKUP 和较低的 priority。

sudo tee /etc/keepalived/keepalived.conf <<'EOF'
global_defs {
    router_id LVS_DEVEL
}

vrrp_script check_haproxy {
    script "/etc/keepalived/check_haproxy.sh"
    interval 2
    weight -20
    fall 3
    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 1234
    }
    virtual_ipaddress {
        192.168.1.100
    }
    track_script {
        check_haproxy
    }
}
EOF

关键参数说明:

  • virtual_router_id - 在两个节点上必须相同;这是它们识别彼此属于同一 VRRP 组的方式。如果 LAN 上存在其他 VRRP 组,则必须唯一。
  • priority - 较高者赢得选举。node-lb01(101)在两者都健康时成为 MASTER;node-lb02(100)在 node-lb01 的有效优先级降至 100 以下时接管。
  • track_script 配合 weight -20 - 这是将 Keepalived 的故障转移与 HAProxy 的健康状况联系起来的实际部分。在 Keepalived 中,一旦跟踪的脚本连续失败 fall(3)次,负权重就会从实例的优先级中减去。正权重会做相反的事情(成功时增加优先级),并且不会在此触发故障转移。使用 weight -20,如果 HAProxy 在 node-lb01 上死亡,其有效优先级从 101 降至 81——低于 node-lb02 的 100——因此 node-lb02 接管浮动 IP。
  • auth_pass - 必须在两个节点上匹配。它可以防止同一网络上无关的 VRRP 流量干扰。请注意,auth_type PASS 会在线路上以明文发送此密码(实际上只使用前 8 个字符)。它旨在阻止共享 LAN 上无关 VRRP 组之间的意外串扰,而不是抵御已经在该网络上的恶意行为者。如果你需要真正防止伪造的 VRRP 流量,请改用 Keepalived 较新的 auth_type AH 选项。
  • advert_int 1 - MASTER 每 1 秒发送一次通告;BACKUP 在大约 3 个错过的间隔后认为 MASTER 死亡。

3.5 启动 Keepalived

在两个节点上:

sudo systemctl start keepalived
sudo systemctl enable keepalived

3.6 验证浮动 IP

在 node-lb01 上,确认它现在拥有浮动 IP:

ip addr show eth0
ip addr show eth0 | grep 192.168.1.100

你应该在 MASTER 节点上看到 192.168.1.100 列为辅助地址。

来自 node-lb01 的示例输出:

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    inet 192.168.1.11/24 brd 192.168.1.255 scope global eth0
    inet 192.168.1.100/32 scope global eth0

在 node-lb02 上,同样的命令应该什么都不显示。它处于 BACKUP 状态。

来自 node-lb02 的示例输出:

(无输出)

检查 Keepalived 日志以确认状态转换:

sudo journalctl -u keepalived

在 MASTER 节点上,你会看到:

Keepalived_vrrp[12345]: VRRP_Instance(VI_1) Transition to MASTER STATE
Keepalived_vrrp[12345]: VRRP_Instance(VI_1) Entering MASTER STATE

在 Backup 节点上,你会看到:

Keepalived_vrrp[12345]: VRRP_Instance(VI_1) Entering BACKUP STATE

第 4 部分:端到端测试

从网络上的任何客户端机器:

curl http://192.168.1.100/

运行几次,你应该看到响应在 "Response from web01" 和 "Response from web02" 之间交替,这要归功于 HAProxy 的轮询平衡。

检查 HAProxy stats 页面(从浏览器或通过 SSH 隧道,因为此配置未将其暴露在外部):

curl http://192.168.1.11:8080/haproxy?stats
curl http://192.168.1.12:8080/haproxy?stats

你应该看到 web01 和 web02 都列为 UP(绿色)。

MASTER 节点的 HAProxy Stats 页面:

(截图省略)

第 5 部分:测试故障转移

这是实际验证"高可用"声明的部分。不要跳过。

5.1 模拟负载均衡器故障

在 node-lb01(当前 MASTER)上,停止 Keepalived:

sudo systemctl stop keepalived

几秒钟内,转到 node-lb02 并检查浮动 IP:

ip addr show eth0 | grep 192.168.1.100

它现在应该显示浮动 IP。同时,从客户端运行连续的 curl 循环以确认没有明显中断:

while true; do curl -s -o /dev/null -w "%{http_code}\n" http://192.168.1.100/; sleep 1; done

在转换期间,你应该看到最多一两个失败/缓慢的请求,然后流量通过 node-lb02 正常恢复。

重新启动 node-lb01 上的 Keepalived 以将其恢复为 MASTER(其较高的优先级意味着它将自动重新声明浮动 IP):

sudo systemctl start keepalived

转到 node-lb02 并验证它是否使用浮动 IP。这次你不会看到浮动 IP。

5.2 模拟 Web 服务器故障

停止 web01 上的 NGINX:

sudo systemctl stop nginx

观察 HAProxy stats 页面。web01 应在约 6 秒内(3 次失败检查 × 2 秒间隔)翻转为 DOWN,并且所有流量应转移到 web02,客户端可见错误为零,因为 HAProxy 在后端被标记为 down 的那一刻就停止路由到它。

重新启动 NGINX 并确认 web01 重新加入轮询:

sudo systemctl start nginx

5.3 模拟活动节点上的 HAProxy 故障

停止当前 MASTER 节点上的 HAProxy(不是 Keepalived):

sudo systemctl stop haproxy

由于 track_script 块,Keepalived 应通过 check_haproxy 检测到这一点并降级自身,将浮动 IP 移交给另一个节点,即使 Keepalived 本身仍在运行。

现在尝试访问 MASTER 节点的 HAProxy stats 页面,即 http://192.168.1.11:8080/haproxy?stats。它将无法加载。

你仍然可以访问 BACKUP 节点的 HAProxy stats 页面,即 http://192.168.1.12:8080/haproxy?stats,并查看所有节点的统计信息。

这是天真的仅 Keepalived 设置(不检查 HAProxy 健康)会完全错过的场景,使浮动 IP 指向一个代理已死的节点。

第 6 部分:生产环境加固

一个可用的故障转移演示并不等同于生产就绪的架构。在投入生产之前,请考虑:

1. TLS 终止

本指南为清晰起见使用了纯 HTTP。在生产环境中,使用 Let's Encrypt 通过 certbot 在 HAProxy(或后端 NGINX,或两者)终止 TLS,并将端口 80 重定向到 443。

2. 如果多播不可靠,使用单播 VRRP

一些云提供商(AWS、Azure、GCP)阻止多播/广播流量,而 VRRP 默认依赖这些流量。在 vrrp_instance 块内使用 unicast_peer 和 unicast_src_ip 指令来改为通过单播运行 VRRP。

3. 防火墙规则

将 HAProxy stats 页面(端口 8080)锁定为仅内部 IP,并限制两个负载均衡节点之间的入站 VRRP 流量仅限彼此。

4. 更多后端 Web 服务器

此模式可以干净地扩展。向 HAProxy 后端块添加更多 server 行。

5. 监控和告警

将 HAProxy 和 Keepalived 日志发送到中央系统(例如 Prometheus + HAProxy exporter,或日志聚合器),并对 VRRP 状态转换发出告警。故障转移正常工作很好,但你仍然需要知道它发生了。

6. 会话持久性

如果你的应用依赖服务器端会话(不是无状态/JWT 类型),请向后端块添加 cookie 指令,或将会话状态移动到共享存储(如 Redis),以便任一后端都可以服务任何请求。

7. 配置管理

手动验证后,将 HAProxy 和 Keepalived 配置迁移到 Ansible、Terraform 或你选择的其他配置工具,以便两个负载均衡节点保持同步,并且可以可重复地构建新节点。

为什么这能让你接近 99.99%

正常运行时间数学是无情的。正如我们所说,99.99% 每年允许大约 52 分钟 36 秒的停机时间,或大约 4 分 23 秒每月。单个负载均衡器或单个 Web 服务器很容易因一次糟糕的内核更新或一次硬件故障而超出该预算。

此架构在两层消除了单点故障:

  • 负载均衡器层: Keepalived 的 VRRP 故障转移通常在 1-3 秒内完成,并且由于它还跟踪 HAProxy 自身的健康状况(不仅仅是机器是否启动),挂起或崩溃的代理进程也会触发故障转移。
  • 应用层: HAProxy 的活动健康检查会在几秒钟内将故障 Web 服务器从轮询中移除,流量继续从剩余节点提供服务。

此架构不能自行解决的是应用级错误、数据库故障转移、DNS 级中断,或同时导致两个负载均衡器故障的故障(例如共享电源/网络依赖)。

因此,如果 99.99% 是硬性 SLA 承诺,请确保两个负载均衡器和两个 Web 服务器位于真正独立的故障域(单独的机架、可用区或主机),而不仅仅是同一虚拟机监控程序上的独立虚拟机。

总结

你现在拥有:

  • 两个 NGINX Web 服务器,提供内容和健康检查端点
  • 两个 HAProxy 实例,通过活动健康检查在这些 Web 服务器之间进行负载均衡
  • 两个 Keepalived 实例,通过 VRRP 共享浮动 IP,故障转移与 HAProxy 的实际健康状况相关联,而不仅仅是节点存活状态

这是无数生产 SaaS 平台在底层使用的相同模式,并且完全开源、可自托管、与云无关。从这里开始,自然的下一步是 TLS 终止、配置自动化和监控分层,以便故障转移可见而不是静默。

附:原文受保护标识符

while true; do curl -s -o /dev/null -w "%{http_code} %{time_total}s\n" http://192.168.0.100/; sleep 0.5; done Running on: Linux 7.0.0-28-generic #28-Ubuntu SMP PREEMPT_DYNAMIC Sun Jun 21 01:01:36 UTC 2026 x86_64 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 sudo ufw allow from 192.168.0.0/24 to any port 8404 proto tcp   # stats page, LAN only echo "<h1>Response from web01 (192.168.0.21)</h1>" | sudo tee /var/www/html/index.html echo "<h1>Response from web02 (192.168.0.22)</h1>" | sudo tee /var/www/html/index.html Status: long-term supported branch - will stop receiving fixes around Q2 2030. Aug 09 08:52:57 node-lb01 Keepalived_vrrp[15913]: (VI_1) Entering MASTER STATE Aug 09 08:52:57 node-lb02 Keepalived_vrrp[15682]: (VI_1) Entering BACKUP STATE
echo "net.ipv4.ip_nonlocal_bind = 1" | sudo tee -a /etc/sysctl.conf HAProxy version 3.2.9-1ubuntu2.2 2026/06/19 - https://haproxy.org/ sudo tee /etc/keepalived/check_haproxy.sh > /dev/null << 'EOF' sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak inet6 fe80::be24:11ff:fe29:90f6/64 scope link proto kernel_ll inet 192.168.0.100/24 scope global secondary proto 0x12 eth0 http-check send meth GET uri /healthz hdr Host example.com sudo ufw allow from 192.168.0.11 to 224.0.0.18 proto vrrp sudo ufw allow from 192.168.0.12 to 224.0.0.18 proto vrrp sudo ufw allow from 192.168.0.11 to any port 80 proto tcp
sudo ufw allow from 192.168.0.12 to any port 80 proto tcp inet 192.168.0.11/24 brd 192.168.0.255 scope global eth0 Known bugs: http://www.haproxy.org/bugs/bugs-3.2.9.html # Stats page for quick visibility into backend health Keepalived + HAProxy            Keepalived + HAProxy link/ether bc:24:11:29:90:f6 brd ff:ff:ff:ff:ff:ff node-lb01 (MASTER)             node-lb02 (BACKUP) 192.168.0.21 (NGINX)         192.168.0.22 (NGINX) sudo chmod +x /etc/keepalived/check_haproxy.sh sudo journalctl -u keepalived -n 30 --no-pager
192.168.0.11                    192.168.0.12 if systemctl is-active --quiet haproxy; then sudo haproxy -c -f /etc/haproxy/haproxy.cfg echo "OK" | sudo tee /var/www/html/healthz sudo sysctl -w net.ipv4.ip_nonlocal_bind=1 sudo nano /etc/keepalived/keepalived.conf script "/etc/keepalived/check_haproxy.sh" valid_lft forever preferred_lft forever sudo apt update && sudo apt upgrade -y # Exit 0 = healthy, exit 1 = unhealthy
sudo systemctl enable --now keepalived default-server inter 2s fall 3 rise 2 stats auth admin:ChangeThisPassword! sudo systemctl enable --now haproxy ip a show eth0 | grep 192.168.0.100 web01                        web02 sudo nano /etc/haproxy/haproxy.cfg server web01 192.168.0.21:80 check server web02 192.168.0.22:80 check # On both node-lb01 and node-lb02
sudo systemctl enable --now nginx │                              │ └──────────────┬───────────────┘ curl http://192.168.0.21/healthz curl http://192.168.0.22/healthz sudo systemctl status keepalived ┌──────────────┴──────────────┐ sudo systemctl start keepalived │                            │ sudo apt install -y keepalived
http://192.168.0.11:8404/stats http://192.168.0.12:8404/stats sudo systemctl stop keepalived ┌─────────────┴─────────────┐ sudo systemctl status haproxy net.ipv4.ip_nonlocal_bind = 1 http-check expect status 200 sudo systemctl status nginx sudo apt install -y haproxy default_backend web_servers
option httpchk GET /healthz sudo systemctl stop haproxy Floating IP: 192.168.0.100 log /dev/log local1 notice auth_pass ChangeThisSecret curl http://192.168.0.100/ sudo systemctl start nginx # On both web01 and web02 sudo apt install -y nginx vrrp_script chk_haproxy {
sudo systemctl stop nginx altname enxbc24112990f6 sudo ufw allow 22/tcp sudo ufw allow 80/tcp # Then, on each host: bind 192.168.0.100:80 vrrp_instance VI_1 { virtual_router_id 51 log /dev/log local0 option  dontlognull
timeout client  30s timeout server  30s frontend http_front backend web_servers virtual_ipaddress { cookie SRVID insert Internet / Clients timeout connect 5s balance roundrobin stats refresh 10s
virtual_router_id stats uri /stats authentication { 192.168.0.100/24 check_haproxy.sh sudo ufw enable sudo haproxy -v option  httplog altname enp0s18 log     global
interface eth0 auth_type PASS track_script { ip a show eth0 option httpchk unicast_src_ip group haproxy 192.168.0.100 fall 3 rise 2 vrrp_instance
maxconn 4096 user haproxy mode    http listen stats stats enable state MASTER priority 150 advert_int 1 state BACKUP priority 100
track_script unicast_peer bind *:8404 #!/bin/bash chk_haproxy haproxy -v interval 2 weight -60 224.0.0.18 retries 3
node-lb01 node-lb02 auth_pass auth_hmac defaults priority certbot global daemon exit 0
exit 1 fall 3 rise 2 server [...] web01 web02 else VRRP eth0
ip a ens3 ens5 fall DOWN EOF fi OK UP -v
-a -c -s -o │ ▼ }