一、实现IPVS的高可用性
1.1 简介
1.1.1 IPVS 高可用核心方案:IPVS + Keepalived 双机热备
1.1.2 IPVS 的高可用本质是
用 Keepalived 做VIP 管理 + 故障切换,用 IPVS 做负载均衡转发,两者配合实现:
1.1.3 特点
流量始终可达:VIP 不随单节点故障失效
负载均衡不变:IPVS 规则在两台 LB 上一致
故障自动恢复:秒级切换,对业务无感知
二、 配置ipvs的高可用需要的环境
2.1 实验环境
|-------------|-----------------------------------------------------------|------|
| 主机名 | IP | 角色 |
| keepalived1 | 192.168.248.50 模式:仅主机 wg:192.168.248.2 | 调度器1 |
| keepalived2 | 192.168.248.60 模式:仅主机 wg:192.168.248.2 | 调度器2 |
| webserve1 | 192.168.248.10 模式:仅主机 wg:192.168.248.2 lo:192.168.248.100 | 服务器1 |
| webserver2 | 192.168.248.20 模式:仅主机 wg:192.168.248.2 lo:192.168.248.100 | 服务器2 |
| client | 192.168.198.10 模式:host-only | 客户端 |
2.2 配置webserver 的 ip,配置lvs相应的软件环境及文件
2.2.1 配置webserver IP lo回环ip
bash
[root@web1 system-connections]# cp eth0.nmconnection lo.nmconnection -p
[root@web1 system-connections]# vim lo.nmconnection
[connection]
id=lo
type=loopback
interface-name=lo
[ipv4]
method=manual
address1=127.0.0.1/8
address1=192.168.248.100/32
[root@web1 system-connections]# nmcli connection reload
[root@web1 system-connections]# nmcli connection up lo
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/5)
[root@web1 ~]# ip ad
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 192.168.248.100/32 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:f2:dc:c4 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 192.168.248.10/24 brd 192.168.248.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::a9f6:400:428:83d4/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@web2 system-connections]# cp eth0.nmconnection lo.nmconnection -p
[root@web2 system-connections]# vim lo.nmconnection
[connection]
id=lo
type=loopback
interface-name=lo
[ipv4]
method=manual
address1=127.0.0.1/8
address1=192.168.248.100/32
[root@web2 system-connections]# nmcli connection reload
[root@web2 system-connections]# nmcli connection up lo
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/5)
[root@web2 ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 127.0.0.1/24 brd 127.0.0.255 scope host lo
valid_lft forever preferred_lft forever
inet 192.168.248.100/32 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:ad:be:2c brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 192.168.248.20/24 brd 192.168.248.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::8e01:e3ed:e8db:424a/64 scope link noprefixroute
valid_lft forever preferred_lft forever
2.2.2 给webserver做ARP抑制配置
web 不做 ARP 抑制,它会对外广播我是 VIP,导致客户端流量直接打到 web ,绕过 keepalived ,破坏负载均衡逻辑
bash
[root@web1 ~]# vim /etc/sysctl.conf
[root@web1 ~]# sysctl -p
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
[root@web2 ~]# vim /etc/sysctl.conf
[root@web2 ~]# sysctl -p
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore=1 :对所有网口**,**对所有网口,仅响应目标 IP 是本网卡 IP 的 ARP 请求,拒绝响应针对 VIP绑在 lo的 ARP 查询,避免 RS 抢 VIP
net.ipv4.conf.all.arp_announce=2:对所有网口,仅宣告本网卡的主 IP,不宣告次级 / 别名 IP 不对外广播我有 VIP,只暴露真实物理网卡 IP
net.ipv4.conf.lo.arp_announce=2:对 lo 接口,限制 ARP 宣告,不把 lo 上的 VIP 广播出去
net.ipv4.conf.lo.arp_ignore=1:对 lo 接口,仅响应发给 lo 自身 IP 的 ARP 请求,进一步隔离 VIP 的 ARP 广播
2.3 开启基础的ipvs高可用
下载 ipvsadm 配置keepalived.conf 文件
bash
[root@KA1 ~]# dnf install ipvsadm-1.31-6.el9.x86_64 -y
17 vrrp_instance WEB_VIP {
18 state MASTER
19 interface eth0
20 virtual_router_id 51
21 priority 100
22 advert_int 1
23 authentication {
24 auth_type PASS
25 auth_pass 1111
26 }
27 virtual_ipaddress {
28 192.168.248.100/24 dev eth0 label eth0:0
29 }
30 }
33 virtual_server 192.168.248.100 80 {
34 delay_loop 6
35 lb_algo rr
36 lb_kind DR
37 protocol TCP
38
39 real_server 192.168.248.10 80 {
40 weight 1
41 HTTP_GET {
42 url {
43 path /
44 status_code 200
45 }
46 connect_timeout 1
47 retry 3
48 delay_before_retry 1
49 }
50 }
51 real_server 192.168.248.20 80 {
52 weight 1
53 TCP_CHECK {
54 connect_timeout 5
55 retry 3
56 delay_before_retry 3
57 connect_port 80
58 }
59 }
60 }
[root@KA1 ~]# systemctl restart keepalived.service
[root@KA2 ~]# vim /etc/keepalived/keepalived.conf
18 vrrp_instance WEB_VIP {
19 state BACKUP
20 interface eth0
21 virtual_router_id 51
22 priority 80
23 advert_int 1
24 authentication {
25 auth_type PASS
26 auth_pass 1111
27 }
28 virtual_ipaddress {
29 192.168.248.100 dev eth0 label eth0:0
30 }
31 }
32 virtual_server 192.168.248.100 80 {
33 delay_loop 6
34 lb_algo rr
35 lb_kind DR
36 protocol TCP
37
38 real_server 192.168.248.10 80 {
39 weight 1
40 HTTP_GET {
41 url {
42 path /
43 status_code 200
44 }
45 connect_timeout 1
46 retry 3
47 delay_before_retry 1
48 }
49 }
50
51 real_server 192.168.248.20 80 {
52 weight 1
53 TCP_CHECK {
54 connect_timeout 5
55 retry 3
56 delay_before_retry 3
57 connect_port 80
58 }
59 }
60 }
[root@KA2 ~]# systemctl restart keepalived.service
2.4 测试
查看策略是否自动生成
bash
[root@KA1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.198.100:80 rr
-> 192.168.248.10:80 Route 1 0 0
-> 192.168.248.20:80 Route 1 0 0
curl 192.168.248.100 查看是否实现均衡负载
bash
[2026-03-21 19:22.38] ~
[.LAPTOP-223ABRUC] ⮞ curl 192.168.248.100
RS1 - 192.168.248.10
✓
────────────────────────────────────────────────────────────────────────────────────────────────────
[2026-03-21 19:22.40] ~
[.LAPTOP-223ABRUC] ⮞ curl 192.168.248.100
RS2 - 192.168.248.20
✓
────────────────────────────────────────────────────────────────────────────────────────────────────
[2026-03-21 19:22.41] ~
[.LAPTOP-223ABRUC] ⮞ curl 192.168.248.100
RS1 - 192.168.248.10
✓
────────────────────────────────────────────────────────────────────────────────────────────────────
[2026-03-21 19:26.20] ~
[.LAPTOP-223ABRUC] ⮞ curl 192.168.248.100
RS2 - 192.168.248.20
监控ipvsadm 策略编写,关闭KA1 的keepalived 服务,查看策略变化
bash
[root@KA1 ~]# systemctl stop keepalived.service
[root@KA1 ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:6d:7f:2b brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 192.168.248.50/24 brd 192.168.248.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::7831:d38e:18e8:c266/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@KA1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@KA2 ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:f6:15:27 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 192.168.248.60/24 brd 192.168.248.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet 192.168.248.100/32 scope global eth0:0
valid_lft forever preferred_lft forever
inet6 fe80::3b5a:7484:2377:ed88/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@KA2 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.248.100:80 rr
-> 192.168.248.10:80 Route 1 0 0
-> 192.168.248.20:80 Route 1 0 0
测试 当vip 漂移到KA2 时是否还能实现均衡负载
bash
[2026-03-21 19:26.25] ~
[.LAPTOP-223ABRUC] ⮞ curl 192.168.248.100
RS1 - 192.168.248.10
✓
────────────────────────────────────────────────────────────────────────────────────────────────────
[2026-03-21 19:30.46] ~
[.LAPTOP-223ABRUC] ⮞ curl 192.168.248.100
RS2 - 192.168.248.20
✓
────────────────────────────────────────────────────────────────────────────────────────────────────
[2026-03-21 19:30.46] ~
[.LAPTOP-223ABRUC] ⮞ curl 192.168.248.100
RS1 - 192.168.248.10
✓
────────────────────────────────────────────────────────────────────────────────────────────────────
[2026-03-21 19:30.47] ~
[.LAPTOP-223ABRUC] ⮞ curl 192.168.248.100
RS2 - 192.168.248.20
三、双主模式代理不同业务实现高可用
3.1 简介:
Keepalived + LVS的进阶高可用方案: 两台节点同时对外提供服务,各自承载不同业务,同时互为备份,解决了主备模式下备机闲置的问题,资源利用率更高。
优势:
(1)资源利用率高:两台机器都在干活,避免备机空转
(2)业务隔离:不同业务用不同 VIP,故障影响范围小
(3)高可用更强:单节点故障不影响任何业务,自动漂移
(4)水平扩展:后续可加更多节点,扩展更多业务
3.2 双主模式代理http 服务和 mysql 服务
在web1 web2 上下载 数据库 maridb,做初始化配置
bash
[root@web1 ~]# dnf install mariadb-server -y
systemctl enable --now mariadb
[root@web1 ~]# systemctl enable --now mariadb
Created symlink /etc/systemd/system/mysql.service → /usr/lib/systemd/system/mariadb.se rvice.
Created symlink /etc/systemd/system/mysqld.service → /usr/lib/systemd/system/mariadb.s ervice.
Created symlink /etc/systemd/system/multi-user.target.wants/mariadb.service → /usr/lib /systemd/system/mariadb.service.
[root@web1 ~]# ^C
[root@web1 ~]# mysql
MariaDB [(none)]> CREATE USER bi@'%' identified by '123';
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]> GRANT ALL ON *.* TO bi@'%';
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]> exit
Bye
[root@web1 ~]# mysql -ubi -p123
MariaDB [(none)]>
[root@web2 ~]# dnf install mariadb-server -y^
[root@web2 ~]# systemctl enable --now mariadb
[root@web2 ~]# systemctl enable --now mariadb
Created symlink /etc/systemd/system/mysql.service → /usr/lib/systemd/system/mariadb.se rvice.
Created symlink /etc/systemd/system/mysqld.service → /usr/lib/systemd/system/mariadb.s ervice.
Created symlink /etc/systemd/system/multi-user.target.wants/mariadb.service → /usr/lib /systemd/system/mariadb.service.
[root@web2 ~]# mysql
MariaDB [(none)]> CREATE USER bi@'%' identified by '123';
Query OK, 0 rows affected (0.000 sec)
MariaDB [(none)]> GRANT ALL ON *.* TO bi@'%';
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]> exit
Bye
[root@web2 ~]# mysql -ubi -p123
MariaDB [(none)]>
配置KA1 和 KA2 的第二个主备服务
bash
[root@KA1 ~]# vim /etc/keepalived/keepalived.conf
32 vrrp_instance DB_VIP {
33 state BACKUP
34 interface eth0
35 virtual_router_id 52
36 priority 80
37 davert_int 1
38 authentication {
39 auth_type PASS
40 auth_pass 1111
41 }
42 virtual_ipaddress {
43 192.168.248.200/24 dev eth0 label eth0:1
44 }
45 }
77 virtual_server 192.168.248.200 3306 {
78 delay_loop 6
79 lb_algo rr
80 lb_kind DR
81 procotol TCP
82
83 real_server 192.168.248.10 3306 {
84 weight 1
85 HTTP_GET {
86 url {
87 path /
88 status_code 200
89 }
90 connect_timeout 1
91 retry 3
92 delay_before_retry 1
93 }
94 }
95 real_server 192.168.248.20 3306 {
96 weight 1
97 TCP_CKECK {
98 connect_timeout 5
99 retry 3
100 delay_before_retry 3
101 connect_port 3306
102 }
103 }
104 }
[root@KA1 ~]# systemctl restart keepalived.service
[root@KA1 ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:6d:7f:2b brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 192.168.248.50/24 brd 192.168.248.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet 192.168.248.100/24 scope global secondary eth0:0
valid_lft forever preferred_lft forever
inet6 fe80::7831:d38e:18e8:c266/64 scope link noprefixroute
valid_lft forever preferred_lft forever
bash
[root@KA2 [root@KA2 ~]# systemctl restart keepalived.service
34 vrrp_instance DB_VIP {
35 state MASTER
36 interface eth0
37 virtual_router_id 52
38 priority 100
39 advert_int 1
40 authentication {
41 auth_type PASS
42 auth_pass 1111
43 }
44 virtual_ipaddress {
45 192.168.248.200/24 dev eth0 label eth0:1
46 }
47 }
80 virtual_server 192.168.248.200 3306 {
81 delay_loop 6
82 lb_algo rr
83 lb_kind DR
84 protocol TCP
85
86 real_server 192.168.248.10 3306 {
87 weight 1
88 TCP_CHECK {
89 connect_timeout 5
90 retry 3
91 delay_before_retry 3
92 connect_port 3306
93 }
94 }
95
96 real_server 192.168.248.20 3306 {
97 weight 1
98 TCP_CHECK {
99 connect_timeout 5
100 retry 3
101 delay_before_retry 3
102 connect_port 3306
103 }
104 }
105 }
[root@KA2 ~]# systemctl restart keepalived.service
[root@KA2 ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:f6:15:27 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 192.168.248.60/24 brd 192.168.248.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet 192.168.248.200/24 scope global secondary eth0:1
valid_lft forever preferred_lft forever
inet6 fe80::3b5a:7484:2377:ed88/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3.3 测试
查看vip 挂载情况
bash
[root@KA1 ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 10
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen
link/ether 00:0c:29:6d:7f:2b brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 192.168.248.50/24 brd 192.168.248.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet 192.168.248.100/24 scope global secondary eth0:0
valid_lft forever preferred_lft forever
inet6 fe80::7831:d38e:18e8:c266/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@KA2 ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 10
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen
link/ether 00:0c:29:f6:15:27 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 192.168.248.60/24 brd 192.168.248.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet 192.168.248.200/24 scope global secondary eth0:1
valid_lft forever preferred_lft forever
inet6 fe80::3b5a:7484:2377:ed88/64 scope link noprefixroute
valid_lft forever preferred_lft forever
测试httpd 服务均衡负载情况

测试mysql 服务负载均衡情况(我在主机上登录了四次192.168.248.100的mysql服务)


关闭web1 mysql 服务 再链接 192.168.248.100 mysql服务三次

