前面在说LNMT架构的时候,在最后留了一个疑问,就是我们的单台Nginx做负载均衡的时候出现故障的话,我们整个架构就会瘫痪,这显然是不被允许的。因此我们就需要给Nginx做高可用部署,keepalived就是今天的主角。
keepalived是集群管理中保证集群高可用的一个服务软件,用来防止单点故障。它可以自动检测集群中服务器的健康状况,比如主从模式时,当主服务器发生故障时,Keepalived会根据服务器的VRRP优先级来选举一个从服务器成为主服务器,实现主从的无缝切换,保证持续的提供服务,并且Keepalived也会及时的通过邮件通知到相关负责人进行维护出现问题的服务器。 Keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP功能。因此,Keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx、Haproxy、MySQL等)的高可用解决方案软件。
Keepalived软件主要是通过VRRP协议实现高可用功能的。VRRP是Virtual Router Redundancy Protocol(虚拟路由器冗余协议)的缩写,VRRP出现的目的就是为了解决静态路由单点故障问题的,它能够保证当个别节点宕机时,整个网络可以不间断地运行。所以,Keepalived一方面具有配置管理LVS的功能,同时还具有对LVS下面节点进行健康检查的功能,另一方面也可实现系统网络服务的高可用功能。(因此Keepalived在给Nginx,Haproxy做高可用的时候,仅仅 只是用了keepalived的VRRP协议。)
keepalived是以VRRP协议为实现基础的,VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议。虚拟路由冗余协议,可以认为是实现路由器高可用的协议,即将N台提供相同功能的路由器组成一个路由器组,这个组里面有一个master和多个backup,master上面有一个对外提供服务的vip(该路由器所在局域网内其他机器的默认路由为该vip),master会发组播,当backup收不到vrrp包时就认为master宕掉了,这时就需要根据VRRP的优先级来选举一个backup当master。这样的话就可以保证路由器的高可用了。
LNMT的架构中,Nginx负载均衡服务器可用理解为这里所说的路由器。
Layer3,4,&5工作在IP/TCP协议栈的网络层,传输层,及应用层。
网络层:Keepalived通过ICMP协议向服务器集群中的每一个节点发送一个ICMP数据包(有点类似与Ping的功能),如果某个节点没有返回响应数据包,那么认为该节点发生了故障,Keepalived将报告这个节点失效,并从服务器集群中剔除故障节点。
传输层:Keepalived在传输层里利用了TCP协议的端口连接和扫描技术来判断集群节点的端口是否正常,比如对于常见的WEB服务器80端口。或者SSH服务22端口,Keepalived一旦在传输层探测到这些端口号没有数据响应和数据返回,就认为这些端口发生异常,然后强制将这些端口所对应的节点从服务器集群中剔除掉。
应用层:,Keepalived的运行方式也更加全面化和复杂化,用户可以通过自定义Keepalived工作方式,例如:可以通过编写程序或者脚本来运行Keepalived,而Keepalived将根据用户的设定参数检测各种程序或者服务是否允许正常,如果Keepalived的检测结果和用户设定的不一致时,Keepalived将把对应的服务器从服务器集群中剔除。
keepalived主要有三个模块,分别是core、check和vrrp。
(1)core模块为keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析(2)check负责健康检查,包括常见的各种检查方式。
(3)vrrp模块是来实现VRRP协议的。
root@nginx:~#sudo apt install -y keepalived
root@nginx:~#
安装完keepalived之后我们可以通过dpkg -L keepalived查看有哪些keepalived的相关文件和目录,在/usr/share/doc/keepalived/samples/下有很多配置模板。我们可以将模板直接负载到/etc/keepalived下面,重命名为.conf结尾的配置文件。
/etc/keepalived ##配置文件目录,配置文件需要以.conf结尾
/usr/sbin/keepalived ##keepalived的bin文件
/lib/systemd/system/keepalived.service ##system管理文件
/var/log/syslog|message ## 日志文件
/usr/share/doc/keepalived/samples ##配置模板所在目录(存在大量模板,基本满足日常定义)
配置文件分为三个部分:全局配置(global_defs);VRRP配置;LVS配置。
global_defs {
notification_email { #故障发生时给谁发邮件通知
[email protected]
[email protected]
[email protected]
}
notification_email_from [email protected] ##通知邮件从哪个地址发出
smtp_server 192.168.200.1 ##通知邮件的smtp地址。
smtp_connect_timeout 30 ##连接smtp服务器的超时时间
router_id LVS_DEVEL #标识这台机器ID,默认情况下是主机名,可以配置成主机名
vrrp_skip_check_adv_addr #所有报文都检查比较消耗性能,此配置为如果收到的报文和上一个报文是同一个路由器则跳过检查报文中的源地址
vrrp_strict #严格遵守VRRP协议,不允许状况:1,没有VIP地址,2.配置了单播邻居,3.在VRRP版本2中有IPv6地址
vrrp_garp_interval 0 #ARP报文发送延迟
vrrp_gna_interval 0 #消息发送延迟
#vrrp_mcast_group4 224.0.0.18 #指定组播IP地址,默认值:224.0.0.18 范围:224.0.0.0到239.255.255.255
#vrrp_iptables #避免生成iptables input链 规则,sip any 拒绝 dip any
}
vrrp_script chk_nginx_server {
script "/etc/keepalived/chk_nginx.sh "
interval 1
weight -2
}
vrrp_instance VI_1 { #虚拟路由器名称,在一个keepalived可以启多个虚拟路由器,每个虚拟路由器的名字都不一样
state MASTER #当前节点在此虚拟路由器上的初始状态,状态为MASTER或者BACKUP,一般都是配置backup,该值无法决定身份,最终还是通过比较priority
interface eth0 #绑定为当前虚拟路由器使用的物理接口,如:ens32,eth0,bond0,br0
virtual_router_id 51 #每个虚拟路由器惟一标识,范围:0-255,同一组虚拟路由器的vrid必须一致
priority 100 #当前物理节点在此虚拟路由器的优先级,范围:1-254,每个keepalived主机节点此值不同
advert_int 1 #vrrp通告的时间间隔,默认1s
nopreempt #当master宕机恢复之后不抢占master
authentication { #认证机制
auth_type PASS #AH(不推荐)或PASS
auth_pass 1111 #预共享密钥,仅前8位有效,同一个虚拟路由器的多个keepalived节点必须一样
}
virtual_ipaddress { #虚拟IP
10.0.0.100 #指定VIP,不指定网卡,默认为eth0,注意:不指定/prefix,默认为/32
10.0.0.101/24 dev eth1 #指定VIP的网卡
10.0.0.102/24 dev eth2 label eth2:1 #指定VIP的网卡label
}
track_script {
chk_nginx_server
}
}
注意:
1. nopreempt:当master宕机之后,原先的backup会升级成master,配置该参数之后原先的master即使恢复了,也不会抢占现在的master(该参数需要准备都配置为backup的时候才生效)。
2. vrrp_script: 配置块是用来定义检测脚本的。
vrrp_script { #定义一个检测脚本,在global_defs之外配置
script | #shell命令或脚本路径
interval #间隔时间,单位为秒,默认1秒
timeout #超时时间
weight #此值为负数,表示fall((脚本返回值为非0)时,会将此值与本节点权重相加可以降低本节点权重,如果是正数,表示 rise (脚本返回值为0)成功后,会将此值与本节点权重相加可以提高本节点权重,通常使用负值较多
fall #脚本几次失败转换为失败,建议设为2以上
rise #脚本连续监测成功后,把服务器从失败标记为成功的次数
user USERNAME [GROUPNAME] #执行监测脚本的用户或组
init_fail #设置默认标记为失败状态,监测成功之后再转换为成功状态
}
###调用脚本
vrrp_instance VI_1 {
…
track_script {
script_name
}
}
virtual_server 10.0.0.100 80 { #定义虚拟主机IP地址及其端口
delay_loop 6 #检查后端服务器的时间间隔
lb_algo wrr #定义调度方法,可选rr|wrr|lc|wlc|lblc|sh|dh
lb_kind DR #集群的类型,注意要大写,可选NAT|DR|TUN
#persistence_timeout 20 #持久连接时长,LVS在多少时间内没有与后端服务进行数据传输,就会断开
protocol TCP #指定服务协议,可选TCP|UDP|SCTP
sorry_server 10.0.0.101 80 #所有RS故障时,备用服务器地址(报错服务器)
real_server 10.0.0.11 80 { #RS的IP和PORT
weight 1 #RS权重
notify_up | #RS上线通知脚本
notify_down | #RS下线通知脚本
HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK { #定义当前主机的健康状态 检测方法
...
}
}
}
注意:
1. HTTP_GET|SSL_GET : 用于应用层检测。
2. TCP_CHECK|SMTP_CHECK|MISC_CHECK: 用于传输层检测。
HTTP_GET|SSL_GET(Nginx,Tomcat)检测:
HTTP_GET|SSL_GET {
url {
path #定义要监控的URL
status_code #判断上述检测机制为健康状态的响应码,一般为 200
}
connect_timeout #客户端请求的超时时长, 相当于haproxy的timeout server,多久连接不上就报错
nb_get_retry #重试次数
delay_before_retry #重试之前的延迟时长
connect_ip #向当前RS哪个IP地址发起健康状态检测请求
connect_port #向当前RS的哪个PORT发起健康状态检测请求
bindto #向当前RS发出健康状态检测请求时使用的源地址
bind_port #向当前RS发出健康状态检测请求时使用的源端口
}
## 示例
! Configuration File for keepalived
global_defs {
notification_email {
acassen
}
notification_email_from [email protected]
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
virtual_server 192.168.200.100 443 {
delay_loop 6
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
real_server 192.168.201.100 443 {
weight 1
SSL_GET {
url {
path /
digest ff20ad2481f97b1754ef3e12ecd3a9cc
}
connect_port 444
connect_timeout 3
retry 3
delay_before_retry 3
}
}
}
TCP_CHECK|SMTP_CHECK|MISC_CHECK:
TCP_CHECK {
connect_timeout #客户端请求的超时时长, 相当于haproxy的timeout server,多久连接不上就报错
nb_get_retry #重试次数
delay_before_retry #重试之前的延迟时长
connect_ip #向当前RS哪个IP地址发起健康状态检测请求,多网卡情况下
connect_port #向当前RS的哪个PORT发起健康状态检测请求
bindto #向当前RS发出健康状态检测请求时使用的源地址,多网卡情况下
bind_port #向当前RS发出健康状态检测请求时使用的源端口
}
###示例:
! Configuration File for keepalived
! This example demonstrates MISC_CHECK, a component of LVS configuration.
global_defs {
notification_email {
acassen
}
notification_email_from [email protected]
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
virtual_server 10.10.10.2 1358 {
delay_loop 6
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
real_server 192.168.200.6 1358 {
weight 1
MISC_CHECK {
misc_path /usr/local/bin/script.sh
! misc_dynamic
}
}
}
配置示例在/usr/share/doc/keepalived/samples目录下
## 全局
global_defs {
...
}
##检测脚本定义
vrrp_script chkha {
...
}
## vrrp配置块
vrrp_instance VI_1 {
...
调用检测脚本
track_script {
chkha
}
}
###LVS配置快
virtual_server 10.0.0.100 80 {
....
real_server 10.0.0.11 80 {
....
HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK {
...
}
}
}