3.4双主架构
说明:
每一个vrrp只有一个主,但是可以在两台服务器上配置多个vrrp,每一台服务器是某一个虚拟ip的主设备
master/slave的单主架构,同一时间只有一个Keepalived对外提供服务,此主机繁忙,而另一台主机却很空闲,利用率低下,可以使用master/master的双主架构,解决此问题。
master/master 的双主架构:
即将两个或以上VIP分别运行在不同的keepalived服务器,以实现服务器并行提供web访问的目的,提高服务器资源利用率
##ka1主机配置
#针对于vrid55的vrrp配置
[root@ka1 /etc/keepalived/conf.d]#cat master.conf
vrrp_instance test1 { #添加 test1 实例
state MASTER #在另一个主机上为BACKUP
interface ens33 #网卡
virtual_router_id 55 #每个vrrp_instance唯一
priority 100 #在另一个主机上为80(只要比100小就行)
advert_int 1
preempt_delay 5
authentication {
auth_type PASS
auth_pass sunxiang
}
virtual_ipaddress {
10.0.0.15 dev ens33 laber ens33:0 #指定vrrp_instance各自的VIP
}
}
#针对于vrid66的vrrp配置
[root@ka1 /etc/keepalived/conf.d]#cat backup.conf
vrrp_instance test2 {
state BACKUP
interface ens33
virtual_router_id 66 #每个vrrp_instance唯一
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass sunxiang
}
virtual_ipaddress {
10.0.0.25 dev ens33 laber ens33:1 #指定vrrp_instance各自的VIP
}
}
##ka2主机配置
#针对于vrid55的vrrp配置
[root@ka2 /etc/keepalived/conf.d]#cat backup.conf
vrrp_instance test1 {
state BACKUP
interface ens33
virtual_router_id 55
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass sunxiang
}
virtual_ipaddress {
10.0.0.15 dev ens33 laber ens33:0
}
}
#针对于vrid66的vrrp配置
[root@ka2 /etc/keepalived/conf.d]#cat master.conf
vrrp_instance test2 {
state MASTER
interface ens33
virtual_router_id 66
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass sunxiang
}
virtual_ipaddress {
10.0.0.25 dev ens33 laber ens33:1
}
}
#重启服务
[root@ka1 /etc/keepalived/conf.d]#systemctl restart keepalived.service
[root@ka2 /etc/keepalived/conf.d]#systemctl restart keepalived.service
#查看虚拟ip信息
[root@ka1 /etc/keepalived/conf.d]#ip a
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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:95:b7:a2 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.11/24 brd 10.0.0.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 10.0.0.15/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe95:b7a2/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@ka2 /etc/keepalived/conf.d]#ip a
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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:ff:33:b2 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.21/24 brd 10.0.0.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 10.0.0.25/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feff:33b2/64 scope link noprefixroute
valid_lft forever preferred_lft forever
#抓包 vrid66主设备为10.0.0.21,vrid55主设备为10.0.0.11。都会向对方发送组播报文
[root@centos7blog ~]# tcpdump -i ens33 -nn host 224.0.0.18
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
18:29:27.488548 IP 10.0.0.21 > 224.0.0.18: VRRPv2, Advertisement, vrid 66, prio 100, authtype simple, intvl 1s, length 20
18:29:27.566569 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 55, prio 100, authtype simple, intvl 1s, length 20
18:29:28.489312 IP 10.0.0.21 > 224.0.0.18: VRRPv2, Advertisement, vrid 66, prio 100, authtype simple, intvl 1s, length 20
18:29:28.570515 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 55, prio 100, authtype simple, intvl 1s, length 20
18:29:29.491238 IP 10.0.0.21 > 224.0.0.18: VRRPv2, Advertisement, vrid 66, prio 100, authtype simple, intvl 1s, length 20
18:29:29.573328 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 55, prio 100, authtype simple, intvl 1s, length 20
18:29:30.493232 IP 10.0.0.21 > 224.0.0.18: VRRPv2, Advertisement, vrid 66, prio 100, authtype simple, intvl 1s, length 20
18:29:30.574217 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 55, prio 100, authtype simple, intvl 1s, length 20
#模拟故障,在ka2上停服务
#抓包 在停服务之前都是互为主备,当服务停止之后vrid55和66的主设备都是10.0.0.11,都是10.0.0.11发送组播
[root@centos7blog ~]# tcpdump -i ens33 -nn host 224.0.0.18
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
18:37:28.562324 IP 10.0.0.21 > 224.0.0.18: VRRPv2, Advertisement, vrid 66, prio 100, authtype simple, intvl 1s, length 20
18:37:28.676421 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 55, prio 100, authtype simple, intvl 1s, length 20
18:37:29.563015 IP 10.0.0.21 > 224.0.0.18: VRRPv2, Advertisement, vrid 66, prio 100, authtype simple, intvl 1s, length 20
18:37:29.679107 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 55, prio 100, authtype simple, intvl 1s, length 20
18:37:30.080837 IP 10.0.0.21 > 224.0.0.18: VRRPv2, Advertisement, vrid 66, prio 0, authtype simple, intvl 1s, length 20
18:37:30.681044 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 55, prio 100, authtype simple, intvl 1s, length 20
18:37:30.772663 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 66, prio 80, authtype simple, intvl 1s, length 20
18:37:31.683951 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 55, prio 100, authtype simple, intvl 1s, length 20
18:37:31.776033 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 66, prio 80, authtype simple, intvl 1s, length 20
3.5脑裂(需要避免)
生成中出现一个虚拟地址在多台设备上都有的情况,比如说心跳线故障,就会导致脑裂。
#正常情况下访问10.0.0.25应该是ka2进行回应
[root@centos7blog ~]# arping 10.0.0.25
ARPING 10.0.0.25 from 10.0.0.40 ens33
Unicast reply from 10.0.0.25 [00:0C:29:FF:33:B2] 0.849ms
Unicast reply from 10.0.0.25 [00:0C:29:FF:33:B2] 1.029ms
Unicast reply from 10.0.0.25 [00:0C:29:FF:33:B2] 1.000ms
Unicast reply from 10.0.0.25 [00:0C:29:FF:33:B2] 1.464ms
^CSent 4 probes (1 broadcast(s))
Received 4 response(s)
[root@ka2 ~]#ip a
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:ff:33:b2 #确实是ka2的mac地址
#我这里没有心跳线就直接用防火墙禁止ka2上发过来的消息
[root@ka1 ~]#iptables -AINPUT -s 10.0.0.21 -j DROP
#通过arping进行ping发现有ka1的应答也有ka2的应答,这就是脑裂
root@ubuntu1804:~# arping 10.0.0.25
ARPING 10.0.0.25
60 bytes from 00:0c:29:95:b7:a2 (10.0.0.25): index=0 time=4.500 usec
60 bytes from 00:0c:29:ff:33:b2 (10.0.0.25): index=1 time=32.781 usec
60 bytes from 00:0c:29:ff:33:b2 (10.0.0.25): index=2 time=134.991 usec
60 bytes from 00:0c:29:95:b7:a2 (10.0.0.25): index=3 time=172.941 usec
60 bytes from 00:0c:29:95:b7:a2 (10.0.0.25): index=4 time=273.242 usec
60 bytes from 00:0c:29:ff:33:b2 (10.0.0.25): index=5 time=334.562 usec
60 bytes from 00:0c:29:ff:33:b2 (10.0.0.25): index=6 time=237.685 usec
60 bytes from 00:0c:29:95:b7:a2 (10.0.0.25): index=7 time=287.485 usec
#看一下ka1和ka2的ip信息。发现两台设备上都有10.0.0.25这个地址
[root@ka1 ~]#hostname -I
10.0.0.11 10.0.0.15 10.0.0.25
[root@ka2 ~]#hostname -I
10.0.0.21 10.0.0.25
这个我上一份工作中还真就出现过,一个同事配置iptables的时候直接没注意结果学校的同学反映某个网站卡顿,当时以为是宿舍网的问题都没重视,过了三四天反映的人多起来了,排查一下才发现的。后来我是准备通过arping进行一个监控,发现频繁的抖动就直接停一台设备的服务,给学校的领导反映了一下,但是学校有钱准备直接买设备监控,我就没弄了。正好那会也要离职了没机会玩一下可惜了
3.6实现IPVS的高可用性(LVS+Keepalive)
3.6.1 IPVS相关配置
3.6.1.1 虚拟服务器配置结构
virtual_server IP port {
...
real_server {
...
}
real_server {
...
}
…
}
3.6.1.2 virtual server (虚拟服务器)的定义格式
virtual_server IP port #定义虚拟主机IP地址及其端口
virtual_server fwmark int #ipvs的防火墙打标,实现基于防火墙的负载均衡集群
virtual_server group string #使用虚拟服务器组
3.6.1.3 虚拟服务器组
将多个虚拟服务器定义成一个组,统一对外服务,如:http和https定义成一个虚拟服务器组
#参考文档:/usr/share/doc/keepalived/keepalived.conf.virtual_server_group
virtual_server_group <STRING> {
# Virtual IP Address and Port
<IPADDR> <PORT>
<IPADDR> <PORT>
...
# <IPADDR RANGE> has the form
# XXX.YYY.ZZZ.WWW-VVV eg 192.168.200.1-10
# range includes both .1 and .10 address
<IPADDR RANGE> <PORT># VIP range VPORT
<IPADDR RANGE> <PORT>
...
# Firewall Mark (fwmark)
fwmark <INTEGER>
fwmark <INTEGER>
...
}
3.6.1.4 虚拟服务器配置
virtual_server IP port { #VIP和PORT
delay_loop <INT> #检查后端服务器的时间间隔
lb_algo rr|wrr|lc|wlc|lblc|sh|dh #定义调度方法
lb_kind NAT|DR|TUN #集群的类型,注意要大写
persistence_timeout <INT> #持久连接时长
protocol TCP|UDP|SCTP #指定服务协议,一般为TCP
sorry_server <IPADDR> <PORT> #所有RS故障时,备用服务器地址
real_server <IPADDR> <PORT> { #RS的IP和PORT
weight <INT> #RS权重
notify_up <STRING>|<QUOTED-STRING> #RS上线通知脚本
notify_down <STRING>|<QUOTED-STRING> #RS下线通知脚本
HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK { ... } #定义当前主机健康状态检测方法
}
}
#注意:括号必须分行写,两个括号写在一行,如: }} 会出错
3.6.1.5 应用层监测
应用层检测:HTTP_GET|SSL_GET
HTTP_GET|SSL_GET {
url {
path <URL_PATH> #定义要监控的URL
status_code <INT> #判断上述检测机制为健康状态的响应码,一般为 200
}
connect_timeout <INTEGER> #客户端请求的超时时长, 相当于haproxy的timeout server
nb_get_retry <INT> #重试次数
delay_before_retry <INT> #重试之前的延迟时长
connect_ip <IP ADDRESS> #向当前RS哪个IP地址发起健康状态检测请求
connect_port <PORT> #向当前RS的哪个PORT发起健康状态检测请求
bindto <IP ADDRESS> #向当前RS发出健康状态检测请求时使用的源地址
bind_port <PORT> #向当前RS发出健康状态检测请求时使用的源端口
}
3.6.1.6 TCP监测
传输层检测:TCP_CHECK
TCP_CHECK {
connect_ip <IP ADDRESS> #向当前RS的哪个IP地址发起健康状态检测请求
connect_port <PORT> #向当前RS的哪个PORT发起健康状态检测请求
bindto <IP ADDRESS> #发出健康状态检测请求时使用的源地址
bind_port <PORT> #发出健康状态检测请求时使用的源端口
connect_timeout <INTEGER> #客户端请求的超时时长, 等于haproxy的timeout server
}
3.6.2实战案例
3.6.2.1 实战案例1:实现单主的 LVS-DR 模式
3.6.2.1.1配置后端RS主机(两台操作一样)
#安装nginx
[root@web1 ~]# yum install -y nginx
[root@web1 ~]# systemctl enable --now nginx.service
#用脚本绑定VIP至web服务器lo网卡
[root@web1 ~]# bash lvs_dr_rs.sh start
The RS Server is Ready!
[root@web1 ~]# ip a
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 10.0.0.15/32 scope global lo:1
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
#脚本内容
[root@web1 ~]# cat lvs_dr_rs.sh
#!/bin/bash
#Author:sunxiang
#Date:2021-10-22
vip=10.0.0.15
mask='255.255.255.255'
dev=lo:1
case $1 in
start)
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
ifconfig $dev $vip netmask $mask #broadcast $vip up
echo "The RS Server is Ready!"
;;
stop)
ifconfig $dev down
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "The RS Server is Canceled!"
;;
*)
echo "Usage: $(basename $0) start|stop"
exit 1
;;
esac
#修改一下nginx默认页面便于区分
[root@web1 ~]# echo `hostname -I` > /usr/share/nginx/html/index.html
3.6.2.1.2访问测试
root@ubuntu1804:~# curl 10.0.0.20
10.0.0.20
root@ubuntu1804:~# curl 10.0.0.30
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
curl: (7) Failed to connect to 10.0.0.15 port 80: Connection refused
3.6.2.1.3配置keepalive
##ka1
#全局配置
[root@ka1 /etc/keepalived/conf.d]#cat ../keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
448803503@qq.com
}
notification_email_from 448803503@qq.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id ka1 #设备标识
vrrp_skip_check_adv_addr
#vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
include /etc/keepalived/conf.d/*.conf
#vrrp配置
[root@ka1 /etc/keepalived/conf.d]#cat master.conf
vrrp_instance test1 {
state MASTER
interface ens33 #网卡
virtual_router_id 55 #vid全局唯一
priority 100 #主设备优先级比备设备高即可
advert_int 1
preempt_delay 5
authentication {
auth_type PASS
auth_pass sunxiang
}
virtual_ipaddress {
10.0.0.15 dev ens33 laber ens33:0 #vip
}
}
#virtual_server配置
[root@ka1 /etc/keepalived/conf.d]#cat lvs.conf
virtual_server 10.0.0.15 80 {
delay_loop 3
lb_algo rr #调度方式
lb_kind DR #集群的类型,注意要大写
protocol TCP
sorry_server 127.0.0.1 80 #后端服务器出现故障时候备用的服务器
real_server 10.0.0.20 80 { #后端服务器
weight 1
HTTP_GET {
url { #通过url进行监控检查(如果不能返回状态吗200则认为故障)
path /
status_code 200
}
connect_timeout 1
nb_get_retry 3
delay_before_retry 1
}
}
real_server 10.0.0.30 80 {
weight 1
TCP_CHECK { #通过tcp协议监控如果不能连接端口80则认为故障
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connetc_port 80
}
}
}
##ka2与ka1大同小异
#全局配置
[root@ka2 /etc/keepalived/conf.d]#cat ../keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
448803503@qq.com
}
notification_email_from 448803503@qq.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id ka2 #设备标识
vrrp_skip_check_adv_addr
#vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
include /etc/keepalived/conf.d/*.conf
#vrrp配置
[root@ka2 /etc/keepalived/conf.d]#cat backup.conf
vrrp_instance test1 {
state BACKUP #改成BACKUP
interface ens33
virtual_router_id 55
priority 80 #修改为小于主设备的优先级
advert_int 1
authentication {
auth_type PASS
auth_pass sunxiang
}
virtual_ipaddress {
10.0.0.15 dev ens33 laber ens33:0
}
}
#virtual_server配置
[root@ka2 /etc/keepalived/conf.d]#cat lvs.conf
virtual_server 10.0.0.15 80 {
delay_loop 3
lb_algo rr
lb_kind DR
protocol TCP
sorry_server 127.0.0.1 80
real_server 10.0.0.20 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
nb_get_retry 3
delay_before_retry 1
}
}
real_server 10.0.0.30 80 {
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connetc_port 80
}
}
}
#重启服务
[root@ka1 /etc/keepalived/conf.d]#systemctl restart keepalived.service
[root@ka2 /etc/keepalived/conf.d]#systemctl restart keepalived.service
3.6.2.1.4访问测试
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.20
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.20
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.20
[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 10.0.0.15:80 rr
-> 10.0.0.20:80 Route 1 0 3
-> 10.0.0.30:80 Route 1 0 3
3.6.2.1.5模拟故障
针对url检查,我们使其检查的页面是一个不存在的网页
[root@ka1 /etc/keepalived/conf.d]#vim lvs.conf
virtual_server 10.0.0.15 80 {
delay_loop 3
lb_algo rr
lb_kind DR
protocol TCP
sorry_server 127.0.0.1 80
real_server 10.0.0.20 80 {
weight 1
HTTP_GET {
url {
path /bucunzai #一个不存在的url
status_code 200
}
connect_timeout 1
nb_get_retry 3
delay_before_retry 1
}
}
real_server 10.0.0.30 80 {
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connetc_port 80
}
}
}
#重启服务
[root@ka1 /etc/keepalived/conf.d]#systemctl restart keepalived.service
#查看一下lvs的信息,只有一个后端服务器了
[root@ka1 /etc/keepalived/conf.d]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.0.0.15:80 rr
-> 10.0.0.30:80 Route 1 0 7
#访问测试,只有一台服务器响应
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
#当故障恢复后(改为存在的url),后端rs服务器又恢复正常
[root@ka1 /etc/keepalived/conf.d]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.0.0.15:80 rr
-> 10.0.0.20:80 Route 1 0 0
-> 10.0.0.30:80 Route 1 0 0
3.6.2.2 实战案例2:实现双主的 LVS-DR 模式
vip 10.0.0.15 Nginx 10.0.0.11为主 10.0.0.21为备
vip 10.0.0.25 Mysql 10.0.0.11为备 10.0.0.21为主
3.6.2.2.1配置后端RS服务器(两台服务器一样)
##正常生产中都是不同的服务器运行不同的服务,我这里就直接一个服务器上跑多个服务了
#先停脚本
[root@web1 ~]# bash lvs_dr_rs.sh stop
The RS Server is Canceled!
#修改一下脚本
[root@web1 ~]# cat lvs_dr_rs.sh
#!/bin/bash
#Author:sunxiang
#Date:2021-10-22
vip=10.0.0.15
vip2=10.0.0.25
mask='255.255.255.255'
dev=lo:1
dev2=lo:2
case $1 in
start)
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
ifconfig $dev $vip netmask $mask #broadcast $vip up
ifconfig $dev2 $vip2 netmask $mask #broadcast $vip2 up
echo "The RS Server is Ready!"
;;
stop)
ifconfig $dev down
ifconfig $dev2 down
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "The RS Server is Canceled!"
;;
*)
echo "Usage: $(basename $0) start|stop"
exit 1
;;
esac
#运行脚本
[root@web1 ~]# bash lvs_dr_rs.sh start
The RS Server is Ready!
#查看ip信息
[root@web1 ~]# ip a
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 10.0.0.15/32 scope global lo:1
valid_lft forever preferred_lft forever
inet 10.0.0.25/32 scope global lo:2
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
#安装服务
#Nginx之前已经安装了,再装一个MySQL,直接跑脚本了,mysql章节有写这个脚本自己去看吧
[root@web1 mysql]# . mysql_5.7_8.0_Online.sh
#配置mysql
#获取初始化密码
[root@web1 ~]# grep password /data/mysql/mysql.log
2021-12-29T08:11:05.705363Z 1 [Note] A temporary password is generated for root@localhost: nwes(3dJeV.Q
#修改初始化密码
[root@web1 ~]# mysql -uroot -p'nwes(3dJeV.Q'
mysql> alter user root@'localhost' identified by 'sunxiang';
Query OK, 0 rows affected (0.00 sec)
#创建用于测试的账号
mysql> create user test@'10.0.0.%' identified by 'sunxiang';
Query OK, 0 rows affected (0.00 sec)
#为测试账号授权
mysql> grant all on *.* to test@'10.0.0.%';
Query OK, 0 rows affected (0.00 sec)
3.6.2.2.2配置keepalive
在实例一的基础上增加一个vrrp配置和virtual_server配置
##ka1
#vrrp配置
[root@ka1 /etc/keepalived/conf.d]#cat backup.conf
vrrp_instance test2 {
state BACKUP
interface ens33
virtual_router_id 66
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass sunxiang
}
virtual_ipaddress {
10.0.0.25 dev ens33 laber ens33:1
}
}
#virtual_server配置 与Nginx的区别在于端口号和健康检查方式,mysql只能通过tcp来进行监控了
[root@ka1 /etc/keepalived/conf.d]#cat mysql.conf
virtual_server 10.0.0.25 3306 {
delay_loop 3
lb_algo rr
lb_kind DR
protocol TCP
sorry_server 127.0.0.1 80
real_server 10.0.0.20 3306 {
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connetc_port 3306
}
}
real_server 10.0.0.30 3306 {
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connetc_port 3306
}
}
}
##ka2
#vrrp配置
[root@ka2 /etc/keepalived/conf.d]#cat master.conf
vrrp_instance test2 {
state MASTER
interface ens33
virtual_router_id 66
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass sunxiang
}
virtual_ipaddress {
10.0.0.25 dev ens33 laber ens33:1
}
}
#virtual_server配置
[root@ka2 /etc/keepalived/conf.d]#cat mysql.conf
virtual_server 10.0.0.25 3306 {
delay_loop 3
lb_algo rr
lb_kind DR
protocol TCP
sorry_server 127.0.0.1 80
real_server 10.0.0.20 3306 {
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connetc_port 3306
}
}
real_server 10.0.0.30 3306 {
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connetc_port 3306
}
}
}
#重启服务
[root@ka1 /etc/keepalived/conf.d]#systemctl restart keepalived.service
[root@ka2 /etc/keepalived/conf.d]#systemctl restart keepalived.service
3.6.2.2.3访问测试
#查看一下vip的绑定情况,一台服务器上有一个keepalive没啥问题
[root@ka1 /etc/keepalived/conf.d]#ip addr show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:95:b7:a2 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.11/24 brd 10.0.0.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 10.0.0.15/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe95:b7a2/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@ka2 /etc/keepalived/conf.d]#ip addr show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:ff:33:b2 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.21/24 brd 10.0.0.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 10.0.0.25/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feff:33b2/64 scope link noprefixroute
valid_lft forever preferred_lft forever
#访问mysql 正常进行轮询
root@ubuntu1804:~# mysql -utest -psunxiang -h10.0.0.25 -e 'select @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| web1 |
+------------+
root@ubuntu1804:~# mysql -utest -psunxiang -h10.0.0.25 -e 'select @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| web2 |
+------------+
root@ubuntu1804:~# mysql -utest -psunxiang -h10.0.0.25 -e 'select @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| web1 |
+------------+
#访问nginx 正常进行轮询
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.20
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.20
3.6.2.2.4模拟故障
#模拟后端RS服务器故障
#web2直接关机
[root@web2 mysql]# poweroff
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.20
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.20
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.20
root@ubuntu1804:~# mysql -utest -psunxiang -h10.0.0.25 -e 'select @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| web1 |
+------------+
root@ubuntu1804:~# mysql -utest -psunxiang -h10.0.0.25 -e 'select @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| web1 |
+------------+
root@ubuntu1804:~# mysql -utest -psunxiang -h10.0.0.25 -e 'select @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| web1 |
+------------+
#故障恢复
#重启服务器,运行lvs脚本
[root@web2 ~]# bash lvs_dr_rs.sh start
The RS Server is Ready!
#恢复正常
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.20
root@ubuntu1804:~# mysql -utest -psunxiang -h10.0.0.25 -e 'select @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| web2 |
+------------+
root@ubuntu1804:~# mysql -utest -psunxiang -h10.0.0.25 -e 'select @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| web1 |
+------------+
##模拟keepalive服务器故障
#在ka2上停服务
[root@ka2 /etc/keepalived/conf.d]#systemctl stop keepalived.service
#连接测试依旧是正常的轮询
root@ubuntu1804:~# mysql -utest -psunxiang -h10.0.0.25 -e 'select @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| web1 |
+------------+
root@ubuntu1804:~# mysql -utest -psunxiang -h10.0.0.25 -e 'select @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| web2 |
+------------+
root@ubuntu1804:~# mysql -utest -psunxiang -h10.0.0.25 -e 'select @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| web1 |
+------------+
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.20
#抓包 都是从10.0.0.11发的组播报文
[root@centos7blog ~]# tcpdump -i ens33 -nn host 224.0.0.18
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
02:36:27.381322 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 55, prio 100, authtype simple, intvl 1s, length 20
02:36:27.449187 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 66, prio 80, authtype simple, intvl 1s, length 20
02:36:28.382133 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 55, prio 100, authtype simple, intvl 1s, length 20
02:36:28.450149 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 66, prio 80, authtype simple, intvl 1s, length 20
02:36:29.384165 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 55, prio 100, authtype simple, intvl 1s, length 20
02:36:29.451119 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 66, prio 80, authtype simple, intvl 1s, length 20
02:36:30.385787 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 55, prio 100, authtype simple, intvl 1s, length 20
02:36:30.453772 IP 10.0.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 66, prio 80, authtype simple, intvl 1s, length 20
^C
8 packets captured
8 packets received by filter
0 packets dropped by kernel
3.6.2.3 实战案例3:实现单主的 LVS-DR 模式,利用FWM绑定成多个服务为一个集群服务
参考文档: 注意有bug
/usr/share/doc/keepalived/keepalived.conf.fwmark
3.6.2.3.1打标签
[root@ka1 ~]#iptables -t mangle -A PREROUTING -d 10.0.0.15 -p tcp -m multiport --dports 80,3306 -j MARK --set-mark 6
[root@ka2 ~]#iptables -t mangle -A PREROUTING -d 10.0.0.15 -p tcp -m multiport --dports 80,3306 -j MARK --set-mark 6
3.6.2.3.2配置keepalive
#修改virtual_server的配置,将上面两个实验创建virtual_server的conf文件修改后缀为bak
#创建一个新的调用组的virtual_server的conf文件
[root@ka1 /etc/keepalived/conf.d]#cat fwm.conf
virtual_server fwmark 6 { #指定FWM为6
delay_loop 3
lb_algo rr
lb_kind DR
protocol TCP
sorry_server 127.0.0.1 80
real_server 10.0.0.20 80 { #注意端口必须指定(官方文档上没有指定端口,会报错,随意指定组成员的任意一个端口即可)
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
nb_get_retry 3
delay_before_retry 1
}
}
real_server 10.0.0.30 80 { #注意端口必须指定
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connetc_port 80
}
}
}
[root@ka2 /etc/keepalived/conf.d]#cat fwm.conf
virtual_server fwmark 6 { #指定FWM为6
delay_loop 3
lb_algo rr
lb_kind DR
protocol TCP
sorry_server 127.0.0.1 80
real_server 10.0.0.20 80 { #注意端口必须指定(官方文档上没有指定端口,会报错,随意指定组成员的任意一个端口即可)
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 1
nb_get_retry 3
delay_before_retry 1
}
}
real_server 10.0.0.30 80 { #注意端口必须指定
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connetc_port 80
}
}
}
#重启服务
[root@ka1 /etc/keepalived/conf.d]#systemctl restart keepalived.service
[root@ka2 /etc/keepalived/conf.d]#systemctl restart keepalived.service
3.6.2.3.3访问测试
#都是进行正常的轮询,与之前不同的地方在于此时一个虚拟ip对应多个服务
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.20
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.30
root@ubuntu1804:~# curl 10.0.0.15
10.0.0.20
root@ubuntu1804:~# mysql -utest -psunxiang -h10.0.0.15 -e 'select @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| web2 |
+------------+
root@ubuntu1804:~# mysql -utest -psunxiang -h10.0.0.15 -e 'select @@hostname'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------+
| @@hostname |
+------------+
| web1 |
+------------+