摘要
一、LVS-HA
1.1 HA与keepalived
上述演示中,不管是lvs-nat还是lvs-nat模型,都会有2个遗留问题:
(1) 如果调度器服务器挂了,如何对调度器做高可用
(2) 如果RS中某台服务器挂了,如何对RS做集群的健探测
健康监测的方式有很多种,比如网络层可以使用icmp ping监测主机的存活状态,传输层可以使用tcp端口监测工具探测端口的可用性,比如nmap,应用层,比如可以对关键服务发起请求。
而实现高可用的方案一般有2种,一种是vrrp协议的实现,比如keepalived,一种是ais的实现方案,比如heartbeat,corosync
首先,这里以非常简单的方式描述下ais方案,首先假设这样一种场景,由多台服务器提供相同的服务,比如是httpd服务,此时集群中每台机器需要知道对方的生存状况,比如机器A持续的向其他机器发送信息表示自己存活(假如连续3次失败则会被判定为非存活状态),这种方式被称为心跳检测,但是可能会有这样一种网络原因造成的故障,A认为自己是存活的,但是信息没有成功被其他服务器接收,比如B和C都认为A是非存活状态,此时会造成分裂现象,解决这个问题需要一个仲裁方案,比如最简单的少数服从多数原则,这也是一般推荐奇数台机器构建集群的原因,有时候只有2台,可以使用比如网关服务器当观察者凑够3台也可以,总之必须有一个仲裁机制。假设此时多数的认为机器B可以当做Master向外提供服务,需要一个机制可以停止掉机器A的服务,并且剥夺他的ip使用权,最简单的方式,就是停掉A,然后在机器B上配置的接口上配置一个别名。而实际上ais的实现非常复杂,分为三层,最底层是集群事务层,还有资源管理层和资源代理层,它是一个非常完备的实现,基本上可以满足一切的高可用方案。
这里我们关注的是vrrp协议,,Virtual Redundant Routing Protocol,vrrp协议是非常老的一个协议,是一个虚拟的路由器协议,而keepalived则是vrrp协议的实现。
1.2 VRRP与keepalived
关于VRRP的协议详情可以参考华为等公司一些vrrp协议白皮书,因为vrrp协议原本就是用来做虚拟路由之类的。
VRRP中术语说明:
虚拟路由器:由一个Master路由器和多个Backup组成。主机将虚拟路由器当做默认网关。
VRID:虚拟路由器的标识
Master路由器:虚拟路由器中承担报文转发任务的路由器。
Backup路由器:Master路由器出现故障时,能够代替Master路由器工作的路由器。
虚拟IP地址:虚拟路由器的IP地址。一个虚拟路由器可以有一个或者多个IP地址
IP地址拥有者:接口IP地址和虚拟IP地址相同的路由器被称为IP地址拥有者。
虚拟MAC地址:一个虚拟路由器拥有一个虚拟MAC地址。虚拟MAC地址的格式为00-00-5E-00-01-{VRID}。通常情况下,虚拟路由器回应ARP请求使用的是虚拟MAC地址,只有虚拟路由器做特殊配置的时候,才回应接口的真实MAC地址。
优先级:VRRP根据优先级来确定虚拟路由器中每台路由器的地位。
抢占模式:在抢占模式下,如果Backup设备的优先级更高,则自己主动自己切换成Master
非抢占模式:在非抢占式模式下,只要Master设备没有出现故障,Backup设备即使随后被配置了更高的优先级,也不会成为Master设备
VRRP的工作过程:
(1) 虚拟路由器根据优先级选举Master。Master通过发送免费ARP报文,将自己的虚拟MAC地址通知给与它连接的设备或者主机,从而承担报文转发任务。
(2) Master路由器周期性发送VRRP报文,以公布其配置信息和工作状态
(3)如果Master出现故障,根据优先级从Backup中选举
(4)虚拟路由器状态切换时,Master路由器由一台设备切换为另一台,新的Master路由器只是简单地发送一个携带虚拟路由器的MAC地址和虚拟IP地址信息的免费ARP报文,这样就可以更新与它相连接的主机或者设备中的ARP相关信息。网络上的主机感知不到Master路由器已经切换为另外一个台设备
(5)Backup路由器的优先级高于Master时,根据工作方式决定是否重新选举
VRRP的工作模式
主备模式,一台Master,多台为Backup
主/主模式,其实是互为主备模式
keepalived
keepalived作为vrrp协议的实现,设计目的是为了高可用ipvs服务器,他能够在配置文件定义ipvs规则,并能对RS的健康状态进行探测;vrrp_script,vrrp_track
keepalivedz中包含多个组件:
控制组件:配置文件分析器
内存管理
IO复用
核心组件
vrrp stack
checker
ipvs wrapper
watch dog
HA集群配置的前提
(1)各节点时间同步,Centos上可以基于ntp协议,Centos7上可以是chrony
(2)确保iptables以及selinux不会阻碍;
(3)各节点之间通过主机名互相铜线,即名称解析服务器的解析结果必须和"uname -n"命令的结果一致;
(4)各个节点之root用户基于密钥认证的ssh通信;
yum -y install keepalived
同步下时间:
ntpdate time.windows.com
hwclock -w
1.3 keepalived配置文件
通过命令rpm -qc keepalived发现配置文件只需要关注keepalived.conf即可,详情使用man keepalived.conf观察,下面简要说明一下,Keepavlived分为多个配置段,global配置段,vppr配置段,lvs配置段
global_defs:定义全局配置
global_defs { notification_email { [email protected] } notification_email_from [email protected] smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id ysz202 vrrp_mcast_group4 224.0.100.18 }
说明:其中[email protected]直接使用本地用户当做收件地址,router_id可以使用主机名,要注意的是vrrp_mcast_group4表示的ipv4协议下的组播地址,举个例子,因为集群中的心跳通信用单播每个服务器都要单独发送,用广播会给局域网内所有的服务器都发送信息,因此此处使用组播,向拥有同一组播地址的服务器发送心跳信息比较合适。
vrrp_instance : vrrp实例配置
state MASTER|BACKUP:在当前VRRP实例中此节点的初始状态;
interface IFACE_NAME:vrrp用于绑定vip的接口;
virtual_router_id #:当前VRRP实例的VRID,可用范围为0-255,默认为51;
priority #:当前节点的优先级,可用范围0-255;
advert_int 1:通告时间间隔;
authentication { #认证机制
# PASS||AH
# PASS - Simple Passwd (suggested)
# AH - IPSEC (not recommended))
auth_type PASS
# Password for accessing vrrpd.
# should be the same for all machines.
# Only the first eight (8) characters are used.
auth_pass 1234
}
# 最关键的。定义vip
virtual_ipaddress {
<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>
192.168.200.17/24 dev eth1
192.168.200.18.24 dev eth2 label eth2:1
}
# 一个主机上可能有多个接口,定义要监控的接口
trace_interface {
eth0
eth1
...
}
nopreempt #非抢占模式,默认是抢占模式,如果2个服务器性能有优劣之别,可以抢占..
#通告脚本定义
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
其中的脚本notify.sh可以大致如下
#!/bin/bash # contact=‘[email protected]‘ notify() { subject="$(hostname) to be $1 :vip floating" body="$(date +‘%F %T‘): vrrp transition, $(hostname) change to be $1" echo $body | mail -s "$subject" $contact } case $1 in master) notify master ;; backup) notify backup ;; fault) notify fault ;; *) echo "Usage:$(basename $0) {master|backup|fault}" ;; esac
virtual_server : 虚拟服务器
virtual server IP port或者vitual server FWM #
virtual_server 192.168.200.100 443 { delay_loop 6 # lb_algo rr #负载均衡调度算法 lb_kind NAT #调度类型 nat_mask 255.255.255.0 # persistence_timeout 50 #持久连接时长 protocol TCP #只支持TCP协议 # quality regression. Defaults to 1. quorum 1 sorry_server 192.168.1.202 80 real_server 192.168.201.100 443 { weight 1 #notify_up <STRING>|<QUOTED-STRING> #notify_down <STRING>|<QUOTED-STRING> #应用层检测 SSL_GET { url { path / digest ff20ad2481f97b1754ef3e12ecd3a9cc #特征码 } url { path /mrtg/ status_code 200 #基于状态码判定 } connect_timeout 3 #连接的超时时长 nb_get_retry 3 #连接的重试次数 delay_before_retry 3 #连接的重试间隔 } } }
总结:
如果只是需要vip服务,可以只配置vrrp实例,如果需要keepalived来帮助完成lvs负载均衡才需要配置Vitual Server
1.4 vrrp_script和track_script
vrrp_script: 资源脚本
track_script: 调用vrrp_script脚本去监控资源;
vrrp_script chk_httpd { script "killall -0 httpd" interval 2 weight -5 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.111/32 brd 192.168.1.111 dev eth0 label eth0:0 } track_script { chk_httpd } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" }
说明:上述配置中命令killall -0 httpd 用来检测当前httpd进程是否存活,假如没有的话返回失败,当前服务器的优先级会降低,在抢占工作模式下由Master->Backup实现地址漂移,这种方式可以为任何服务做高可用,比如说这里的httpd可以改成Nginx。
二、演示:使用keepalived完成双主模型
双主模型实际上也是主备模型,2个实例互为主备,比如一个httpd服务,一个nginx服务,尽可能减少资源浪费,注意下面是2个不同的ip地址,因此还可以在DNS解析服务器上再做一次负载均衡,使得请求分散到2个ip中,使得前端2个调度器都不会空闲。
ysz202配置文件
global_defs { notification_email { [email protected] } notification_email_from [email protected] smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id ysz202 vrrp_mcast_group4 224.0.100.18 } vrrp_script chk_httpd { script "killall -0 httpd" interval 2 weight -5 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.111/32 brd 192.168.1.111 dev eth0 label eth0:0 } track_script { chk_httpd } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" } vrrp_instance VI_2 { state BACKUP interface eth0 virtual_router_id 52 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.112/32 brd 192.168.1.111 dev eth0 label eth0:1 } track_script { chk_httpd } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" }
ysz204上配置文件
global_defs { notification_email { [email protected] } notification_email_from [email protected] smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id ysz202 vrrp_mcast_group4 224.0.100.18 } vrrp_script chk_httpd { script "killall -0 httpd" interval 2 weight -5 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.111/32 brd 192.168.1.111 dev eth0 label eth0:0 } track_script { chk_httpd } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" } vrrp_instance VI_2 { state MASTER interface eth0 virtual_router_id 52 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.112/32 brd 192.168.1.111 dev eth0 label eth0:1 } track_script { chk_httpd } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" }