
keepalived 依赖包包括gcc、openssl-devel、libnl3-devel和net-snmp-devel四个。

keepalived源码可通过官网下载(下载选择界面:https://www.keepalived.org/download.html),笔者选择的是2.2.4版本,下载完毕解压至指定文件夹。


进入到解压目录后,执行configure脚本生成Makefile文件,keepalived执行configure脚本时不用添加太多的选项,直接指定安装目录,同时要记得加上--disable-fwmark选项禁止生成iptables规则,否则安装完成后会自动生成iptables规则导致VIP无法访问。如果是通过yum安装的keepalived服务,也要将配置文件中的vrrp_strict一行注释掉。

生成Makefile文件后,执行make && make install命令进行编译和安装。

编译安装完成后,可通过-v选项查看keepalived版本信息,包括编译参数、配置文件参数和系统参数等。

多数服务在编译安装后都要手动创建或者拷贝生成service文件,而keepalived编译安装完成后会自动生成。

更多关于企业集群运维管理系列的学习文章,请参阅:玩转企业集群运维管理专栏,本系列持续更新中。
在安装环节,安装路径下的etc/keepalived/目录中有个自动生成的keepalived.conf配置文件,可以直接拷贝到按指定要求创建的/etc/keepalived/目录下作为服务配置文件。

此时我们已经可以成功启动keepalived服务,查看状态也是显示running的。

查看主机ip时会发现多出了三个地址,即配置文件中默认添加的三个VIP地址,而且也能ping通。如果是执行configure脚本环节未添加--disable-fwmark选项,或者yum安装未注释配置文件中vrrp_strict一行是无法ping通的。在部分Linux主机中,即使修改配置文件并重启服务也无法ping通,需要执行killall keepalived命令杀死进程后重新启动服务。

生产环境使用Keepalived正常运行,共启动3个进程,一个是父进程,负责监控其子进程,一个是VRRP子进程,另外一个是Checkers子进程。
两个子进程都被系统Watchlog看管,两个子进程各自负责自己的事,Healthcheck子进程检查各自服务器的健康状况,如果Healthcheck进程检查到Master上服务不可用了,就会通知本机上的VRRP子进程,让他删除通告,并且去掉虚拟IP,转换为BACKUP状态。
[root@localhost ~]# ps -ef | grep keepalived | grep -v grep
root 16074 1 0 08:37 ? 00:00:00 /usr/sbin/keepalived -D
root 16075 16074 0 08:37 ? 00:00:00 /usr/sbin/keepalived -D
root 16076 16074 0 08:37 ? 00:00:04 /usr/sbin/keepalived -D
keepalived配置文件为/etc/keepalived/keepalived.conf,主要由global_defs、vrrp_instance和virtual_server三个模块构成。
global_defs模块为keepalived全局配置模块,它包括以下内容:
notification_email #可添加keepalived发生切换故障时发送邮件所对应的邮箱,可以分行添加多个邮箱;
notification_email_from #可添加发送邮件的地址;
smtp_server #可添加邮件服务器地址;
smtp_connect_timeout #可设置邮件服务器连接超时时长;
router_id #每个keepalived节点的唯一标识,建议设置为当前主机名,并且多个节点重名时是不受影响的;
vrrp_skip_check_adv_addr #keepalived会以对所有通告报文都进行检查,进而比较消耗性能,启用此配置后,如果收到的通告报文和上一个报文是同一个路由器则跳过检查,默认值为全检查;
vrrp_strict #表示严格遵守VRRP协议,启用此项后以下状况将无法启动服务。
a. 未设置VIP地址
b. 配置了单播邻居
c. 在VRRP的2版本中带有IPV6地址,如果开启了此项后没有设置vrrp_iptables则会自动开启iptables防火墙规则,导致VIP地址无法访问,建议不加此项
vrrp_garp_interval #可设置ARP接口之间发送免费报文的延迟时间,可以精确到毫秒,默认是0;
vrrp_gna_interval #设置非请求消息的发送延迟时间,默认为0;
vrrp_mcast_group4 #可指定组播IP范围,可选择224.0.0.0到239.255.255.255之间的地址,默认为224.0.0.18;
vrrp_iptables #与vrrp_strict同时设置时可禁止iptables规则的生成,注释或者无vrrp_strict时可不加此项。

vrrp_instance模块可配置虚拟路由器,它包含以下内容:
vrrp_instance #模块后面的STRING为VRRP的实例名,一般设置为业务名称;
state #可设置此虚拟路由器的初始状态,可选择MASTER或者BACKUP;
interface #可以绑定当前虚拟路由器所使用的物理接口,如eth0、bond0和br0等,可以和VIP地址不在同一张网卡上;
virtual_router_id #可设置每个虚拟路由器的唯一标识,取值范围为0-255,每个虚拟路由器的该项值必须是唯一的,否则无法启动服务,并且同属一个虚拟路由器的多个keepalived节点必须相同,务必要确认在同一网络中此值必须唯一;
priority #可设置当前物理节点在此虚拟路由器中的优先级,优先级取值范围为1-254,值越大优先级越高,每个keepalived节点取值不同;
advert_int #可设置VRRP通告的时间间隔,默认为1秒;
authentication #可设置认证机制,由以下两部分构成。
a. auth_type为认证类型,可选择AH和PASS两种,AH为IPSC互联网安全协议认证,PASS为简单密码认证,推荐PASS认证
b. auth_pass为预共享秘钥设置,仅前8位有效,同一虚拟路由器的多个keepalived节点auth_pass值必须保持一致
virtual_ipaddress #可添加虚拟路由器的VIP,并可设置VIP对应的子网掩码、网卡和标签等,生产中可能会在同一个虚拟路由器上添加上百个VIP,不同的VIP分行隔开,不指定网卡时默认添加在eth0上,不设置子网掩码时默认为32位。在添加VIP地址时,需确保将要使用的VIP不存在,即还没被使用。


virtual_server模块用于虚拟服务器配置,将虚拟路由器中添加的VIP与后端real server对应起来,该模块包括以下内容:
virtual_server #后面需要跟上VIP地址和端口,即客户端是通过哪一个VIP和哪个端口向后端服务器发起访问;
delay_loop #检查后端服务器的时间间隔;
lb_algo #可定义调度算法,如rr、wrr、lc、wlc、lblc、sh和dh等;
lb_kind #可定义集群的类型,如NAT、DR和TUN,注意要使用大写;
persistence_timeout #可设置持久连接时长;
protocol #可指定服务协议,如TCP、UDP和SCTP,一般使用TCP;
sorry_server #可设置当所有后端服务器都不可用时的备用服务器地址;
real_server #设置VIP所对应的后端服务器IP和端口,包括以下构成部分——
a. weight可以设置对应后端服务器的权重
b. SSL_GET、HTTP_GET、TCP_CHECK、SMTP_CHECK和MISC_CHECK等可以定义当前后端主机的健康状况检查方法
c. connect_timeout表示客户端连接超时时长
d. nb_get_retry表示重试次数
e. delay_before_retry表示重试之前的延迟时长


更多关于企业集群运维管理系列的学习文章,请参阅:玩转企业集群运维管理专栏,本系列持续更新中。
主192.168.179.102
[root@localhost ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id real-server1-nginx
script_user root
enable_script_security
}
vrrp_script chk_nginx {
script "/data/shell/check_nginx_status.sh"
interval 2
}
vrrp_instance VI_1 {
state MASTER
interface ens32
virtual_router_id 151
priority 100
advert_int 5
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.179.199
}
track_script {
chk_nginx
}
}
[root@localhost ~]# nginx
[root@localhost ~]# systemctl start keepalived
[root@localhost ~]# ip a | grep 199
inet 192.168.179.199/32 scope global ens32
日志/var/log/message
Nov 19 10:51:17 localhost Keepalived_vrrp[45924]: VRRP_Script(chk_nginx) succeeded
Nov 19 10:51:22 localhost Keepalived_vrrp[45924]: VRRP_Instance(VI_1) Transition to MASTER STATE
Nov 19 10:51:27 localhost Keepalived_vrrp[45924]: VRRP_Instance(VI_1) Entering MASTER STATE
Nov 19 10:51:27 localhost Keepalived_vrrp[45924]: VRRP_Instance(VI_1) setting protocol VIPs.
Nov 19 10:51:27 localhost Keepalived_vrrp[45924]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 10:51:27 localhost Keepalived_vrrp[45924]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens32 for 192.168.179.199
备 192.168.179.103 只需要修改两个地方,state BACKUP priority 80
[root@localhost ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id real-server2-nginx
script_user root
enable_script_security
}
vrrp_script chk_nginx {
script "/data/shell/check_nginx_status.sh"
interval 2
}
vrrp_instance VI_1 {
state BACKUP
interface ens32
virtual_router_id 151
priority 50
advert_int 5
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.179.199
}
track_script {
chk_nginx
}
}
[root@localhost ~]# nginx
[root@localhost ~]# systemctl start keepalived
日志如下:
Nov 19 11:00:29 localhost Keepalived[7824]: Opening file '/etc/keepalived/keepalived.conf'.
Nov 19 11:00:29 localhost Keepalived[7825]: Starting Healthcheck child process, pid=7826
Nov 19 11:00:29 localhost Keepalived[7825]: Starting VRRP child process, pid=7827
Nov 19 11:00:29 localhost systemd: Started LVS and VRRP High Availability Monitor.
Nov 19 11:00:29 localhost Keepalived_healthcheckers[7826]: Opening file '/etc/keepalived/keepalived.conf'.
Nov 19 11:00:29 localhost Keepalived_vrrp[7827]: Registering Kernel netlink reflector
Nov 19 11:00:29 localhost Keepalived_vrrp[7827]: Registering Kernel netlink command channel
Nov 19 11:00:29 localhost Keepalived_vrrp[7827]: Registering gratuitous ARP shared channel
Nov 19 11:00:29 localhost Keepalived_vrrp[7827]: Opening file '/etc/keepalived/keepalived.conf'.
Nov 19 11:00:29 localhost Keepalived_vrrp[7827]: VRRP_Instance(VI_1) removing protocol VIPs.
Nov 19 11:00:29 localhost Keepalived_vrrp[7827]: Using LinkWatch kernel netlink reflector...
Nov 19 11:00:29 localhost Keepalived_vrrp[7827]: VRRP_Instance(VI_1) Entering BACKUP STATE
Nov 19 11:00:29 localhost Keepalived_vrrp[7827]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)]
Nov 19 11:00:29 localhost Keepalived_vrrp[7827]: VRRP_Script(chk_nginx) succeeded
Nov 19 11:01:02 localhost systemd: Started Session 12 of user root.
Nov 19 11:01:02 localhost systemd: Starting Session 12 of user root.
现在两台配置keepalived算基本配置完毕,只有当backup收不到master的主播包以后才会进行切换,现在master和backup就变成VRRP集群了。(注意这个和nginx没有半毛钱关系,这个高可用是对主机做的,只不过用户访问nginx不是通过宿主机IP去访问nginx,而是通过VIP去访问nginx)。
master直接把nginx干掉
[root@localhost ~]# pkill nginx
日志如下
Nov 19 11:04:59 localhost Keepalived[45922]: Stopping
Nov 19 11:04:59 localhost systemd: Stopping LVS and VRRP High Availability Monitor...
Nov 19 11:04:59 localhost Keepalived_vrrp[45924]: VRRP_Instance(VI_1) sent 0 priority
Nov 19 11:04:59 localhost Keepalived_vrrp[45924]: VRRP_Instance(VI_1) removing protocol VIPs.
Nov 19 11:04:59 localhost Keepalived_healthcheckers[45923]: Stopped
Nov 19 11:05:00 localhost Keepalived_vrrp[45924]: Stopped
backup观察现象
#backup日志
Nov 19 11:05:00 localhost Keepalived_vrrp[7827]: VRRP_Instance(VI_1) Transition to MASTER STATE
Nov 19 11:05:05 localhost Keepalived_vrrp[7827]: VRRP_Instance(VI_1) Entering MASTER STATE
Nov 19 11:05:05 localhost Keepalived_vrrp[7827]: VRRP_Instance(VI_1) setting protocol VIPs.
Nov 19 11:05:05 localhost Keepalived_vrrp[7827]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:05:05 localhost Keepalived_vrrp[7827]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens32 for 192.168.179.199
Nov 19 11:05:05 localhost Keepalived_vrrp[7827]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:05:05 localhost Keepalived_vrrp[7827]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:05:05 localhost Keepalived_vrrp[7827]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:05:05 localhost Keepalived_vrrp[7827]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:05:10 localhost Keepalived_vrrp[7827]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:05:10 localhost Keepalived_vrrp[7827]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens32 for 192.168.179.199
可以看到VIP飘移到backup上面了
[root@localhost ~]# ip a | grep 199
inet 192.168.179.199/32 scope global ens32
现在将master起来
[root@localhost ~]# nginx
[root@localhost ~]# systemctl start keepalived
日志如下:
Nov 19 11:11:47 localhost Keepalived_vrrp[49324]: Opening file '/etc/keepalived/keepalived.conf'.
Nov 19 11:11:47 localhost Keepalived_vrrp[49324]: VRRP_Instance(VI_1) removing protocol VIPs.
Nov 19 11:11:47 localhost Keepalived_vrrp[49324]: Using LinkWatch kernel netlink reflector...
Nov 19 11:11:47 localhost Keepalived_vrrp[49324]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)]
Nov 19 11:11:47 localhost Keepalived_vrrp[49324]: VRRP_Script(chk_nginx) succeeded
Nov 19 11:11:50 localhost Keepalived_vrrp[49324]: VRRP_Instance(VI_1) Transition to MASTER STATE
Nov 19 11:11:55 localhost Keepalived_vrrp[49324]: VRRP_Instance(VI_1) Entering MASTER STATE
Nov 19 11:11:55 localhost Keepalived_vrrp[49324]: VRRP_Instance(VI_1) setting protocol VIPs.
Nov 19 11:11:55 localhost Keepalived_vrrp[49324]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:11:55 localhost Keepalived_vrrp[49324]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens32 for 192.168.179.199
Nov 19 11:11:55 localhost Keepalived_vrrp[49324]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:11:55 localhost Keepalived_vrrp[49324]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:11:55 localhost Keepalived_vrrp[49324]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:11:55 localhost Keepalived_vrrp[49324]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:12:00 localhost Keepalived_vrrp[49324]: Sending gratuitous ARP on ens32 for 192.168.179.199
[root@localhost ~]# ip a | grep 199
inet 192.168.179.199/32 scope global ens32
再去查看backup状态( #可以看到backup上是不存在VIP的)
Nov 19 11:05:10 localhost Keepalived_vrrp[7827]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:05:10 localhost Keepalived_vrrp[7827]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:05:10 localhost Keepalived_vrrp[7827]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:05:10 localhost Keepalived_vrrp[7827]: Sending gratuitous ARP on ens32 for 192.168.179.199
Nov 19 11:11:50 localhost Keepalived_vrrp[7827]: VRRP_Instance(VI_1) Received advert with higher priority 100, ours 50
#可以看到接收到优先级100比自己高的,自己优先级是50,自动退变为backup
Nov 19 11:11:50 localhost Keepalived_vrrp[7827]: VRRP_Instance(VI_1) Entering BACKUP STATE
Nov 19 11:11:50 localhost Keepalived_vrrp[7827]: VRRP_Instance(VI_1) removing protocol VIPs.
[root@localhost ~]# ip a | grep 199
如果你的两台nginx上面都有VIP的存在,那么就是防火墙的问题了,防火墙阻挡了。因为master收不到backup的主播(在配置配置文件的时候注意括号和空格)。
基于SHELL编程脚本一键实现Nginx高可用,主要编程思路如下:
[root@real-server2 ~]# ip a
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:a7:ff:f7 brd ff:ff:ff:ff:ff:ff
inet 192.168.179.104/24 brd 192.168.179.255 scope global ens32
valid_lft forever preferred_lft forever
inet6 fe80::831c:6df1:a633:742a/64 scope link
valid_lft forever preferred_lft forever
#为ens33网卡创建了一个子网卡接口,该子网卡的IP地址为VIP地址,为Nginx提供对外服务
[root@real-server2 ~]# ifconfig ens32:1 192.168.179.199/24
[root@real-server2 ~]# ip a
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:a7:ff:f7 brd ff:ff:ff:ff:ff:ff
inet 192.168.179.104/24 brd 192.168.179.255 scope global ens32
valid_lft forever preferred_lft forever
inet 192.168.179.199/24 brd 192.168.179.255 scope global secondary ens32:1
valid_lft forever preferred_lft forever
inet6 fe80::831c:6df1:a633:742a/64 scope link
valid_lft forever preferred_lft forever

#将子网卡接口down掉
[root@real-server2 ~]# ifconfig ens32:1 down
[root@real-server2 ~]# ip a
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:a7:ff:f7 brd ff:ff:ff:ff:ff:ff
inet 192.168.179.104/24 brd 192.168.179.255 scope global ens32
valid_lft forever preferred_lft forever
inet6 fe80::831c:6df1:a633:742a/64 scope link
valid_lft forever preferred_lft forever
[root@real-server2 ~]# cat vip.sh
#!/bin/bash
vip_addr="192.168.179.199"
while true
do
nginx_status=$(ps -ef | grep nginx | grep -v grep | wc -l)
if [ $nginx_status -ne 0 ];then
ping -c 4 $ip_addr
if [ $? -ne 0 ];then
ifconfig ens32:1 $vip_addr/24
fi
else
ifconfig ens32:1 down
fi
sleep 5s
done
[root@real-server2 ~]# nohup sh vip.sh &
[1] 49462
[root@real-server2 ~]# nohup: ignoring input and appending output to ?.ohup.out?
[root@real-server2 ~]# ip a
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:a7:ff:f7 brd ff:ff:ff:ff:ff:ff
inet 192.168.179.104/24 brd 192.168.179.255 scope global ens32
valid_lft forever preferred_lft forever
inet 192.168.179.199/24 brd 192.168.179.255 scope global secondary ens32:1
valid_lft forever preferred_lft forever
inet6 fe80::831c:6df1:a633:742a/64 scope link
valid_lft forever preferred_lft forever
#server2先运行脚本先抢到VIP,现在杀掉Nginx进程
[root@real-server2 ~]# pkill nginx
#可以看到VIP飘到了server1上面
[root@real-server1 ~]# ip a
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:61:90:c1 brd ff:ff:ff:ff:ff:ff
inet 192.168.179.103/24 brd 192.168.179.255 scope global ens32
valid_lft forever preferred_lft forever
inet 192.168.179.199/24 brd 192.168.179.255 scope global secondary ens32:1
valid_lft forever preferred_lft forever
inet6 fe80::f54d:5639:6237:2d0e/64 scope link
valid_lft forever preferred_lft forever
更多关于企业集群运维管理系列的学习文章,请参阅:玩转企业集群运维管理专栏,本系列持续更新中。
参考链接:https://blog.51cto.com/johnnyfang /5419017 https://blog.csdn.net/qq_34556414 /article/details/109803454 https://blog.csdn.net /qq_34556414/article/details/107669979