一、理论
lvs不具备健康检测功能,无法及时移除群集中的故障机,结合keepalived即可实现此功能。
keepalived采用vrrp(virtual router rendundancy protocol,虚拟路由冗余协议)热备份协议,以软件的方式实现linux服务器的多机热备功能。
vrrp是多台路由器组成一个热备组,通过共用的虚拟ip地址对外提供服务,每个热备组同一时刻只有一台主路由器提供服务,其他路由器处于冗余状态。当主路由器失效时,其他路由器会按优先级大小自动接替,优先级大的成为主,接替虚拟ip地址以继续提供服务。
vip也称为飘逸ip,因为该ip不固定在一台设备上。
当vip发生切换,从主机1切换到主机2.原vip、虚拟mac与交换机接口的对应信息已经被记录到mac地址表中。如果重新获取当前vip拥有者与交换机连接的接口,耗费时间,也会导致服务中断。这怎么办呢?当vip从主机1切换到主机2时,主机2会向下游设备(交换机)发送免费arp,只有arp应答,告诉交换机自己的vip以及vmac,来更新mac地址表中vip对应的接口。这样,通信就不会中断了。
注:客户机通过arp广播来请求vip,vmac返回时,交换机会将vip、vmac以及对应的接口记录到地址表中
注:例如vip是192.168.1.1 vmac是01(简写) VIP被主机1拥有.主机1与交换机相连的接口是e0/1。
mac地址表会记录
192.168.1.1 01 e0/1
而当主机1故障,主机2拥用vip,mac地址表还记录的是主机1的信息。主机2上任的时候就会向交换机发送免费arp来更新vip vmac对应的接口。
mac地址表记录变为
192.168.1.1 01 e0/2
二、实践
bash
1、网络拓扑
lk01
192.168.10.101
lk02
192.168.10.102
web01
192.168.10.103
web02
192.168.10.104
client
192.168.10.105
2、过程
[root@lk01 ~]# dnf -y install keepalived ipvsadm
[root@lk01 ~]# modprobe ip_vs
[root@lk01 ~]# cat /proc/net/ip_vs
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@lk01 ~]# cd /etc/keepalived/
[root@lk01 keepalived]# cp keepalived.conf.sample keepalived.conf
[root@lk01 keepalived]# ls
keepalived.conf keepalived.conf.sample
[root@lk01 keepalived]# cat keepalived.conf
global_defs {
router_id LVS_HA_R1 # 主调度器的名称
}
vrrp_instance VI_1 {
state MASTER # 主调度器的热备状态
interface ens160 # 当前ip对应的网络接口,通过ip add查看。
virtual_router_id 1 # 虚拟路由id(0-255),在一个vrrp实例中主备服务器id必须一样。
priority 100 # 主调度器的优先级,要比备用的大。
advert_int 1 # 通告时间间隔,单位秒,主备要一致。
authentication { # 主、从热备认证信息
auth_type PASS
auth_pass 1234567
}
virtual_ipaddress { # 指定群集VIP地址
192.168.10.100
}
}
virtual_server 192.168.10.100 80 { # 虚拟服务器地址(vip)、端口
delay_loop 15 # 健康检查的间隔时间(秒)
lb_algo rr # 轮询(rr)调度算法
lb_kind DR # 直接路由(DR)群集工作模式
! persistence_timeout 50 # 连接保持时间(秒),需启用去叹号。
protocol TCP # 应用服务采用tcp协议。
real_server 192.168.10.103 80 { # 第一个web节点的地址、端口
weight 1 # 节点的权重。
TCP_CHECK { # 健康检查方式。
connect_port 80 # 检查的目标端口。
connect_timeout 3 # 连接超时(秒)
nb_get_retry 3 # 重试次数
delay_before_retry 4 # 重试间隔(秒)
}
}
real_server 192.168.10.104 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 3
nb_get_retry 3
delay_before_retry 4
}
}
}
[root@lk01 keepalived]# systemctl start keepalived
[root@lk02 ~]# dnf -y install keepalived ipvsadm
[root@lk02 ~]# scp [email protected]:/etc/keepalived/keepalived.conf /etc/keepalived/
Authorized users only. All activities may be monitored and reported.
[email protected]'s password:
keepalived.conf 100% 826 297.1KB/s 00:00
[root@lk02 keepalived]# cat keepalived.conf
global_defs {
router_id LVS_HA_R1
}
vrrp_instance VI_1 {
state BACKUP
interface ens160
virtual_router_id 1
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1234567
}
virtual_ipaddress {
192.168.10.100
}
}
virtual_server 192.168.10.100 80 {
delay_loop 15
lb_algo rr
lb_kind DR
! persistence_timeout 50
protocol TCP
real_server 192.168.10.103 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 3
nb_get_retry 3
delay_before_retry 4
}
}
real_server 192.168.10.104 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 3
nb_get_retry 3
delay_before_retry 4
}
}
}
[root@lk02 keepalived]# systemctl start keepalived
[root@web01 ~]# dnf -y install httpd
[root@web01 ~]# cat /var/www/html/index.html
web01
[root@web01 ~]# systemctl start httpd
[root@web01 ~]# ip addr add 192.168.10.100/32 dev lo label lo:0
[root@web01 ~]# ip route add local 192.168.10.100/32 dev lo
RTNETLINK answers: File exists
[root@web01 ~]# vim /etc/sysctl
[root@web01 ~]# vim /etc/sysctl.conf
[root@web01 ~]# sysctl -p
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
[root@web02 ~]# dnf -y install httpd
[root@web02 ~]# cat /var/www/html/index.html
web02
[root@web02 ~]# systemctl start httpd
[root@web02 ~]# ip addr add 192.168.10.100/32 dev lo label lo:0
[root@web02 ~]# ip route add local 192.168.10.100/32 dev lo
RTNETLINK answers: File exists
[root@web02 ~]# vim /etc/sysctl
[root@web02 ~]# vim /etc/sysctl.conf
[root@web02 ~]# sysctl -p
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
[root@client ~]# curl 192.168.10.100
web01
[root@client ~]# curl 192.168.10.100
web02
[root@client ~]# curl 192.168.10.100
web01
[root@client ~]# curl 192.168.10.100
web02
[root@client ~]# curl 192.168.10.100
web01
[root@client ~]# curl 192.168.10.100
web02
[root@client ~]# curl 192.168.10.100
web01
[root@client ~]# curl 192.168.10.100
web02
[root@lk01 ~]# ip a
inet 192.168.10.100/32 scope global ens160
[root@lk01 ~]# 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.10.100:80 rr
-> 192.168.10.103:80 Route 1 0 0
-> 192.168.10.104:80 Route 1 0 0
[root@lk01 ~]# ipvsadm -lnc
IPVS connection entries
pro expire state source virtual destination
TCP 01:56 FIN_WAIT 192.168.10.105:59254 192.168.10.100:80 192.168.10.103:80
TCP 01:55 FIN_WAIT 192.168.10.105:59236 192.168.10.100:80 192.168.10.103:80
TCP 01:57 FIN_WAIT 192.168.10.105:59270 192.168.10.100:80 192.168.10.104:80
TCP 01:55 FIN_WAIT 192.168.10.105:59250 192.168.10.100:80 192.168.10.104:80
[root@lk02 ~]# ip a
inet 192.168.10.102/24 scope global ens160
[root@lk01 ~]# 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.10.100:80 rr
-> 192.168.10.103:80 Route 1 0 0
-> 192.168.10.104:80 Route 1 0 0
[root@lk01 ~]# ipvsadm -lnc
IPVS connection entries
pro expire state source virtual destination
[root@lk01 ~]# systemctl stop keepalived
[root@lk02 ~]# ip a
inet 192.168.10.100/32 scope global ens160
[root@client ~]# curl 192.168.10.100
web01
[root@client ~]# curl 192.168.10.100
web02
[root@client ~]# curl 192.168.10.100
web01
[root@client ~]# curl 192.168.10.100
web02
[root@lk01 ~]# 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.10.100:80 rr
-> 192.168.10.103:80 Route 1 0 0
-> 192.168.10.104:80 Route 1 0 0
[root@lk01 ~]# ipvsadm -lnc
IPVS connection entries
pro expire state source virtual destination
TCP 01:56 FIN_WAIT 192.168.10.105:59254 192.168.10.100:80 192.168.10.103:80
TCP 01:55 FIN_WAIT 192.168.10.105:59236 192.168.10.100:80 192.168.10.103:80
TCP 01:57 FIN_WAIT 192.168.10.105:59270 192.168.10.100:80 192.168.10.104:80
TCP 01:55 FIN_WAIT 192.168.10.105:59250 192.168.10.100:80 192.168.10.104:80