keepalived
高可用集群概念
- 集群类型:
-
LB(Load Balance)
- lvs/HAProxy/nginx(http/upstream, stream/upstream)
- (负载均衡类型高可用集群,就是对某些负载均衡器做高可用,常见的就是lvs/HAProxy/nginx这些服务本身不提供高可用,一些硬件厂商本身就具备高可用,比如f5,路由器,防火墙等等)
- lvs/HAProxy/nginx(http/upstream, stream/upstream)
-
HA(High Availability)
- 高可用集群,数据库、Zookeeper、Redis SPoF: Single Point of Failure,解决单点故障
- (高可用类型高可用集群,服务本身具备集群或者主备功能,比如数据库、Zookeeper、Redis等等)
- 高可用集群,数据库、Zookeeper、Redis SPoF: Single Point of Failure,解决单点故障
-
HPC
- 高性能集群(High Performance Computing) https://www.top500.org
- (高性能类型高可用集群,比如超算中心,这个一般我们接触不到)
- 高性能集群(High Performance Computing) https://www.top500.org
-
系统可用性:
- SLA(Service-Level Agreement) 95%=(602430)*(1-0.9995)(指标)=99.9%, ..., 99.999%,99.9999%
- (对于运维来说,LB类型的,HA类型的高可用集群都会接触到,有百分之20的公司是根据运维维护系统的稳定性浮动的发工资,他会计算sla服务可用性,如果是一个月之内整个网站服务宕机时间低于指定的时间,就发全工资,这个时间用60分钟乘以24小时得出一天这么多分钟,然后乘以月,通常是30天,然后在乘以1减去0.9995这就是百分之99.95,这就得出每个月可宕机时间了,这个服务宕机时间可以通过第三方监控宝、听云,或者黑盒监控)
- SLA(Service-Level Agreement) 95%=(602430)*(1-0.9995)(指标)=99.9%, ..., 99.999%,99.9999%
-
示例
[23:15:44 root@localhost ~]#bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
(60*24*30)*(1-0.9995)
21.6000 # 每个月允许宕机21分钟
(60*24*30)*(1-0.9998)
8.6400 # 每个月允许宕机8分钟
-
系统故障(影响sla的故障非常多):
- 硬件故障:设计缺陷、wear out(损耗)、自然灾害....
- 软件故障:设计缺陷
-
提升系统高用性的解决方案之降低MTTR- Mean Time To Repair(平均故障时间)
- 解决方案,建立冗余机制如下:
- active/passive 在多台服务器做主/备
- active/active 在多台服务器做双主
- (降低故障时间)
- 解决方案,建立冗余机制如下:
-
高可用的是“服务可用性(服务可用性是衡量高可用的标准)”
- HA nginx service:
- (怎么实现高可用的nginx呢?)
- vip/nginx process[/shared storage]
- (先配置vip,然后把nginx跑起来,使他生成nginx process进程,然后给多个nginx挂个/shared storage共享存储,让每一个nginx都可以读到同一份数据)
- 资源:组成一个高可用服务的“组件” (这些资源就是组成高可用服务的组件,其实就是每一台nginx都是组成高可用服务的组件)
- (1) passive node的数量
- (如果服务挂了,那么这个passive node就是备份节点数量越多,那么高可用性越好)
- (2) 资源切换
- (这个时候就涉及到节点切换,就是我们的vip会自动飘逸,从主切到备)
- (1) passive node的数量
- HA nginx service:
-
Network partition:网络分区,由于网络设备故障导致的网络分裂,比如存在node1、node2、node3、node4、node5这五个节点,node1、node2处于同一个子网,node3、node4、node5处于另一个子网,中间通过交换机相连,若两个子网间的交换机故障率既发生了网络分区,node1、node2和node3、node4、node5便不能通讯,会导致集群运行异常,那么集群的正常运行如何维护?
- quorum:法定人数(法定人数就是允许宕机的主机数量)
- with quorum: > total/2 (with quorum在集群工作的主机,需要大于total是集群总数,除以2)
- without quorum: <= total/2 (without quorum是出问题的服务器,需要小于total是集群总数,除以2)
- (有些服务是本身具备高可用功能的,但是主机宕机不能超过集群法定人数的一半以上,否则集群就会出现问题)
- quorum:法定人数(法定人数就是允许宕机的主机数量)
-
双节点集群(TWO nodes Cluster)
- 辅助设备:ping node, quorum disk(仲裁设备)
- Failover:故障切换,即某资源的主节点故障时,将资源转移至其它节点的操作
- Failback:故障移回,即某资源的主节点故障后重新修改上线后,将之前已转移至其它节点的资源重新切回的过程
- (双节点就是haproxy、nginx、lvs这种负载均衡类型的,给他添加辅助设备,就是ping node相互之间ping或者quorum disk仲裁盘,这种仲裁盘就是在两个服务器上挂一个存储,存储里面可以先写好脚本,如果存储里面存在某一个文件,如果这个文件存在,那么就表示master宕机了,这个时候slave服务器就负责接管资源,所以如果通过ping,但是由于网线的关系,无法保证保证集群可用性,那么监控,比如zabbix监控服务的api或者url,如果能访问他就什么都不做,如果不能访问就往仲裁盘上生成一个文件,salve会周期性的检测这个文件是否存在,如果发现文件存在,就认为master挂了,不具备提供服务的能力,就会把master的vip资源抢过来,继续对外提供服务)
- (当出现主从服务器都绑定同一个vip的时候,我们把这个称之为脑裂,这会导致vip冲突, 可能是检查机制失败,就以为master挂了,就把自己提升为master了并绑定了vip资源,解决脑裂的方法可以通过仲裁设备判断避免脑裂,基于仲裁盘这种比较权威)
高可用集群-后端存储

- JBOD ( Just a Bunch Of Disks )不是标准的 RAID 等级,它通常用来表示一个没有控制软件提供协调控制的磁盘集合, JBOD 将多个物理磁盘串联起来,提供一个巨大的逻辑磁盘, JBOD 的数据存放机制是由第一块磁盘开始按顺序往后存储,当前磁盘存储空间用完后,再依次往后面的磁盘存储数据, JBOD 存储性能完全等同于单块磁盘,而且也不提供数据安全保护,它只是简单提供一种扩展存储空间的机制, JBOD 可用存储容量等于所有成员磁盘的存储空间之和。

keepalived
- keepalived在公司中用于,做某一种服务高可用,他本身其实不提供任何服务
- (redis有集群,mysql有主从,但是像nginx、lvs、haproxy这种服务没有这种高可用机制,这些没有高可用机制的服务通常就通过keepalived来实现高可用,keepalived本身通过vrrp协议,在两个服务器之间做心跳检测,如果第一个服务器挂了,那么第二个服务器会把vip资源接管过去,由第二个服务器对外提供服务。)
- 功能:
- 基于vrrp协议完成地址流动
- 为vip地址所在的节点生成ipvs规则(在配置文件中预先定义)
- 为ipvs集群的各RS做健康状态检测
- 基于脚本调用接口通过执行脚本完成脚本中定义的功能,进而影响集群事务,以此支持nginx,haproxy等服务
keepalived官网:https://keepalived.org/
keepalived组件介绍

-
用户空间核心组件
- vrrp stack-VIP消息通告
- (谁的优先级高,)
- checkers-监测real server
- system call-标记real server权
- SMTP-邮件组件
- ipvs wrapper-生成IPVS规则
- Netlink Reflector-网络接口
- WatchDog-监控进程
- vrrp stack-VIP消息通告
-
控制组件
- 配置文件解析(Control Plane Configuration file parser)
-
IO复用器(Scheduler-I/O Multiplexer)
-
内存管理组件(Memory Mngt)
keepalived安装
使用两台服务器server1和server2,一台yum安装,一台编译安装
keepalived安装-系统仓库源
系统自带的yum源他的版本相对会比较久,但是满足我们的需求,问题不大
示例
# server1 yum安装keepalived
[root@localhost ~]# yum -y install keepalived
# 查看安装后生成的文件
[root@localhost ~]# rpm -ql keepalived
/etc/keepalived/keepalived.conf # 主配置文件
/usr/lib/systemd/system/keepalived.service # service文件,如果编译安装这个service文件可以拷贝出来,后面编译安装使用
/usr/share/doc/keepalived-1.3.5/samples/keepalived.conf.vrrp # 模板文件,后面我们跟着这个文件来配置
/usr/share/doc/keepalived-1.3.5/samples/keepalived.conf.vrrp.scripts # 这也是一个模板文件
# 编辑配置文件(跟编译的配置一致,不要virtual_server这个后面在配置,修改vrrp_instance VI_1)
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_strict
#vrrp_iptables # 如果ping不通就添加这条参数,默认他会在iptables中生成规则(使用iptables -vnL查看),导致ping不通,编译安装的时候使用--disable-fwmark关闭这条规则,就可以ping通了,或者关闭iptables
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface eth0
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface ens33 # 看自己的网卡名,不一致服务起不来
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { # 虚拟出的ip地址,启动后这个地址是可以ping通的,绑定网卡
192.168.127.100/24 dev ens33 label ens33:0 # 这个地址不冲突,没人用,在同一个网段就行,也可以写掩码(dev ens33 label ens33:0不添加也能起来地址可以ping通,,label表示标签,加上启动会添加一个网卡)
# 192.168.127.101/24 dev ens33 label ens33:1 # 如果有多个标签可以顺序使用
}
}
# 重启keepalived
[root@localhost ~]# systemctl restart keepalived
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.128 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::2a84:c23d:b387:68 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
RX packets 34949 bytes 29578196 (28.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 9444 bytes 820667 (801.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.0 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 192 bytes 16704 (16.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 192 bytes 16704 (16.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# 客户端访问虚拟地址测试(ping通,测试成功)
[root@localhost ~]# ping 192.168.127.100
PING 192.168.127.100 (192.168.127.100) 56(84) bytes of data.
64 bytes from 192.168.127.100: icmp_seq=1 ttl=64 time=0.314 ms
64 bytes from 192.168.127.100: icmp_seq=2 ttl=64 time=0.346 ms
keepalived安装-编译安装
编译需要去官网把源码download下来,地址:https://keepalived.org/download.html#
示例
# 安装依赖关系
[root@localhost ~]# yum -y install libnfnetlink-devel libnfnetlink ipvsadm libnl libnl-devel libnl3 libnl3-devel lm_sensors-libs net-snmp-agent-libs net-snmp-libs openssh-server openssh-clients openssl openssl-devel automake iproute gcc
# 下载keepalievd源码包
[root@localhost ~]# wget https://keepalived.org/software/keepalived-2.2.2.tar.gz
# 解压keepalievd源码包
[root@localhost ~]# ls
anaconda-ks.cfg keepalived-2.2.2.tar.gz keepalived.service
[root@localhost ~]# tar xvf keepalived-2.2.2.tar.gz
# 进到keepalived-2.2.2目录
anaconda-ks.cfg keepalived-2.2.2 keepalived-2.2.2.tar.gz keepalived.service
[root@localhost ~]# cd keepalived-2.2.2
# 编译(--disable-fwmark)(测试不加此选项也可以ping通)这就是表示防火墙了,把这个防火墙关掉就行了,这个功能是,在装完keepalievd以后,他是禁止访问外面的请求到本机,为了保证keepalievd服务器的性能,这个我们一般给他关掉,如果不关会发现vip会ping不通)
[root@localhost keepalived-2.2.2]# ./configure --prefix=/apps/keepalived --disable-fwmark
# 查看编译的keepalived的service模板文件(这里面的变量,是根据编译时的参数进行替换)
[root@localhost keepalived-2.2.2]# cat keepalived/
bfd/ .deps/ main.c trackers/
check/ etc/ Makefile vrrp/
core/ include/ Makefile.am
dbus/ keepalived.service.in Makefile.in
[root@localhost keepalived-2.2.2]# cat keepalived/keepalived.service.in
[Unit]
Description=LVS and VRRP High Availability Monitor
After=network-online.target syslog.target @SNMP_SERVICE@
Wants=network-online.target @SNMP_SERVICE@
[Service]
Type=@SYSTEMD_SERVICE_TYPE@
PIDFile=@RUN_DIR@/run/keepalived.pid
KillMode=process
EnvironmentFile=-@sysconfdir@/sysconfig/keepalived
ExecStart=@sbindir@/keepalived @SYSTEMD_EXEC_START_OPTIONS@ $KEEPALIVED_OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
# 安装
[root@localhost keepalived-2.2.2]# make && make install
# 查看安装的路径下是否有程序(在这些目录当中,我们主要用的时sbin保存的主程序和etc保存在配置文件)
[root@localhost keepalived-2.2.2]# ll /apps/keepalived/
总用量 0
drwxr-xr-x. 2 root root 21 4月 5 22:39 bin
drwxr-xr-x. 4 root root 41 4月 5 22:39 etc
drwxr-xr-x. 2 root root 24 4月 5 22:39 sbin
drwxr-xr-x. 5 root root 40 4月 5 22:39 share
# 这时候编译安装完成,他就会把service文件生成好,里面的变量都会替换掉,查看一下,这个文件不用拷贝,他之间给你放到了/lib
[root@localhost keepalived-2.2.2]# cat keepalived/keepalived.service
[Unit]
Description=LVS and VRRP High Availability Monitor
After=network-online.target syslog.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/run/keepalived.pid
KillMode=process
EnvironmentFile=-/apps/keepalievd/etc/sysconfig/keepalived
ExecStart=/apps/keepalievd/sbin/keepalived $KEEPALIVED_OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
# 查看service下的keepalived.service
[root@localhost keepalived-2.2.2]# cat /lib/systemd/system/keepalived.service
[Unit]
Description=LVS and VRRP High Availability Monitor
After=network-online.target syslog.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/run/keepalived.pid
KillMode=process
EnvironmentFile=-/apps/keepalievd/etc/sysconfig/keepalived
ExecStart=/apps/keepalievd/sbin/keepalived $KEEPALIVED_OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
# 将配置文件拷贝到/etc下
[root@localhost keepalived-2.2.2]# mkdir -pv /etc/keepalived/
mkdir: 已创建目录 "/etc/keepalievd/"
[root@localhost keepalived-2.2.2]# cp ./keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
# 修改配置文件(删掉virtual_server)
[root@localhost keepalived-2.2.2]# vi /etc/keepalievd/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface eth0
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface ens33 # 看自己的网卡名,不一致服务起不来
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { # 虚拟出的ip地址,启动后这个地址是可以ping通的,绑定网卡
192.168.127.200 dev ens33 label ens33:0 # 这个地址不冲突,没人用,在同一个网段就行,可以写掩码(dev ens33 label ens33:0不添加也能起来地址可以ping通,,label表示标签,加上启动会添加一个网卡)
}
}
# 启动keepalived
[root@localhost keepalived-2.2.2]# systemctl restart keepalived
# 关闭防火墙,客户端ping虚拟地址(192.168.127.200此地址是虚拟地址,可以ping通,keepalievd启动正常)
[root@localhost keepalived-2.2.2]# systemctl stop firewalld
[root@localhost keepalived-2.2.2]# setenforce 0
[root@localhost ~]# ping 192.168.127.200
PING 192.168.127.200 (192.168.127.200) 56(84) bytes of data.
64 bytes from 192.168.127.200: icmp_seq=1 ttl=64 time=0.618 ms
64 bytes from 192.168.127.200: icmp_seq=2 ttl=64 time=0.759 ms
# 查看添加的虚拟网卡(可以看到ens33:0这个网卡,地址是192.168.127.200)
[root@localhost keepalived-2.2.2]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.130 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::416a:3c27:69b0:148f prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
RX packets 70803 bytes 96464492 (91.9 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 27448 bytes 2223924 (2.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 260 bytes 22624 (22.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 260 bytes 22624 (22.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
keepalived配置
Global全局配置
定义一些全局的默认配置
示例
global_defs区域主要是配置故障发生时的通知对象以及机器标识
global_defs {
notification_email { # 故障发生时(故障切换)给谁发邮件通知
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc # 通知邮件从哪个地址发出
smtp_server 192.168.200.1 # 通知邮件的smtp地址
smtp_connect_timeout 30 # 连接smtp服务器的超时时间
router_id LVS_DEVEL # 标识本节点的字符串,通常为hostname,但不一定非得是hostname。故障发生时,邮件通知会用到
vrrp_skip_check_adv_addr # 所有报文都检查比较消耗性能,此配置为如果收到的报文和上一个报文是同一个路由器则跳过检查报文中的源地址(主要是用来节省cpu开销的)
vrrp_strict # 严格遵守VRRP协议,不允许状况:
# 1,没有VIP地址(如果virtual_ipaddress中没有配置vip的话,服务起不来,会停止keepalived服务)
# 2.配置了单播邻居(不允许配置单播,服务器起不来,会停止keepalived服务)
# 3.在VRRP版本2中有IPv6地址
vrrp_garp_interval 0 #ARP报文发送延迟(不允许延迟,延迟干啥,ARP的广播不延迟,到时间就发送)
vrrp_gna_interval 0 # 消息发送延迟(也不延迟通告消息,到时间就发送)
vrrp_mcast_group4 224.0.0.18 # 默认组播IP地址,224.0.0.0到239.255.255.255
# vrrp_iptables # 会生成iptables规则,禁止来自vip的请求到服务器本机,是一种安全机制,比如配置了个vip,用户的请求都要到vip上,要是允许请求过来的话,那么很可能一部分请求包含的有攻击,那么这些攻击来了后,很有可能就把这些服务器的资源占完了,导致那些正常的请求进不来,但是有时候我们为了验证vip通不通我们还是需要给他关掉的,配置后在把这个iptables规则启用就好了
}
VRRP配置
- VRRP instance(s):即一个个的vrrp虚拟路由器
- (VRRP配置就是一个一个的instance,就是实例的意思,在k8s里面就是一个pod都是一个一个实例,或者说一个一个个体,在keepalived里面一个一个虚拟路由器就是一个实例,一个keepalived里面可以有好多个instance,需要保证每一个instance的virtual_router_id 51的id不一样和instance的名称也不能一样 全局配置一般很少去改)
示例
# vrrp_instance区域
vrrp_script switch { # 定义vrrp_script 区域名称
script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0" # 所要执行的脚本
interval 1 # 脚本执行间隔时间
weight 2 # 脚本结果导致的优先级变更:2表示优先级+2;-2则表示优先级-2
}
vrrp_instance VI_1 { # 用来定义对外提供服务的VIP区域及其相关属性
state MASTER # 可以是MASTER或BACKUP,不过当其他节点keepalived启动时会将priority比较大的节点选举为MASTER,因此该项其实没有实质用途
interface eth0 # 节点固有IP(非VIP)的网卡,用来发VRRP包
virtual_router_id 51 # 取值在0-255之间,用来区分多个instance的VRRP组播。 注意: 同一网段中virtual_router_id的值不能重复,否则会出错。
priority 100 # 用来选举master的,要成为master,那么这个选项的值最好高于其他机器50个点,数值高的优先级高,该项取值范围是1-255(在此范围之外会被识别成默认值100)
advert_int 1 # 检查间隔,默认为1秒
authentication { # 这里设置认证(认证机制)
auth_type PASS # 认证方式,可以是PASS或AH两种认证方式,pass表示密码认证,密码只使用前8位字符
auth_pass 1111 # 认证密码
}
track_script { # 对vrrp_script定义的脚本进行追踪
switch # 对那一个区域进行追踪
}
virtual_ipaddress {
192.168.200.16
192.168.200.17
192.168.200.18
}
notify_master /path/to/to_master.sh # 切换到主状态要发的通知
notify_backup /path_to/to_backup.sh # 切换到备状态要执行的通知
notify_fault "/path/fault.sh VG_1" # 故障时要执行的通知(如果路径中有空格,需要加双引号引用)
# 注意:
# 以上三个参数指的脚本要自定义
}
# 配置参数:
state MASTE|BACKUP:当前节点在此虚拟路由器上的初始状态,状态为MASTER或者BACKUP(state表示状态,这个状态只有MASTER和BACKUP两种状态,但是这个没有什么意义,最终需要使用priority来设置这个虚拟路由器是MASTER还是BACKUP,优先级最高就是MASTER)
interface IFACE_NAME:绑定为当前虚拟路由器使用的物理接口 ens32,eth0,bond0,br0(通过此接口接收报文的通告,不要写错了)
virtual_router_id VRID:当前虚拟路由器惟一标识,范围是0-255(这个实例或者这个虚拟路由器的id,在整个局域网中必须唯一)
priority 100:当前物理节点在此虚拟路由器中的优先级;范围1-254
advert_int 1:vrrp通告的时间间隔,默认1s(就是谁是MASTER,他过一段时间就会通告一次状态是ok的,时间可以长点,2秒钟比较合适,在通告报文当中会通告比如ip地址,虚拟路由器id, 通过tcpdump -i ehh0 -nn src 172.31.7.101进行抓包查看, 172.31.7.101是MASTE节点,可以看到BACKUP会接收MASTE节点的通告信息,就是MASTE在喊我是存活的)
LVS配置(不是必须的)
- 如果想要用keepalived去管理iptables规则那么就加上这些配置,很多时候我们只需要让keepalived做vip的高可用就够了,不加lvs
示例
# virtual_server区域
virtual_server 192.168.200.100 443 { # 对外通过ip地址192.168.200.100 提供443端口的服务
delay_loop 6 # 延迟轮询时间(s)
lb_algo rr # 后端指定的调度算法
lb_kind NAT # 调度模式
nat_mask 255.255.255.0 # 网络地址
persistence_timeout 50 # 会话保持时间(秒为单位),用户在50秒内被分配到同一个后端realserver
protocol TCP # 健康检查用的是TCP还是UDP
real_server 192.168.201.100 443 { # 后端真实节点主机的权重等设置,主要,后端有几台这里就要设置几个
weight 1 # 每一台realserver的权重
SSL_GET { # 健康检查方式
url { # 要检测的URL,可以有多个
path / # 具体的路径
digest ff20ad2481f97b1754ef3e12ecd3a9cc # 表示用genhash算出的结果
}
url {
path /mrtg/
digest 9b3a0c85a887a256d6939da88aabd8cd
}
connect_timeout 3 # 超时时长
nb_get_retry 3 # 重试次数
delay_before_retry 3 # 下次重试的时间延迟
}
}
}
参考
简介
示例
Keepalived:它的诞生最初是为ipvs(一些服务,内核中的一些规则)提供高可用性的,最初最主要目的是能够自主调用ipvsadm来生成规则,并且能够自动实现将用户访问的地址转移到其他节点上进行实现的。
Keepalived:核心包含两个ckeckers和VRRP协议。
ckeckers
检查服务检查reserved的健康状况的,基于脚本也可检查服务本身的健康状况。这里是实现ipvs后端健康状况的检测的。
VRRP
是一种容错协议,它保证当主机的下一跳路由器出现故障时,由另一台路由器来代替出现故障的路由器进行工作,从而保持网络通信的连续性和可靠性。VRRP中每个节点之间都有优先级的一般为0-255(0,255有特殊用法)数字越大优先级越高。
相关术语解析
-
虚拟路由器
- 由一个Master路由器和多个Backup路由器组成(组成一个虚拟路由器)。主机将虚拟路由器当作默认网关;
-
VRID
- 虚拟路由器的标识。有相同VRID的一组路由器构成一个虚拟路由器;
-
Master路由器
- 虚拟路由器中承担报文转发任务的路由器;
-
Backup路由器
- Master路由器出现故障时,能够代替Master路由器工作的路由器;
-
虚拟IP 地址
- 虚拟路由器的IP 地址。一个虚拟路由器可以拥有一个或多个IP地址;
-
IP地址拥有者
- 接口IP地址与虚拟IP地址相同的路由器被称为IP地址拥有者;
-
虚拟MAC地址
- 一个虚拟路由器拥有一个虚拟MAC地址。通常情况下,虚拟路由器回应ARP请求使用的是虚拟MAC地址,只有虚拟路由器做特殊配置的时候,才回应接口的真实MAC地址;
-
优先级
- VRRP根据优先级来确定虚拟路由器中每台路由器的地位;
-
非抢占方式
- 如果Backup路由器工作在非抢占方式下,则只要Master路由器没有出现故障Backup路由器即使随后被配置了更高的优先级也不会成为Master路由器;
-
抢占方式
- 如果Backup路由器工作在抢占方式下,当它收到VRRP报文后,会将自己的优先级与通告报文中的优先级进行比较。如果自己的优先级比当前的Master路由器的优先级高,就会主动抢占成为Master路由器;否则,将保持Backup状态.
Keepalived原理
组成模块
示例
keepalived也是模块化设计,不同模块复杂不同的功能,下面是keepalived的组件
core check vrrp libipfwc libipvs-2.4 libipvs-2.6
core
是keepalived的核心,复杂主进程的启动和维护,全局配置文件的加载解析等
check
负责healthchecker(健康检查),包括了各种健康检查方式,以及对应的配置的解析包括LVS的配置解析
vrrp
VRRPD子进程,VRRPD子进程就是来实现VRRP协议的
libipfwc
iptables(ipchains)库,配置LVS会用到
libipvs*
配置LVS会用到
进程
示例
keepalived启动后会有三个进程
父进程:内存管理,子进程管理等等
子进程:VRRP子进程
子进程:checkers子进程
两个子进程都被系统WatchDog看管,两个子进程各自复杂自己的事,checkers子进程复杂检查各自服务器的健康程度,例如HTTP,LVS等等,如果checkers子进程检查到MASTER上服务不可用,就会通知本机上的兄弟VRRP子进程,让他删除通告,并且去掉虚拟IP,转换为BACKUP状态
测试vip能够在两个server之间迁移完成
示例
- 两个server之间:
vrrp_instance # 名称一致
state # 状态需要分清主备MASTER和BACKUP
virtual_router_id # id号一致
priority # 优先级备份BACKUP的优先级不能高于主MASTER的优先级
authentication # 认证方式和密码一致
virtual_ipaddress # vip地址一致
示例,抢占模式
- 如果Backup路由器工作在抢占方式下,当它收到VRRP报文后,会将自己的优先级与通告报文中的优先级进行比较。如果自己的优先级比当前的Master路由器的优先级高,就会主动抢占成为Master路由器;否则,将保持Backup状态
示例
# server1安装keepalived和tcpdump抓包软件
[root@localhost ~]# yum -y install keepalived
[root@localhost ~]# yum -y install tcpdump
# server2安装keepalived和tcpdump抓包软件
[root@localhost ~]# yum -y install keepalived
[root@localhost ~]# yum -y install tcpdump
# server1编辑配置文件
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
...
vrrp_instance VI_1 {
state MASTER # 主的状态设置为MASTER
interface ens33 # 修改网卡名,绑定为当前虚拟路由器使用的物理接口,通过此接口接收报文的通告
virtual_router_id 51 # 虚拟路由器id,双方一致
priority 100 # 优先级100,需要BACKUP优先级高
advert_int 1 # 通告发送间隔必须一致
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress { # 配置vip地址
192.168.127.200 dev ens33 lable ens33:0
192.168.127.200 dev ens33 lable ens33:1 # 两个虚拟网卡的名称不能一致
}
}
# 配置文件直接拷贝到server2中
[root@localhost ~]# scp /etc/keepalived/keepalived.conf 192.168.127.130://etc/keepalived/keepalived.conf
# server2编辑修改一下配置文件
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
...
vrrp_instance VI_1 {
state BACKUP # 备份的状态设置为BACKUP
interface ens33 # 修改网卡名,绑定为当前虚拟路由器使用的物理接口,通过此接口接收报文的通告
virtual_router_id 51 # 虚拟路由器id,双方一致
priority 50 # 备份BACKUP的优先级不能比主MASTER的优先级高
advert_int 1 # 通告发送间隔必须一致
authentication { # 验证方式密码双方一致
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress { # 配置vip地址双方一致
192.168.127.200 dev ens33 lable ens33:0
192.168.127.200 dev ens33 lable ens33:1 # 两个虚拟网卡的名称不能一致
}
}
# server1启动keepalived服务,并查看网卡(MASTER配置vip)
[root@localhost ~]# systemctl restart keepalived
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.128 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::2a84:c23d:b387:68 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
RX packets 6876 bytes 789542 (771.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5634 bytes 733395 (716.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5920 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5920 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# server2启动keepalived服务,并查看网卡
[root@localhost ~]# systemctl restart keepalived
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.130 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::416a:3c27:69b0:148f prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
RX packets 7278 bytes 762605 (744.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4390 bytes 708381 (691.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5920 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5920 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# server2对MASTER的ip进行抓包(这个时候BACKUP节点相当于收到了MASTER节点的通告信息,其实就是告诉BACKUP节点我是存活的,存在的,如果MASTER节点没有通告,BACKUP节点才会接管MASTER角色,并绑定vip)
[root@localhost ~]# tcpdump -i ens33 -n src 192.168.127.128
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
09:30:37.252243 IP 192.168.127.128 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 24
09:30:38.254750 IP 192.168.127.128 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 24
09:30:39.255857 IP 192.168.127.128 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 24
09:30:40.258172 IP 192.168.127.128 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 24
09:30:41.263196 IP 192.168.127.128 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 24
## 192.168.127.128每隔一秒钟会发给224.0.0.18这个组播地址,他的版本是VRRPv2,vrid虚拟路由器的id是51,prio优先级是100,authtype simple密码是简单的,intvl 1s每间隔1秒钟,length报文长度是24个字节
## -i<网络界面> 使用指定的网络截面送出数据包(指定网卡)
## -n 不把主机的网络地址转换成名字
## src 数据包的源网络地址
# server1停掉keepalived服务,查看网卡(已经不提供vip),验证主备切换,抓包查看通知报文
[root@localhost ~]# systemctl stop keepalived
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.128 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::2a84:c23d:b387:68 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
RX packets 6985 bytes 798068 (779.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5824 bytes 749737 (732.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5920 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5920 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# server1对组播地址进行抓包(可以清晰的看到通告发送过程的vip迁移切换过程)
[root@localhost ~]# tcpdump -i ens33 -n host 224.0.0.18
10:18:08.946710 IP 192.168.127.130 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 24
10:18:09.955747 IP 192.168.127.130 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 24
10:18:09.956556 IP 192.168.127.128 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 24
10:18:10.957772 IP 192.168.127.128 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 24
# server2查看网卡并查看系统日志(可以看到当MASTER挂掉以后,BACKUP提升为MASTER角色的系统日志记录vip迁移过程)
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.130 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::416a:3c27:69b0:148f prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
RX packets 7534 bytes 778975 (760.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4489 bytes 715877 (699.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5920 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5920 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@localhost ~]# tail -f /var/log/messages
Apr 7 09:57:01 localhost systemd: Started Network Manager Script Dispatcher Service. (本地主机 系统:启动了网络管理器脚本调度程序服务。)
Apr 7 09:57:01 localhost nm-dispatcher: req:1 'dhcp4-change' [ens33]: new request (3 scripts) (本地主机 nm-调度器:req:1 'dhcp4-change' [ens33]: 新请求(3个脚本))
Apr 7 09:57:01 localhost nm-dispatcher: req:1 'dhcp4-change' [ens33]: start running ordered scripts... (本地主机 nm-调度器:req:1 'dhcp4-change' [ens33]:开始运行有序脚本... )
Apr 7 09:57:50 localhost Keepalived_vrrp[1467]: VRRP_Instance(VI_1) Transition to MASTER STATE (本地主机Keepalived_vrrp [1467]:VRRP_Instance(VI_1)转换为MASTER 状态)
Apr 7 09:57:51 localhost Keepalived_vrrp[1467]: VRRP_Instance(VI_1) Entering MASTER STATE (本地主机Keepalived_vrrp [1467]:VRRP_Instance(VI_1)进入MASTER 状态)
Apr 7 09:57:51 localhost Keepalived_vrrp[1467]: VRRP_Instance(VI_1) setting protocol iptable drop rule (本地主机Keepalived_vrrp [1467]:VRRP_Instance(VI_1)设置协议iptable删除规则)
Apr 7 09:57:51 localhost Keepalived_vrrp[1467]: VRRP_Instance(VI_1) setting protocol VIPs. (本地主机Keepalived_vrrp [1467]:VRRP_Instance(VI_1)设置协议VIPs。)(切换完毕他就会发送广播)
Apr 7 09:57:51 localhost Keepalived_vrrp[1467]: Sending gratuitous ARP on ens33 for 192.168.127.200 (本地主机Keepalived_vrrp [1467]:在ens33上为192.168.127.200发送免费ARP)
Apr 7 09:57:56 localhost Keepalived_vrrp[1467]: Sending gratuitous ARP on ens33 for 192.168.127.100 (本地主机Keepalived_vrrp [1467]:在ens33上为192.168.127.100发送免费ARP)
# server1启动keepalived服务查看网卡并查看系统日志(可以看到server1启动后,强行进行MASTER选举,重新拿到vip成为MASTER,server1的优先级高这就是抢占模式,)
[root@localhost ~]# systemctl restart keepalived
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.128 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::2a84:c23d:b387:68 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
RX packets 7758 bytes 855268 (835.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7196 bytes 865571 (845.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5920 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5920 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@localhost ~]# tail -f /var/log/messages
Apr 7 10:33:40 localhost Keepalived_vrrp[1642]: VRRP_Instance(VI_1) forcing a new MASTER election (本地主机Keepalived_vrrp [1642]:VRRP_Instance(VI_1)强制进行新的MASTER选举)
Apr 7 10:33:41 localhost Keepalived_vrrp[1642]: VRRP_Instance(VI_1) Transition to MASTER STATE (本地主机Keepalived_vrrp [1642]:VRRP_Instance(VI_1)转换为MASTER STATE)
Apr 7 10:33:42 localhost Keepalived_vrrp[1642]: VRRP_Instance(VI_1) Entering MASTER STATE (本地主机Keepalived_vrrp [1642]:VRRP_Instance(VI_1)进入MASTER STATE)
Apr 7 10:33:42 localhost Keepalived_vrrp[1642]: VRRP_Instance(VI_1) setting protocol iptable drop rule (本地主机Keepalived_vrrp [1642]:VRRP_Instance(VI_1)设置协议iptable删除规则)
Apr 7 10:33:42 localhost Keepalived_vrrp[1642]: VRRP_Instance(VI_1) setting protocol VIPs. (本地主机Keepalived_vrrp [1642]:VRRP_Instance(VI_1)设置协议VIP。)
Apr 7 10:33:42 localhost Keepalived_vrrp[1642]: Sending gratuitous ARP on ens33 for 192.168.127.200 (本地主机Keepalived_vrrp [1642]:在ens33上为192.168.127.200发送免费ARP)
Apr 7 10:33:47 localhost Keepalived_vrrp[1642]: Sending gratuitous ARP on ens33 for 192.168.127.100 (本地主机Keepalived_vrrp [1642]:在ens33上为192.168.127.100发送免费ARP)
示例:非抢占模式
- 如果Backup路由器工作在非抢占方式下,则只要Master路由器没有出现故障Backup路由器即使随后被配置了更高的优先级也不会成为Master路由器;
- (这种模式适合根据监控人工在闲时进行迁移vip,因为抢占模式在切换vip的时候,如果内网环境很差可能会出现服务的暂停中断,为了避免由于内网报文阻塞,而导致来回在两个节点之间频繁的vip迁移,倒是访问的中断或者超时,报错等等,因为客户端访问vip正在通信,突然切换了,连接中断了,这种模式使用很少,大多数使用抢占模式)
示例
# 非抢占模式要求
## 双方状态必须是Backup模式,这是初始的角色,根据优先级谁高判定谁是Master
## 不能开启vrrp_strict,开启会严格遵循vrrp协议,否者非抢占模式不生效
## nopreempt # 添加参数,关闭vip抢占
# server1编辑配置文件
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
...
# vrrp_strict # 注释掉vrrp_strict,否者他会严格遵循vrrp协议,导致非抢占模式不生效
vrrp_garp_interval 0
vrrp_gna_interval 0
vrrp_iptables
}
vrrp_instance VI_1 {
state BACKUP # 设置为BACKUP
interface ens33
virtual_router_id 51
priority 100 # 优先级设置为100
nopreempt # 关闭vip抢占,设置在优先级高的Master路由器节点,因为每次抢占都是优先级高的Master路由器节点进行抢占(如果只有两台keepalived的情况下情况下Master节点设置,如果有多台需要每一台都关闭vip抢占),需要各keepalived服务器state为BACKUP,
advert_int 1
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
}
# server2修改配置文件
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
...
# vrrp_strict # 注释掉vrrp_strict,否者他会严格遵循vrrp协议,导致非抢占模式不生效(主要是针对Master,如果有多台需要都关闭)
vrrp_garp_interval 0
vrrp_gna_interval 0
vrrp_iptables
}
vrrp_instance VI_1 {
state BACKUP # 设置为BACKUP
interface ens33
virtual_router_id 51
priority 50 # 优先级设置为50
nopreempt # 关闭vip抢占,设置在优先级高的Master路由器节点,因为每次抢占都是优先级高的Master路由器节点进行抢占(如果只有两台keepalived的情况下Master节点设置,如果有多台需要每一台都关闭vip抢占),需要各keepalived服务器state为BACKUP,
advert_int 1
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
}
# server1和server2重启服务,让配置文件生效
[root@localhost ~]# systemctl restart keepalived
# 查看server1的网卡(可以看到server1的优先级高这时候他还是Master)
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.128 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::2a84:c23d:b387:68 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
RX packets 8771 bytes 930068 (908.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 10129 bytes 1066763 (1.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5920 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5920 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# 查看server2网卡(server2由于优先级低,他现在是BACKUP)
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.130 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::416a:3c27:69b0:148f prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
RX packets 12018 bytes 1063111 (1.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5808 bytes 815455 (796.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5920 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5920 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# server1关闭Master节点keepalived服务
root@localhost ~]# systemctl stop keepalived
# server2查看系统日志,并查看网卡(由于Master节点挂了,vip的迁移是正常进行)
[root@localhost ~]# tail -f /var/log/messages
Apr 7 11:24:39 localhost Keepalived_vrrp[1817]: VRRP_Instance(VI_1) Transition to MASTER STATE (本地主机Keepalived_vrrp [1817]:VRRP_Instance(VI_1)转换为MASTER STATE)
Apr 7 11:24:40 localhost Keepalived_vrrp[1817]: VRRP_Instance(VI_1) Entering MASTER STATE (本地主机Keepalived_vrrp [1817]:VRRP_Instance(VI_1)进入MASTER STATE)
Apr 7 11:24:40 localhost Keepalived_vrrp[1817]: VRRP_Instance(VI_1) setting protocol VIPs. (本地主机Keepalived_vrrp [1817]:VRRP_Instance(VI_1)设置协议VIP。)
Apr 7 11:24:40 localhost Keepalived_vrrp[1817]: Sending gratuitous ARP on ens33 for 192.168.127.200 (本地主机Keepalived_vrrp [1817]:在ens33上为192.168.127.200发送免费ARP)
Apr 7 11:24:40 localhost Keepalived_vrrp[1817]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.127.200 (本地主机Keepalived_vrrp [1817]:VRRP_Instance(VI_1)在ens33上为192.168.127.200发送/排队免费ARP)
Apr 7 11:24:40 localhost Keepalived_vrrp[1817]: Sending gratuitous ARP on ens33 for 192.168.127.100 (本地主机Keepalived_vrrp [1817]:在ens33上为192.168.127.100发送免费ARP)
Apr 7 11:24:40 localhost Keepalived_vrrp[1817]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.127.10 (本地主机Keepalived_vrrp [1817]:VRRP_Instance(VI_1)在ens33上为192.168.127.10发送/排队免费ARP)
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.130 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::416a:3c27:69b0:148f prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
RX packets 12485 bytes 1093009 (1.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6086 bytes 839969 (820.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5920 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5920 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# server1重新上线,并查看网卡(验证非抢占,可以看到并未进行抢占,只有在server2挂掉了,server1才会切换回Master模式)
[root@localhost ~]# systemctl restart keepalived
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.128 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::2a84:c23d:b387:68 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
RX packets 9037 bytes 948893 (926.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 10535 bytes 1095837 (1.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5920 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5920 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
示例:抢占延迟模式
示例
# 抢占延迟模式要求
## 双方状态必须是Backup模式,这是初始的角色,根据优先级谁高判定谁是Master
## 不能开启vrrp_strict,开启会严格遵循vrrp协议,会立即抢占
## preempt_delay 60s # 非抢占模式,默认延迟300s,延迟60秒进行抢占
## Master还是Master只不过延迟一会在进行抢占
# server1修改配置文件
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
...
# vrrp_strict # 注释掉vrrp_strict,否者他会严格遵循vrrp协议,导致延迟抢占模式不生效(主要是针对Master,如果有多台需要都关闭)
vrrp_garp_interval 0
vrrp_gna_interval 0
vrrp_iptables
}
vrrp_instance VI_1 {
state BACKUP # 设置为BACKUP
interface ens33
virtual_router_id 51
priority 100 # 优先级设置为100
#nopreempt
preempt_delay 60s # 非抢占模式,默认延迟300s,(如果只有两台keepalived的情况下Master节点设置,如果有多台需要每一台都关闭vip抢占),需要各keepalived服务器state为BACKUP,
advert_int 1
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
}
# server2修改配置文件
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
...
# vrrp_strict # 注释掉vrrp_strict,否者他会严格遵循vrrp协议,导致延迟抢占模式不生效(主要是针对Master,如果有多台需要都关闭)
vrrp_garp_interval 0
vrrp_gna_interval 0
vrrp_iptables
}
vrrp_instance VI_1 {
state BACKUP # 设置为BACKUP
interface ens33
virtual_router_id 51
priority 50 # 优先级设置为50
#nopreempt
preempt_delay 60s # 非抢占模式,默认延迟300s,(如果只有两台keepalived的情况下Master节点设置,如果有多台需要每一台都关闭vip抢占),需要各keepalived服务器state为BACKUP,
advert_int 1
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
}
# server1和server2重启服务,让配置文件生效
[root@localhost ~]# systemctl restart keepalived
# server1查看网卡
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.128 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::2a84:c23d:b387:68 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
RX packets 9844 bytes 1009086 (985.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 11486 bytes 1172673 (1.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5920 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5920 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# server2查看网卡
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.130 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::416a:3c27:69b0:148f prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
RX packets 13222 bytes 1148859 (1.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6929 bytes 903821 (882.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 76 bytes 6624 (6.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 76 bytes 6624 (6.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# server1关闭Master节点keepalived服务
root@localhost ~]# systemctl stop keepalived
# server2查看系统日志,并查看网卡(由于Master节点挂了,vip的迁移是正常进行)
[root@localhost ~]# tail -f /var/log/messages
Apr 7 11:57:46 localhost Keepalived_vrrp[2002]: VRRP_Instance(VI_1) Received advert with higher priority 100, ours 50 (本地主机Keepalived_vrrp [2002]:VRRP_Instance(VI_1)收到优先级为100的通告,我们的优先级为50)
Apr 7 11:57:46 localhost Keepalived_vrrp[2002]: VRRP_Instance(VI_1) Entering BACKUP STATE (本地主机Keepalived_vrrp [2002]:VRRP_Instance(VI_1)输入备份状态)
Apr 7 11:57:46 localhost Keepalived_vrrp[2002]: VRRP_Instance(VI_1) removing protocol VIPs. (本地主机Keepalived_vrrp [2002]:VRRP_Instance(VI_1)删除了协议VIP。)
Apr 7 11:59:52 localhost Keepalived_vrrp[2002]: VRRP_Instance(VI_1) Transition to MASTER STATE (本地主机Keepalived_vrrp [2002]:VRRP_Instance(VI_1)转换为MASTER STATE)
Apr 7 11:59:53 localhost Keepalived_vrrp[2002]: VRRP_Instance(VI_1) Entering MASTER STATE (本地主机Keepalived_vrrp [2002]:VRRP_Instance(VI_1)进入MASTER STATE)
Apr 7 11:59:53 localhost Keepalived_vrrp[2002]: VRRP_Instance(VI_1) setting protocol VIPs. (本地主机Keepalived_vrrp [2002]:VRRP_Instance(VI_1)设置协议VIP。)
Apr 7 11:59:53 localhost Keepalived_vrrp[2002]: Sending gratuitous ARP on ens33 for 192.168.127.200 (本地主机Keepalived_vrrp [2002]:在ens33上为192.168.127.200发送免费ARP)
Apr 7 11:59:53 localhost Keepalived_vrrp[2002]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.127.200 (本地主机Keepalived_vrrp [2002]:VRRP_Instance(VI_1)在ens33上为192.168.127.200发送/排队免费ARP)
Apr 7 11:59:53 localhost Keepalived_vrrp[2002]: Sending gratuitous ARP on ens33 for 192.168.127.100 (本地主机Keepalived_vrrp [2002]:在ens33上为192.168.127.100发送免费ARP)
Apr 7 11:59:53 localhost Keepalived_vrrp[2002]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.127.10 (本地主机Keepalived_vrrp [2002]:VRRP_Instance(VI_1)在ens33上为192.168.127.100发送/排队免费ARP)
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.130 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::416a:3c27:69b0:148f prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
RX packets 12485 bytes 1093009 (1.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6086 bytes 839969 (820.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5920 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5920 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# server1重新上线,并查看网卡(验证延迟抢占,60秒后server1自动提升为Master)
[root@localhost ~]# systemctl restart keepalived
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.128 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::2a84:c23d:b387:68 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
RX packets 10970 bytes 1095095 (1.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 12302 bytes 1325983 (1.2 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5920 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5920 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
######60秒后(抢占过来了)
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.128 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::2a84:c23d:b387:68 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
RX packets 11092 bytes 1105202 (1.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 12430 bytes 1348287 (1.2 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 68 bytes 5920 (5.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 68 bytes 5920 (5.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
vip 单播配置及示例(Keepalivde 双主配置)
-
keepalived默认是组播,改成单播
- (因为组播是广播发送报文,比如大喇叭,容易产生广播风暴,单播是一对一发送广播,比如电话)
-
使用场景
- 在生成中负载均衡器特别多,一般是一个业务一个负载均衡器,或者一个访问l量加大的服务给他配置一个负载均衡器,如果访问量比较大,就单独给他配一个负载均衡器,所以这种负载均衡器使用的非常多,如果都配置成组播方式的话node1,node2,node3,node4都是这个vip地址,那么通告报文会产生影响,尤其是一不小心把vrid的id配置重了,然后一个节点发生了宕机,然后你的BACKUP节点会接管
示例:配置多个虚拟路由器
-
配置多个虚拟路由器,每一个虚拟路由器都有它自己的vrrp_instance名称,statc初始状态,interface指定接口,指定virtual_router_id尤其是这个id在同一个局域网内不要一样,priority然后安装实际需求配置MASTER,配置自己的advert_int通告间隔时间, authentication认证类型, virtual_ipaddress虚拟vip
-
我们的交换机是通过mac地址去通信的,在你的服务器上它会维护一张mac表(也叫arp广播表)
示例
[root@localhost ~]# arp -a
(192.168.127.130) at 00:0c:29:b2:97:66 [ether] on ens33
(192.168.127.1) at 00:50:56:c0:00:08 [ether] on ens33
gateway (192.168.127.2) at 00:50:56:e6:57:d7 [ether] on ens33
(192.168.127.254) at 00:50:56:fb:ac:67 [ether] on ens33
- 用来广播你的192.168.127.130这个ip地址所对应的 00:0c:29:b2:97:66这个mac地址,为什么这个vip发生迁移之后,会有对应的服务器处理用户请求,比如server1宕机了,server2来处理用户请求,这是因为它的它的mac地址变了,vip地址在迁到了server2之后,会有server2的服务器在整个VLAN之间,整个广播是针对于VLAN的进行arp广播,告诉整个VLAN的服务器,整个ip地址我接管了,我的mac地址是多少多少,所以说在内网之内对同一个ip地址的访问就会指向,转发到新的mac地址,同一个VLAN之间的设备都能收到,交换机也能收到,所以交换机也会维护这张arp表,所以我们看虚拟网卡的ip地址都是在物理网卡的mac地址上绑定,对虚拟网卡的访问都会丢到服务网卡进行处理,所有虚拟网卡都是共用物理网卡的mac地址,在局域网之间通信,而虚拟网卡在内网之间进行通信不跨网络走的是mac地址,交换机是不识别ip地址的
示例
# 两个路由器配置两个虚拟路由器
# server1编辑配置文件
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
...
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 100
# nopreempt
preempt_delay 20s
advert_int 1
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
}
vrrp_instance VI_2 { # 修改虚拟路由器名称为VI_2,同一个路由器内,虚拟路由器的名称不要一致
state BACKUP
interface ens33
virtual_router_id 52 # virtual_router_id修改成52顺序使用,和VI_1虚拟路由器不能一样
priority 80 # 优先级改成80
advert_int 2 # 通告间隔时间改成2秒一次
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress { # vip和VI_1虚拟路由器不能一样
192.168.127.220 dev ens33 label ens33:0 # 修片vip地址,网卡子接口也不能和VI_1虚拟路由器一样,因为eth0:0和eth0:1已经被VI_1虚拟路由器占用了,可以顺序使用
192.168.127.110 dev ens33 label ens33:1
}
}
# server2编辑配置文件
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
...
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 50
preempt_delay 60s
advert_int 1
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
}
vrrp_instance VI_2 { # 修改虚拟路由器名称为VI_2,同一个路由器内,虚拟路由器的名称不要一致
state BACKUP
interface ens33
virtual_router_id 52 # virtual_router_id修改成52顺序使用,和VI_1虚拟路由器不能一样
priority 81 # 优先级改成81,比server1的优先级高就行
advert_int 2 # 通告间隔时间改成2秒一次
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress { # vip和VI_1虚拟路由器不能一样
192.168.127.220 dev ens33 label ens33:0 # 修片vip地址,网卡子接口也不能和VI_1虚拟路由器一样,因为eth0:0和eth0:1已经被VI_1虚拟路由器占用了,可以顺序使用
192.168.127.110 dev ens33 label ens33:1
}
}
结构图
示例
# 重启server1和server2的服务
#(可以看到这时候有两个虚拟路由器,每一个虚拟路由器可以配置多个地址)
#(这个时候我们的高可用依然是可用的,server1挂了是不影响server2的)
## 重启server1的keepalived服务,并查看网卡接口
[root@localhost ~]# systemctl restart keepalived
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.128 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::2a84:c23d:b387:68 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
RX packets 15922 bytes 1475890 (1.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 25513 bytes 2392437 (2.2 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 76 bytes 6624 (6.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 76 bytes 6624 (6.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
## 重启server2keepalived服务,并查看网卡接口
[root@localhost ~]# systemctl restart keepalived
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.130 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::416a:3c27:69b0:148f prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
RX packets 28123 bytes 2120963 (2.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 9827 bytes 1231307 (1.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.220 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
ens33:3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.110 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 76 bytes 6624 (6.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 76 bytes 6624 (6.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
单播配置示例
-
配置了server1和server2互为主备就不要使用多播了,因为影响访问太大了
- 两个server都需要配置单播,因为可能其中一台会宕机,另一个会成为MASTER,他们需要互相发送单播通知
示例
- 语法
unicast_src_ip # 指定单播的源IP(源地址就是当前keepalived本机地址)
unicast_peer { # 指定单播的对方IP,如果是多个keepalived指定多个目标主机的ip,向多目标发送通知
目标主机IP
}
注意: vrrp_strict # 严格模式不支持单播
# server1编辑配置文件
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
...
# vrrp_strict # 注释掉vrrp_strict,严格模式不支持单播
vrrp_garp_interval 0
vrrp_gna_interval 0
vrrp_iptables
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 100
advert_int 1
unicast_src_ip 192.168.127.128 # 我的源地址
unicast_peer {
192.168.127.130 # 目标地址,可以写多个但是这里我们只有两台服务器,这时候它就不会在发送给224.0.0.18的组播地址了,也就是说发送这个报文的目标地址就是192.168.127.130
# 193.168.127.140 # 这里可以添加多个目标主机,比如三台keepalived,每台都需要添加
}
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
}
...
# server2编辑配置文件(server1的如果挂了,server2也可能成为MASTER,所以server2也要配置发送到server1的单播)
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
...
# vrrp_strict # 注释掉vrrp_strict,严格模式不支持单播
vrrp_garp_interval 0
vrrp_gna_interval 0
vrrp_iptables
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 50
preempt_delay 60s
advert_int 1
unicast_src_ip 192.168.127.130 # 源地址当前keepalived的本机地址
unicast_peer {
192.168.127.128 # 目标地址
}
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
}
...
# server1和server2重启keepalived
[root@localhost ~]# systemctl restart keepalived
# server1查看网卡接口
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.128 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::2a84:c23d:b387:68 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
RX packets 27777 bytes 2304449 (2.1 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 42023 bytes 4959005 (4.7 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 80 bytes 6960 (6.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 80 bytes 6960 (6.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# server2查看网卡接口
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.130 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::416a:3c27:69b0:148f prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
RX packets 39956 bytes 2893666 (2.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 20830 bytes 3073243 (2.9 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.220 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
ens33:3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.110 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 76 bytes 6624 (6.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 76 bytes 6624 (6.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# server1或server2这个时候在去抓包224.0.0.18就抓不到了
[root@localhost ~]# tcpdump -i ens33 -n 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
# server2去server1的192.168.127.128抓包(可以看到源地址192.168.127.128目的地址是192.168.127.130而不再是224.0.0.18的组播地址)
[root@localhost ~]# tcpdump -i ens33 -n src 192.168.127.128
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
17:13:38.111012 IP 192.168.127.128 > 192.168.127.130: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 24
17:13:39.119027 IP 192.168.127.128 > 192.168.127.130: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 24
17:13:40.131518 IP 192.168.127.128 > 192.168.127.130: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 24
# server1停止keepalived服务,server2成为MASTER后是否会发送单播
[root@localhost ~]# systemctl stop keepalived
# server2查看网卡(vip迁移成功)
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.130 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::416a:3c27:69b0:148f prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
RX packets 40891 bytes 2959938 (2.8 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 21420 bytes 3133445 (2.9 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
ens33:2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.220 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
ens33:3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.110 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 76 bytes 6624 (6.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 76 bytes 6624 (6.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# server1对server2进行抓包(测试成功,地址192.168.127.130向192.168.127.128发送单播地址)
[root@localhost ~]# tcpdump -i ens33 -n src 192.168.127.130
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
17:17:20.412297 IP 192.168.127.130 > 192.168.127.128: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 24
17:17:21.413259 IP 192.168.127.130 > 192.168.127.128: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 24
17:17:21.557857 IP 192.168.127.130 > 224.0.0.18: VRRPv2, Advertisement, vrid 52, prio 81, authtype simple, intvl 2s, length 24 # 这个多播是因为,server2上配置了多个vrrp_instance,我们只为其中一个vrrp_instance配置了单播,所以别的vrrp_instance还是发送的多播给224.0.0.18
对配置文件进行切分,配置子配置文件
在主配置文件中配置的太多会不好维护,可以和nginx一样做子配置文件,对每一个vrrp_instance虚拟路由器,或者虚拟路由器中的配置进行细分创建,比如unicast_src_ip配置单播
示例
# 创建目录
[root@localhost ~]# mkdir -pv /etc/keepalived/vipdir
mkdir: 已创建目录 "/etc/keepalived/vipdir"
# 创建子配置文件
[root@localhost ~]# vi /etc/keepalived/vipdir/vip.conf
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
unicast_src_ip 192.168.127.128
unicast_peer {
192.168.127.130
}
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
}
vrrp_instance VI_2 {
state BACKUP
interface ens33
virtual_router_id 52
priority 80
advert_int 2
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.220 dev ens33 label ens33:2
192.168.127.110 dev ens33 label ens33:3
}
}
# 编辑主配置文件
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
vrrp_iptables
}
include /etc/keepalived/vipdir/*.conf # 添加一条include指向子配置文件路径
# 重启keepalived查看网卡(vip配置成功)
[root@localhost ~]# systemctl restart keepalived
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.128 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::2a84:c23d:b387:68 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
RX packets 34535 bytes 2788455 (2.6 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 48026 bytes 5547415 (5.2 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:7c:7a:83 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 80 bytes 6960 (6.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 80 bytes 6960 (6.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Keepalived通知配置
安装配置mailx
示例
# 安装mailx命令(有几个keepalived就安装几个,因为他们都有可能成为MASTER,进行vip迁移,触发邮件的迁移)
[root@localhost ~]# yum -y install mailx
## mailx本命令用于发送和接收邮件,名字是收信人的用户名,本命令有许多内部命令
# 编辑配置邮件服务器(这里用的163邮箱,也可以用qq邮箱)
[root@localhost ~]# vi /etc/mail.rc
...
set from=xxxxxxxxx@163.com # 发件人,在邮箱里面,比如qq邮箱需要打开设置-->账号-->打开POP3/SMTP服务(POP3是收邮件的,端口是995,smtp是发邮件的,端口是465)
set smtp=smtp.163.com # 指定发件服务器
set smtp-auth-user=xxxxxxxx@163.com # 认证,就是你的邮箱
set smtp-auth-password=xxxxxxxxx # 认证密码,就是授权码
set smtp-auth=login # 认证方式
set ssl-verify=ignore # 忽略证书警告,如果要证书还要交互,所以这里就不要证书了
# 使用echo发送邮件测试
[root@localhost ~]# echo "testmail" | mail -v -s "mail for helloworld" xxxxxxx@qq.com
## -s:指定主题
## -v: 发送时显示详细信息(可以看到发送失败的原因)
## mail -v -a /path/filename -s “主题” dizhi@domain.com 带附件发送
### 错误信息:
####qq邮箱错误:
#####503 Error: need EHLO and AUTH first 表示账号设置有问题,验证不通过(试试复制,不要手动输入)
#####501 Bad address syntax 您所填写的收件人地址格式不正确
####163邮箱错误
#####553 authentication is required,163 表明发件方的身份没有得到认证,而网易的邮箱服务器对于域内的发件方在连接smtp服务器的时候都是要求身份认证的。(试试复制,不要手动输入)
配置keepalived
定义通知脚本
notify_master
| keepalived内置函数用于感知当前的虚拟路由器变成了master主节点时触发的脚本
notify_backup
| keepalived内置函数用于感知当前的虚拟路由器变成了backup备份节点时触发的脚本
notify_fault
| keepalived内置函数用于感知当前的虚拟路由器变成了fault“失败”状态时触发的脚本
notify
| keepalived内置函数,通用格式的通知触发机制,一个脚本可以完成以上三种状态的转换时的通知
定义脚本
示例
# server2定义脚本,测试单台服务器
[root@localhost ~]# vi /etc/keepalived/notify.sh
#!/bin/bash
contact='xxxxxxx@qq.com' # 当发生了故障转移,状态发生了转换,发送邮件,发送给谁,收件人,公司中一般是整个部门的邮件组
notify() { # 定义一个函数notify
mailsubject="$(hostname) to be $1, vip 转移"
mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1" # mailsubject我的主机是$(hostname)取我当前主机的主机名,to be发送到$1这是一个变量需要在case $1 in中判断,并把变量传递到$1中,然后是发送内容“vip 转移“这可以自己写
echo "$mailbody" | mail -v -s "$mailsubject" $contact # -v写在-s前面,否者它会把-v当做标题,测试添加-v
}
# mailbody什么时间$(date +'%F %T')取当前时间赋值给他,vrrp transition发生的vrrp的transition状态转移
case $1 in # case类似if,将匹配到的值赋值给$1
master) # 如果是master
notify master # 将此值赋值给$1
;;
backup) # backup
notify backup # 将此值赋值给$1
;;
fault) # fault
notify fault # 将此值赋值给$1
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac
echo $1
echo $mailsubject
echo mailbody
echo $contact
echo $(date +'%F %T')
# 给脚本执行权限
[root@localhost ~]# chmod a+x /etc/keepalived/notify.sh
# 测试脚本(测试成功)
[root@localhost ~]# bash /etc/keepalived/notify.sh master
keepalived调用脚本
示例
# server1编辑子配置文件(需要单独配置到虚拟路由器中,仅生效当前配置的虚拟路由器,主配置文件中需要指定子配置文件路径)
[root@localhost ~]# vi /etc/keepalived/vipdir/vip.conf
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100 # 优先级高为master
advert_int 1
unicast_src_ip 192.168.127.128 # 设置了单播,指向backup,需要在主配置文件全局中关闭vrrp_strict严格的vrrp协议不支持单播
unicast_peer {
192.168.127.130
}
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
# server2编辑子配置文件(需要单独配置到虚拟路由器中,仅生效当前配置的虚拟路由器,主配置文件中需要指定子配置文件路径)
[root@localhost ~]# vi /etc/keepalived/vipdir/vip.conf
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 80 # 优先级高为BACKUP
advert_int 1
unicast_src_ip 192.168.127.130 # 设置了单播指向master,需要在主配置文件全局中关闭vrrp_strict严格的vrrp协议不支持单播
unicast_peer {
192.168.127.128
}
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
# server1和server2重启keepalived生效配置(脚本如果不执行,可以测试一个小脚本,检测是脚本的问题还是美哟执行脚本)
[root@localhost ~]# systemctl restart keepalived
# server1停止keepalived
[root@localhost ~]# systemctl stop keepalived
# servcer2接管master角色,并触发执行脚本发送邮件
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.130 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::416a:3c27:69b0:148f prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
RX packets 22858 bytes 29001439 (27.6 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8581 bytes 746068 (728.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.200 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:b2:97:66 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 260 bytes 22624 (22.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 260 bytes 22624 (22.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
KeepAlived与IPVS
结合keepalived生成IPVS规则,实现real server状态检测/DR模式
配置参数
示例
# virtual server 配置参数:
virtual server #(虚拟服务)的定义虚拟主机:
virtual_server IP port # 定义虚拟主机IP地址及其端口(使用的最多的方式)
virtual_server fwmark int # ipvs的防火墙打标,实现基于防火墙的负载均衡集群
virtual_server group string # 将多个虚拟服务器定义成组,将组定义成虚拟服务(如果服务器很多可以分组)
# 示例:
virtual_server IP port # 它不做地址转换和不做端口转换,而是通过整个地址和端口响应,所以用户请求的目的地址的目的端口,是作为构建报文时候的源地址和源端口来构建报文的,最核心的原因在于,你的后端服务器要通过这个端口构建响应报文,用户请求的是80,你就必须有80端口来响应
{
...
real_server {
...
}
…
}
real_server 配置参数
示例
delay_loop <INT>: # 检查后端服务器的时间间隔(对后端服务器多长时间检查一次)
lb_algo rr|wrr|lc|wlc|lblc|sh|dh: # 定义调度方法(指定算法一般使用rr和wrr和lc)
lb_kind NAT|DR|TUN: # 集群的类型(lvs一般用DR模式)
persistence_timeout <INT>: # 持久连接时长(会话时长,一定时间内如果说用户访问之后,没有做什么操作,在一定时间之后会给他断开连接,这个要设置长点,如果用户一请求断了,用户在请求还要建立三次握手,这个值通常是30s或者60s)
protocol TCP|UDP|SCTP: # 指定服务协议(主要使用tcp协议)
sorry_server <IPADDR> <PORT>: # 所有RS故障时,备用服务器地址(这个值也很少写)
# real_server 示例:
real_server <IPADDR> <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_CHEC K { ... }: # 定义当前主机的健康状态检测方法(定义对后端服务器的状态检查方法,HTTP_GET实现http检查,SSL_GET实现https检查,TCP_CHECK实现tcp检测比如检测后端服务器的端口状态,SMTP_CHECK邮件检测,如果要做应用层检测就用HTTP_GET,如果是做传输层检测就用TCP_CHECK,所以一般使用这两种方法)
}
应用层检测
示例
HTTP_GET|SSL_GET:应用层检测
HTTP_GET|SSL_GET {
url {
path <URL_PATH>:定义要监控的URL
status_code <INT>:判断上述检测机制为健康状态的响应码
}
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>:发出健康状态检测请求时使用的源地址
bind_port <PORT>:发出健康状态检测请求时使用的源端口
}
keepalived案例一:实现LVS-DR模式(基于http检测)
示例
# 建立两台后端nginx
## web A安装,启动,创建测试页,关闭防火墙,访问测试
[root@localhost ~]# yum -y install epel-release
[root@localhost ~]# yum -y install nginx
[root@localhost ~]# echo "web A" > /usr/share/nginx/html/index.html
[root@localhost ~]# cat /usr/share/nginx/html/index.html
web A
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# systemctl start nginx
### 客户端访问测试
[root@localhost ~]# curl 192.168.127.129
web A
## web B安装,启动,创建测试页,关闭防火墙,访问测试
[root@localhost ~]# yum -y install epel-release
[root@localhost ~]# yum -y install nginx
[root@localhost ~]# echo "web B" > /usr/share/nginx/html/index.html
[root@localhost ~]# cat /usr/share/nginx/html/index.html
web B
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# systemctl start nginx
### 客户端访问测试
[root@localhost ~]# curl 192.168.127.131
web B
# server1和server2安装ipvsadm查看iptables规则
[root@localhost ~]# ipvsadm
# server1编辑主配置文件(注意:括号必须展开,否者服务不生效)
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
...
# vrrp_strict # 注释掉有严格的vrrp
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100 # 优先级100为MASTER
advert_int 1
unicast_src_ip 192.168.127.128
unicast_peer {
192.168.127.130 # 单播指向server2
}
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
virtual_server 192.168.127.128 80 { # 这个virtual_server要写你的vip地址和端口,会绑定
delay_loop 6 # 检测后端服务器间隔时间是6秒钟一次
lb_algo wrr
lb_kind DR # 使用的算法是DR模式加权轮询
#persistence_timeout 120 # 会话保持时间
protocol TCP
# sorry_server 172.18.200.105 80 # 备份服务器后面在加
real_server 192.168.127.129 80 { # 后端服务器
weight 1
HTTP_GET {
url{
path /index.html # 这个路径是192.168.127.129:80/index.html
status_code 200
}
connect_timeout 10 # 客户端请求的超时时长,如果请求后那么长时间没有响应数据我就认为后端服务器挂了,这个时间一定要设置的长点,有可能后端服务器负载比较高,响应数据慢,但是并没有挂掉,比如数据库,它真的可能3秒5秒返回不了数据
nb_get_retry 3 # 连续重试次数
delay_before_retry 1 # 重试之前的延迟时长
}
}
# 关闭防火墙
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
# 重新启动keepalived配置生效
[root@localhost ~]# systemctl restart keepalived
# 查看iptables规则(已经生效)
[root@localhost ~]# 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.127.128:80 wrr # 本机的vip地址的80端口接收的请求,使用wrr调度到下面的服务器
-> 192.168.127.129:80 Route 1 0 0 # 探测80端口通过的后端服务,如果不通过就踢出去
-> 192.168.127.131:80 Route 1 0 0
# 配置文件拷贝到server2(覆盖掉原来配置文件)
[root@localhost ~]# scp /etc/keepalived/keepalived.conf 192.168.127.130:/etc/keepalived/keepalived.conf
# server2编辑主配置文件,改吧改吧(注意:括号必须展开,否者服务不生效)
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
...
# vrrp_strict # 注释掉有严格的vrrp
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 80 # 优先级80为BACKUP
advert_int 1
unicast_src_ip 192.168.127.130
unicast_peer {
192.168.127.128 # 单播指向server1
}
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
virtual_server 192.168.127.200 80 {
delay_loop 6
lb_algo wrr
lb_kind DR
#persistence_timeout 120 #会话保持时间
protocol TCP
# sorry_server 172.18.200.105 80
real_server 192.168.127.129 80 {
weight 1
HTTP_GET {
url{
path /index.html
status_code 200
}
connect_timeout 10
nb_get_retry 3
delay_before_retry 1
}
}
real_server 192.168.127.131 80 {
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
# 关闭防火墙
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
# 重新启动keepalived配置生效
[root@localhost ~]# systemctl restart keepalived
# 查看iptables规则(已经生效)
[root@localhost ~]# 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.127.128:80 wrr # 本机的vip地址的80端口接收的请求,使用wrr调度到下面的服务器
-> 192.168.127.129:80 Route 1 0 0 # 探测80端口通过的后端服务,如果不通过就踢出去
-> 192.168.127.131:80 Route 1 0 0
# 后端服务器web A和web B配置绑定vip
[root@localhost ~]# vi ipvs-dr.sh
#!/bin/bash
# LVS DR模式初始化脚本
# 2020-04-09
LVS_VIP=192.168.127.200 # 绑定vip地址
source /etc/rc.d/init.d/functions
case "$1" in
start)
/sbin/ifconfig lo:0 $LVS_VIP netmask 255.255.255.255 broadcast $LVS_VIP
/sbin/route add -host $LVS_VIP dev lo:0
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "3" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "4" > /proc/sys/net/ipv4/conf/all/arp_announce
sysctl -p > /dev/null 2>&1
echo "RralServer Start OK"
;;
stop)
/sbin/ifconfig lo:0 down
/sbin/route del $LVS_VIP > /dev/null 2>&1
echo "0" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "0" > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "0" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" > /proc/sys/net/ipv4/conf/all/arp_announce
echo "RralServer Stopcd"
;;
*)
echo "Usage: $0 {start|stop}" #start是绑定,stop是清空不在绑定
exit 1
esac
exit 0
# web A执行脚本。绑定vip地址,并查看
[root@localhost ~]# bash ipvs-dr.sh start
RralServer Start OK
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.129 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::c513:18bd:6548:58e7 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:dc:47:29 txqueuelen 1000 (Ethernet)
RX packets 40052 bytes 45115448 (43.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 12963 bytes 1183545 (1.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 202 bytes 17553 (17.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 202 bytes 17553 (17.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo:0: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 192.168.127.200 netmask 255.255.255.255 # 可以看到已绑定vip地址
loop txqueuelen 1 (Local Loopback)
# web B执行脚本。绑定vip地址
[root@localhost ~]# bash ipvs-dr.sh start
RralServer Start OK
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.131 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::38c1:af97:6cab:fec prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:f3:d6:d8 txqueuelen 1000 (Ethernet)
RX packets 34778 bytes 42499557 (40.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 13718 bytes 1151959 (1.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 4 bytes 352 (352.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4 bytes 352 (352.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo:0: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 192.168.127.200 netmask 255.255.255.255 # 可以看到已绑定vip地址
loop txqueuelen 1 (Local Loopback)
# 客户端访问测试(访问vip地址返回页面测试成功)
[root@localhost ~]# curl 192.168.127.200
web A
# http存活测试
## 后端服务器web A的index.html存在访问检测正常
[root@localhost ~]# 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.127.200:80 wrr
-> 192.168.127.129:80 Route 1 0 0
-> 192.168.127.131:80 Route 1 0 0
# 将web Aindex.html改名字,与检测名字不一致
[root@localhost ~]# mv /usr/share/nginx/html/index.html /usr/share/nginx/html/index.html.bak
# 后端服务器web A的index.htm不l存在,将服务器踢出去
[root@localhost ~]# 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.127.200:80 wrr
-> 192.168.127.129:80 Route 1 0 0
TCP检测
示例
传输层检测 TCP_CHECK
TCP_CHECK {
connect_ip <IP ADDRESS>:向当前RS的哪个IP地址发起健康状态检测请求(如果公网有多个ip地址,向哪个地址检测,如果不写它会检测real_server配置的地址)
connect_port <PORT>:向当前RS的哪个PORT发起健康状态检测请求
bindto <IP ADDRESS>:发出健康状态检测请求时使用的源地址 # 如果是内网,一般都不写
bind_port <PORT>:发出健康状态检测请求时使用的源端口
connect_timeout <INTEGER>:客户端请求的超时时长, 等于haproxy的timeout server
}
keepalived案例一:实现LVS-DR模式(基于TCP检测)
示例
# 建立两台后端nginx
## web A安装,启动,创建测试页,关闭防火墙,访问测试
[root@localhost ~]# yum -y install epel-release
[root@localhost ~]# yum -y install nginx
[root@localhost ~]# echo "web A" > /usr/share/nginx/html/index.html
[root@localhost ~]# cat /usr/share/nginx/html/index.html
web A
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# systemctl start nginx
### 客户端访问测试
[root@localhost ~]# curl 192.168.127.129
web A
## web B安装,启动,创建测试页,关闭防火墙,访问测试
[root@localhost ~]# yum -y install epel-release
[root@localhost ~]# yum -y install nginx
[root@localhost ~]# echo "web B" > /usr/share/nginx/html/index.html
[root@localhost ~]# cat /usr/share/nginx/html/index.html
web B
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# systemctl start nginx
### 客户端访问测试
[root@localhost ~]# curl 192.168.127.131
web B
# server1和server2安装ipvsadm查看iptables规则
[root@localhost ~]# ipvsadm
# server1编辑主配置文件(注意:括号必须展开,否者服务不生效)
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
...
# vrrp_strict # 注释掉有严格的vrrp
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100 # 优先级100为MASTER
advert_int 1
unicast_src_ip 192.168.127.128
unicast_peer {
192.168.127.130 # 单播指向server2
}
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
virtual_server 192.168.127.128 80 { # 这个virtual_server要写你的vip地址和端口,会绑定
delay_loop 6 # 检测后端服务器间隔时间是6秒钟一次
lb_algo wrr
lb_kind DR # 使用的算法是DR模式加权轮询
#persistence_timeout 120 # 会话保持时间
protocol TCP
# sorry_server 172.18.200.105 80 # 备份服务器后面在加
real_server 192.168.127.129 80 { # 后端服务器
weight 1
TCP_CHECK {
connect_timeout 10 # 客户端请求的超时时长,如果请求后那么长时间没有响应数据我就认为后端服务器挂了,这个时间一定要设置的长点,有可能后端服务器负载比较高,响应数据慢,但是并没有挂掉,比如数据库,它真的可能3秒5秒返回不了数据
nb_get_retry 3 # 连续重试次数
delay_before_retry 1 # 重试之前的延迟时长
connect_port 80 # 检测的时候后端服务器80端口存在我就认为服务是好的
}
}
# 关闭防火墙
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
# 重新启动keepalived配置生效
[root@localhost ~]# systemctl restart keepalived
# 查看iptables规则(已经生效)
[root@localhost ~]# 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.127.128:80 wrr # 本机的vip地址的80端口接收的请求,使用wrr调度到下面的服务器
-> 192.168.127.129:80 Route 1 0 0 # 探测80端口通过的后端服务,如果不通过就踢出去
-> 192.168.127.131:80 Route 1 0 0
# 配置文件拷贝到server2(覆盖掉原来配置文件)
[root@localhost ~]# scp /etc/keepalived/keepalived.conf 192.168.127.130:/etc/keepalived/keepalived.conf
# server2编辑主配置文件,改吧改吧(注意:括号必须展开,否者服务不生效)
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
...
# vrrp_strict # 注释掉有严格的vrrp
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 80 # 优先级80为BACKUP
advert_int 1
unicast_src_ip 192.168.127.130
unicast_peer {
192.168.127.128 # 单播指向server1
}
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
virtual_server 192.168.127.200 80 {
delay_loop 6
lb_algo wrr
lb_kind DR
#persistence_timeout 120 #会话保持时间
protocol TCP
# sorry_server 172.18.200.105 80
real_server 192.168.127.129 80 {
weight 1
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 1
connect_port 80
}
}
real_server 192.168.127.131 80 {
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
# 关闭防火墙
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
# 重新启动keepalived配置生效
[root@localhost ~]# systemctl restart keepalived
# 查看iptables规则(已经生效)
[root@localhost ~]# 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.127.128:80 wrr # 本机的vip地址的80端口接收的请求,使用wrr调度到下面的服务器
-> 192.168.127.129:80 Route 1 0 0 # 探测80端口通过的后端服务,如果不通过就踢出去
-> 192.168.127.131:80 Route 1 0 0
# 后端服务器web A和web B配置绑定vip
[root@localhost ~]# vi ipvs-dr.sh
#!/bin/bash
# LVS DR模式初始化脚本
# 2020-04-09
LVS_VIP=192.168.127.200 # 绑定vip地址
source /etc/rc.d/init.d/functions
case "$1" in
start)
/sbin/ifconfig lo:0 $LVS_VIP netmask 255.255.255.255 broadcast $LVS_VIP
/sbin/route add -host $LVS_VIP dev lo:0
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "3" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "4" > /proc/sys/net/ipv4/conf/all/arp_announce
sysctl -p > /dev/null 2>&1
echo "RralServer Start OK"
;;
stop)
/sbin/ifconfig lo:0 down
/sbin/route del $LVS_VIP > /dev/null 2>&1
echo "0" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "0" > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "0" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" > /proc/sys/net/ipv4/conf/all/arp_announce
echo "RralServer Stopcd"
;;
*)
echo "Usage: $0 {start|stop}" #start是绑定,stop是清空不在绑定
exit 1
esac
exit 0
# web A执行脚本。绑定vip地址,并查看
[root@localhost ~]# bash ipvs-dr.sh start
RralServer Start OK
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.129 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::c513:18bd:6548:58e7 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:dc:47:29 txqueuelen 1000 (Ethernet)
RX packets 40052 bytes 45115448 (43.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 12963 bytes 1183545 (1.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 202 bytes 17553 (17.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 202 bytes 17553 (17.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo:0: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 192.168.127.200 netmask 255.255.255.255 # 可以看到已绑定vip地址
loop txqueuelen 1 (Local Loopback)
# web B执行脚本。绑定vip地址
[root@localhost ~]# bash ipvs-dr.sh start
RralServer Start OK
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.127.131 netmask 255.255.255.0 broadcast 192.168.127.255
inet6 fe80::38c1:af97:6cab:fec prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:f3:d6:d8 txqueuelen 1000 (Ethernet)
RX packets 34778 bytes 42499557 (40.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 13718 bytes 1151959 (1.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 4 bytes 352 (352.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4 bytes 352 (352.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo:0: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 192.168.127.200 netmask 255.255.255.255 # 可以看到已绑定vip地址
loop txqueuelen 1 (Local Loopback)
# 客户端访问测试(访问vip地址返回页面测试成功)
[root@localhost ~]# curl 192.168.127.200
web A
VRRP Scropt(VRRP脚本)
keepalived调用外部的辅助脚本进行资源监控(所以这个脚本需要我们自己写),并根据监控的结果状态能实现优先动态调整
vrrp_script:自定义资源监控脚本,vrrp实例根据脚本返回值进行下一步操作,脚本可被多个实例调用。track_script:调用vrrp_script定义的脚本去监控资源,定义在实例之内,调用事先定义的vrrp_script
分两步:(1) 先定义一个脚本;(2) 调用此脚本
vrrp_script <SCRIPT_NAME> { # 通过vrrp_script在全局去声明脚本
script|
OPTIONS
}
track_script { # 在虚拟路由器中调用
SCRIPT_NAME_1
SCRIPT_NAME_2
}
示例
# vrrp_script参数
vrrp_script <SCRIPT_NAME> { # 定义一个检测脚本,在global_defs 之外配置
script <STRING>|<QUOTED-STRING> # shell命令或脚本路径
interval <INTEGER> # 脚本的检测时间间隔,单位为秒,默认1秒(多长时间执行一次脚本)
timeout <INTEGER> # 超时时间
weight <INTEGER:-254..254> # 权重,监测失败后会执行权重相加,权重可以为负数即相加后降低本机权重(最重要,我们的脚本检测完之后,它这个虚拟路由器的级别调低还是调高)
fall <INTEGER> # 脚本几次失败转换为失败(通常是3次,检测失败就把它权重调整,调高或调低看自己定的策略,如果调低比backup的优先级低,buckup角色提升为master,就会把vip迁移过去)
rise <INTEGER> # 脚本连续监测成功后,把服务器从失败标记为成功的次数(如果成功,还会把之前检测失败调整的权重调整回来)
user USERNAME [GROUPNAME] # 执行监测的用户或组
init_fail # 设置默认标记为失败状态,监测成功之后再转换为成功状态(初始状态,就是检测失败状态)
}
示例:
示例
# server1和server2备份keepalived配置文件,并删除掉 virtual_server
[root@localhost ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
# server1配置keepalived
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
unicast_src_ip 192.168.127.128
unicast_peer {
192.168.127.130
}
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
unicast_src_ip 192.168.127.128
unicast_peer {
192.168.127.130
}
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
# server2配置keepalived
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 80
advert_int 1
unicast_src_ip 192.168.127.130
unicast_peer {
192.168.127.128
}
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 80
advert_int 1
unicast_src_ip 192.168.127.130
unicast_peer {
192.168.127.128
}
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
192.168.127.200 dev ens33 label ens33:0
192.168.127.100 dev ens33 label ens33:1
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
# 基于互联⽹第三方包在server1和server2上在线安装HAproxy
[root@localhost ~]# wget https://repo.ius.io/ius-release-el7.rpm
## 安装使用yum解决epel源的依赖关系
[root@localhost ~]# yum -y localinstall ius-release-el7.rpm
## 安装haproxy
[root@localhost ~]# yum -y --enablerepo=ius-testing install haproxy22
## haproxy的配置文件已经生成
[root@localhost ~]# vi /etc/haproxy/haproxy.cfg
bind *:5000 # 他会监听在5000端口,启动以下试试
## 启动haproxy(5000端口已监听)
[root@localhost ~]# systemctl restart haproxy
[root@localhost ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 *:5000 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
## 编辑配置文件(删掉除了global和defaults别的定义,定义一个listen)
[root@localhost ~]# vi /etc/haproxy/haproxy.cfg
listen web_port
bind 192.168.127.200:80 # 让它监听到vip上,绑定到80端口
mode http
log global
server webA 192.168.127.129:80 check inter 3000 fall 2 rise 5 # 后端服务器
server webB 192.168.127.131:80 check inter 3000 fall 2 rise 5 # 后端服务器
# 允许非本地地址的绑定,地址转换(server1和server2都要开启,因为master可能会发生迁移)
## 查看是否开启允许非本地地址的绑定,和允许地址转换(没有开启)
[root@localhost ~]# sysctl -a | grep ip_nonlocal_bind
net.ipv4.ip_nonlocal_bind = 0
net.ipv6.ip_nonlocal_bind = 0
[root@localhost ~]# sysctl -a | grep ip.forward
net.ipv4.ip_forward = 0
# 开启允许非本地地址的绑定
[root@localhost ~]# vi /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1
# 从文件中读取值
[root@localhost ~]# sysctl -p
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1
# server1和server2 重启keepalived和haproxy,和关闭防火墙
[root@localhost ~]# systemctl restart keepalived
[root@localhost ~]# systemctl restart haproxy
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
# server1查看haproxy是否绑定监听地址(已绑定)
[root@localhost ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 192.168.127.200:80 *:*
# server2查看haproxy是否绑定监听地址(已绑定)
[root@localhost ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 192.168.127.200:80 *:*
# 客户端方式测试(vip在哪个节点绑定,就有哪个节点的haproxy去处理我们的响应,haproxy默认使用轮询)
[root@localhost ~]# while true; do curl 192.168.127.200;sleep 0.2;done
web B
web A
web B
web A
web B
web A
web B
# 测试master节点的haproxy服务停掉是否还能访问(不可以,服务挂了)
[root@localhost ~]# systemctl stop haproxy
[root@localhost ~]# while true;do curl 192.168.127.200;sleep 0.2;done
curl: (7) Failed connect to 192.168.127.200:80; 拒绝连接
curl: (7) Failed connect to 192.168.127.200:80; 拒绝连接
curl: (7) Failed connect to 192.168.127.200:80; 拒绝连接
curl: (7) Failed connect to 192.168.127.200:80; 拒绝连接
curl: (7) Failed connect to 192.168.127.200:80; 拒绝连接
高可用HAProxy
之前的问题是如果HAProxy的服务挂了,但是keepalived什么都不知道,这个时候访问地址就访问不了了,为了避免这种情况的出现,我们有必要实现haproxy的高可用
写一个脚本来实现检测我们的进程是否存在,如果进程存在就什么都不做,如果进程不存在执行迁移
示例
# 如果没有killall名安装psmisc包,并测试
[root@localhost ~]# yum -y install psmisc
## 如果haproxy存在,killall发送信号执行成功什么也不显示
[root@localhost ~]# killall -0 haproxy
[root@localhost ~]# echo $?
0
### 如果haproxy进程不存在,会报错找不到程序
[root@localhost ~]# systemctl stop haproxy
[root@localhost ~]# killall -0 haproxy
haproxy: no process found(haproxy:未找到进程)
[root@localhost ~]# echo $?
1
# 编写脚本(通过killall -0给haproxy主进程发个信号(最好给killall写绝对路径),如果有这个主进程探测是成功的,如果没有这个主进程就探测失败)
[root@localhost ~]# which killall
/usr/bin/killall
[root@localhost ~]# vi /etc/keepalived/chk_haproxy.sh
#!/bin/bash
/usr/bin/killall -0 haproxy
# 给脚本执行权限
[root@localhost ~]# chmod a+x /etc/keepalived/chk_haproxy.sh
[root@localhost ~]# ll /etc/keepalived/chk_haproxy.sh
-rwxr-xr-x. 1 root root 40 4月 9 19:32 /etc/keepalived/chk_haproxy.sh
#编辑配置文件,声明一个脚本检测
[root@localhost ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
...
{
vrrp_script chk_haproxy {
script "/etc/keepalived/chk_haproxy.sh"
interval 1 # 间隔时间,每间隔1秒,执行一次脚本
weight -30 # 权重是降级-30(示例,比如100的权重100+(-30)=70),降级后比backup优先级低就行了
fall 3 # 如果连续3次检测失败就直接降级(测试次数不能设置太高,检测过程中会终端服务)
rise 5 # 如果连续5次都检测成功了就把权重恢复
timeout 2 # 超时时长是2秒钟,如果两秒钟之内没有任何返回就超时了,超时也失败就直接降级
}
vrrp_instance VI_1 {
...
track_script { # 在VI_1虚拟路由器中调用脚本(想对哪个虚拟路由器需要监控就在哪调用,可以调用多次)
chk_haproxy # 通过名称引用
}
}
# server1重载keepalived(server1加一个检查,一旦haproxy进程不存在后,keepalived会对haproxy进程进行检测,连续3次检测失败后,就触发chk_haproxy操作,它的操作就是降级,只要比backup的优先级低,vip就会迁移到backup改变角色状态成为master)
[root@localhost ~]# systemctl restart keepalived
# server1停止haproxy(服务器会立即迁移,但是会有服务会中断几秒)
[root@localhost ~]# systemctl stop haproxy
# server1查看日志
[root@localhost ~]# tail -f /var/log/messages
Apr 9 20:39:13 localhost Keepalived_vrrp[17328]: /etc/keepalived/chk_haproxy.sh exited with status 1 (本地主机Keepalived_vrrp [17328]:/etc/keepalived/chk_haproxy.sh退出,状态为1)
Apr 9 20:39:13 localhost Keepalived_vrrp[17328]: VRRP_Script(chk_haproxy) failed (本地主机Keepalived_vrrp [17328]:VRRP_Script(chk_haproxy)失败)
Apr 9 20:39:14 localhost Keepalived_vrrp[17328]: VRRP_Instance(VI_1) Changing effective priority from 100 to 70 (本地主机Keepalived_vrrp [17328]:VRRP_Instance(VI_1)将有效优先级从100更改为70)
Apr 9 20:39:14 localhost Keepalived_vrrp[17328]: /etc/keepalived/chk_haproxy.sh exited with status 1 (本地主机Keepalived_vrrp [17328]:/etc/keepalived/chk_haproxy.sh退出,状态为1)
Apr 9 20:39:14 localhost Keepalived_vrrp[17328]: VRRP_Instance(VI_1) Received advert with higher priority 80, ours 70 (本地主机Keepalived_vrrp [17328]:VRRP_Instance(VI_1)收到优先级为80的通告,我们的优先级为70)
Apr 9 20:39:14 localhost Keepalived_vrrp[17328]: VRRP_Instance(VI_1) Entering BACKUP STATE 本地主机Keepalived_vrrp [17328]:VRRP_Instance(VI_1)输入备份状态
Apr 9 20:39:14 localhost Keepalived_vrrp[17328]: VRRP_Instance(VI_1) removing protocol VIPs. (本地主机Keepalived_vrrp [17328]:VRRP_Instance(VI_1)删除了协议VIP。)
Apr 9 20:39:15 localhost Keepalived_vrrp[17328]: /etc/keepalived/chk_haproxy.sh exited with status 1 (本地主机Keepalived_vrrp [17328]:/etc/keepalived/chk_haproxy.sh退出,状态为1)
Apr 9 20:39:16 localhost Keepalived_vrrp[17328]: (本地主机Keepalived_vrrp [17328]:/etc/keepalived/chk_haproxy.sh退出,状态为1)
# server1启动haproxy(server1的权重会恢复,拿回master)
[root@localhost ~]# systemctl restart haproxy
# server1查看日志
[root@localhost ~]# tail -f /var/log/messages
9 20:56:57 localhost systemd: Starting HAProxy Load Balancer... (正在启动HAProxy负载均衡器...)
Apr 9 20:56:57 localhost haproxy: [NOTICE] 098/205657 (21493) : New worker #1 (21498) forked (本地主机haproxy:[通知] 098/205657(21493):分叉了新工人#1(21498))
Apr 9 20:56:57 localhost systemd: Started HAProxy Load Balancer. (启动了HAProxy负载均衡器。)
Apr 9 20:57:02 localhost Keepalived_vrrp[17328]: VRRP_Script(chk_haproxy) succeeded (本地主机Keepalived_vrrp [17328]:VRRP_Script(chk_haproxy)成功)
Apr 9 20:57:03 localhost Keepalived_vrrp[17328]: VRRP_Instance(VI_1) Changing effective priority from 70 to 100 (本地主机Keepalived_vrrp [17328]:VRRP_Instance(VI_1)将有效优先级从70更改为100)
Apr 9 20:57:03 localhost Keepalived_vrrp[17328]: VRRP_Instance(VI_1) forcing a new MASTER election (本地主机Keepalived_vrrp [17328]:VRRP_Instance(VI_1)强制进行新的MASTER选举)
Apr 9 20:57:04 localhost Keepalived_vrrp[17328]: VRRP_Instance(VI_1) Transition to MASTER STATE (本地主机Keepalived_vrrp [17328]:VRRP_Instance(VI_1)转换为MASTER STATE)
Apr 9 20:57:05 localhost Keepalived_vrrp[17328]: VRRP_Instance(VI_1) Entering MASTER STATE (本地主机Keepalived_vrrp [17328]:VRRP_Instance(VI_1)进入MASTER STATE)
Apr 9 20:57:05 localhost Keepalived_vrrp[17328]: VRRP_Instance(VI_1) setting protocol VIPs. (本地主机Keepalived_vrrp [17328]:VRRP_Instance(VI_1)设置协议VIP。)
Apr 9 20:57:05 localhost Keepalived_vrrp[17328]: Sending gratuitous ARP on ens33 for 192.168.127.200 (本地主机Keepalived_vrrp [17328]:在ens33上为192.168.127.200发送免费ARP)
Apr 9 20:57:05 localhost Keepalived_vrrp[17328]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.127.200 (本地主机Keepalived_vrrp [17328]:VRRP_Instance(VI_1)在ens33上为192.168.127.200发送/排队免费ARP)
Apr 9 20:57:05 localhost Keepalived_vrrp[17328]: Sending gratuitous ARP on ens33 for 192.168.127.100 (本地主机Keepalived_vrrp [17328]:在ens33上为192.168.127.100发送免费ARP)
Apr 9 20:57:05 localhost Keepalived_vrrp[17328]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.127.100 (本地主机Keepalived_vrrp [17328]:VRRP_Instance(VI_1)在ens33上为192.168.127.100发送/排队免费ARP)
高可用Nginx
同haproxy的高可用原理一样,改吧改吧名字
示例
vrrp_script chk_nginx {
script "/etc/keepalived/chk_nginx.sh"
interval 1
weight -80
fall 3
rise 5
timeout 2
}
track_script {
chk_haproxy
}
[root@s1 ~]# yum install psmisc -y
[root@s1 ~]# cat /etc/keepalived/chk_nginx.sh
#!/bin/bash
/usr/bin/killall -0 nginx
[root@s1 ~]# chmod a+x /etc/keepalived/chk_nginx.sh
基于仲裁盘的高可用
当存在此仲裁设备时,发生故障迁移,适用场景:在backup服务器探测文件是否存在,当master运行正常的时候没有此文件,当master异常的时候生成此文件,然后将backup服务器的优先级设置高于master,从而将VIP接管到backup服务器。
示例
# nfsserver安装nfs(做一个共享存储,挂载server1和server2上,正常是挂载到第三方服务器上,有第三方服务器去检测你的url,你但你的url不能访问,就生成一个down文件,通常我们前面使用killall命令探测进程是否存在,这种比较简单)
[root@localhost ~]# yum -y install nfs-utils
# 创建 一个目录共享一下
[root@localhost ~]# mkdir -pv /data/downs
mkdir: 已创建目录 "/data"
mkdir: 已创建目录 "/data/downs"
# 编辑配置文件
[root@localhost ~]# vi /etc/exports
/data/downs *(rw,no_root_squash)
## /data/down目录,*表示共享给所有人用,rw表示权限读写,no_root_squash表示不做全局映射,谁创建的文件就是谁的(授权和权限之间不能用空格,如果有空格相当于没有生效,可以启动挂载,但是不能创建文件)
# 启动nfs
[root@localhost ~]# systemctl enable --now nfs
# 关闭防火墙
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
# server2安装nfs-utils工具,并检查共享
[root@localhost ~]# yum -y install nfs-utils
[root@localhost ~]# showmount -e 192.168.127.132
Export list for 192.168.127.132:
/data/downs *
# server2创建目录(用于挂载存储)
[root@localhost mnt]# mkdir -pv /etc/keepalived/device
mkdir: 已创建目录 "/etc/keepalived/device
# server2挂载nfs,并查看
[root@localhost ~]# mount -t nfs 192.168.127.132:/data/downs /etc/keepalived/device
[root@localhost /]# df -TH
192.168.127.132:/data/downs nfs4 20G 1.2G 19G 6% /etc/keepalived/device
server1创建目录(用于挂载存储)
[root@localhost mnt]# mkdir -pv /etc/keepalived/device
mkdir: 已创建目录 "/etc/keepalived/device
# server1挂载nfs,并查看
[root@localhost ~]# mount -t nfs 192.168.127.132:/data/downs /etc/keepalived/device
[root@localhost /]# df -TH
192.168.127.132:/data/downs nfs4 20G 1.2G 19G 6% /etc/keepalived/device
#server1 创建文件测试(创建成功)
[root@localhost mnt]# touch /etc/keepalived/device/index.html
[root@localhost mnt]# ll /etc/keepalived/device、
总用量 0
-rw-r--r--. 1 root root 0 4月 9 21:33 index.html
# 编辑配置文件,写脚本(判断挂载的目录下有没有down文件)
[root@localhost /]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
...
{
vrrp_script chk_down {
script "/bin/bash -c '[[ -f /etc/keepalived/device/down ]]' && exit 0 || exit 7" # 成功退出为0(可以写脚本,这里为了省事就把命令写这了,检测/etc/keepalived/device/down这个文件是否存在,如果是命令执行成功,执行成功返回0,所以0就表示成功,否者就返回7)
interval 1 # 间隔时间,每间隔1秒,执行一次脚本
weight +80 # 权重是降级+80,加了之后就比master高了
fall 1 # 如果连续1次检测失败(都有down文件,表示master挂了)执行weight(80+(80)=160就比master高了)
rise 5 # 如果连续1次都检测成功了(没有down,表示master恢复了)就把权重恢复
timeout 2 # 超时时长是2秒钟,如果两秒钟之内没有任何返回就超时了,超时也失败就直接降级
}
vrrp_instance VI_1 {
...
track_script { # 在VI_1虚拟路由器中调用脚本(想对哪个虚拟路由器需要监控就在哪调用,可以调用多次)(注意参数和花括号中需要有空格,否者不生效)
chk_down # 通过名称引用
}
}
# server2重启keepalived配置生效
[root@localhost ~]# systemctl restart keepalived
# server1创建一个down文件测试,vip是否迁移(这个文件可以通过脚本检查程序状态进行创建,这里手动创建了)
[root@localhost /]# touch /etc/keepalived/device/down
[root@localhost /]# ll /etc/keepalived/device/
总用量 0
-rw-r--r--. 1 root root 0 4月 9 22:22 down
# 查看server2日志(查看vip迁移过程)
[root@localhost ~]# tail -f /var/log/messages
Apr 9 22:26:43 localhost Keepalived_vrrp[22538]: /bin/bash -c '[[ -f /etc/keepalived/device/down ]]' && exit 0 || exit 7 exited with status 7 (本地主机Keepalived_vrrp [22538]:/ bin / bash -c'[[-f / etc / keepalived / device / down]]'&&退出0 ||出口7以状态7退出,状态检测文件一直不存在,返回7,此检测在日志中可以看到1秒钟执行一次)
Apr 9 22:26:48 localhost Keepalived_vrrp[22538]: VRRP_Script(chk_down) succeeded (本地主机Keepalived_vrrp [22538]:VRRP_Script(chk_down)成功,检测到down文件,执行成功,返回0,也说明master节点挂了,vip要进行迁移)
Apr 9 22:26:49 localhost Keepalived_vrrp[22538]: VRRP_Instance(VI_1) Changing effective priority from 80 to 160 (本地主机Keepalived_vrrp [22538]:VRRP_Instance(VI_1)将有效优先级从80更改为160)
Apr 9 22:26:50 localhost Keepalived_vrrp[22538]: VRRP_Instance(VI_1) forcing a new MASTER election (本地主机Keepalived_vrrp [22538]:VRRP_Instance(VI_1)强制进行新的MASTER选举)
Apr 9 22:26:51 localhost Keepalived_vrrp[22538]: VRRP_Instance(VI_1) Transition to MASTER STATE (本地主机Keepalived_vrrp [22538]:VRRP_Instance(VI_1)转换为MASTER STATE)
Apr 9 22:26:52 localhost Keepalived_vrrp[22538]: VRRP_Instance(VI_1) Entering MASTER STATE (本地主机Keepalived_vrrp [22538]:VRRP_Instance(VI_1)进入MASTER STATE)
Apr 9 22:26:52 localhost Keepalived_vrrp[22538]: VRRP_Instance(VI_1) setting protocol VIPs. (本地主机Keepalived_vrrp [22538]:VRRP_Instance(VI_1)设置协议VIP。)
Apr 9 22:26:52 localhost Keepalived_vrrp[22538]: Sending gratuitous ARP on ens33 for 192.168.127.200 (本地主机Keepalived_vrrp [22538]:在ens33上为192.168.127.200发送免费ARP)
Apr 9 22:26:52 localhost Keepalived_vrrp[22538]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.127.200 (本地主机Keepalived_vrrp [22538]:VRRP_Instance(VI_1)在ens33上为192.168.127.200发送/排队免费ARP)
Apr 9 22:26:52 localhost Keepalived_vrrp[22538]: Sending gratuitous ARP on ens33 for 192.168.127.100 (本地主机Keepalived_vrrp [22538]:在ens33上为192.168.127.100发送免费ARP)
Apr 9 22:26:52 localhost Keepalived_vrrp[22538]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.127.100 (本地主机Keepalived_vrrp [22538]:VRRP_Instance(VI_1)在ens33上为192.168.127.100发送/排队免费ARP)

浙公网安备 33010602011771号