keepalived
keepalived的作用就是解决单点问题,当其中一个调度器宕机另一个备用的调度器取而代之,从而实现高可用。keepalived有两个节点,一个为活动节点Active和备份节点Passive。在lvs集群上实现高可用需要有vip,ipvs规则,使用nginx集群实现高可用需要vip和nginx服务。
vip在某个时刻只能在一个节点上,当一个节点宕机了另外一个节点必须取得vip并配置再自己的主机上才能作为访问入口。那么怎么样才能知道活动节点宕机了呢?主节点定时发送组播信息及heartbeat心跳信息,各个主机时间要同步,二者之间约定当主节点宕机后备用调度器就将IP抢过来配置再自己的主机上。对高可用集群来讲,节点之间所征用的资源主要在两个方面,IP和存储。在存储上如nfs可解决并发存储问题。
lvs:vip,ipvs rules
nginx:vip,nginx service
VRRP协议:
vrrp:virtual route redundent protocol,虚拟路由冗余协议。 keepalived就是vrrp协议在linux主机上的以守护进程的实现,能够根据配置文件自动生成ipvs规则,能够对RS做健康状态监测。
Scheduler:调度器
Memory Mngt:内存管理
Control Plance Configuration Parser:配置文件分析器的主控工具,能够reload配置文件,类似Nginx 的master进程。
Core components:核心组件,包括VRRP Strack,也就是vrrp协议的实现。Checkers检测功能。checkers是一个线程,VRRP Stack也是一个线程。
IPVS wrapper:就是能够根据配置文件生成规则的组件。
Watch Dog:内部自我救赎的高可用机制,自动监控VRRP进程是否正常,如果进程挂掉就会把它重新启动起来。
配置文件
安装keepalived:
CentOS 6.4版本以后keepalived已近被收录发行版,可以直接使用yum install keepalived。
主配置文件位置:/etc/keepalived/keepalived.conf
服务启动脚本:/etc/sysconfig/keepalived
配置文件的组成部分:
GLOBAL CONFIGURATION 全局配置段
VRRPD CONFIGURATION vrrp守护进程
vrrp instance 虚拟路由器
vrrp synchoinzation group
LVS CONFIGURATION
HA Cluster配置前提:
1、要能够使用主机名与对方主机进行通讯,本机的主机名与hosts中定义的主机保存一致,要与hostname(uname -n)获得的名称保持一致,修改主机名的命令有:在6中修改文件/etc/sysconfig/network,在7中hostnamectl set-hostname HOSTNAME。各个节点要能够互相解析主机名。一般通过hosts文件解析。
2、各节点时间同步。
3、确保iptables端口开放及关闭selinux。
配置文件中的 global_defs{} 配置段是全局配置,vrrp_instance{} 是用来做虚拟路由实例的。
切换到 /etc/keepalived/keepalived.conf 先将配置文件备份,然后将所有的 virtual_server{} 配置段注释,因为此时用不到。
全局配置:
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 #初始状态,MASTER和BACKUP interface ens33 #IP地址配置再那个网卡上 virtual_router_id 51 #虚拟路由的ID, 工作在同一个虚拟路由上的这个ID要相同。 priority 100 #0-255,优先级,要想成为MASTER就要定义高的优先级 advert_int 1 #心跳信息的发送间隔 authentication { #认证信息 auth_type PASS #认证方式为简单字符认证 auth_pass 1111 #认证用的字符串,同一个虚拟机实例上要一样 } virtual_ipaddress { #虚拟IP地址,这个地址将会配置再上面设置的 interface 上。 192.168.200.16 192.168.200.17 192.168.200.18/24 dev eth2 label eth2:1 #这个配置方法只能在Centos6上,在7上只能用IP/mask方式。 } nopreempt #非抢占模式,默认抢占模式 }
开启日志:
在 /etc/sysconfig/keepalived 修改该为: KEEPALIVED_OPTIONS="-D -S 3"
在 /etc/rsyslog.conf 中在下面添加 local3.* /var/log/keepalived.log,然后重启日子服务systemctl restart rsyslog.service。
这些修改在每个虚拟路由上都要修改,这个日子功能不影响keepalived的正常工作,不开启也可以。这个日子记录了keepalived的心跳信息,启动关闭等等信息。
手动将主节点将为备用节点:
在配置文件中加上这一段脚本,这个脚本的作用是每隔一段时间执行一次,当检测到有down文件时就将此节点的权重减2,从而实现将主节点降低为备用节点,只要在响应目录中添加上down文件就可以控制此操作。
vrrp_script chk_schedown{ script "[[ -f /etc/keepalived/own ]] && exit 1 || exit 0" interval 2 #每隔多长时间检测一次 weight -2 #减少的权重 }
下面这个脚本作用和上面的一样,如果上面的配置不行,实现不了就用下面这个。
vrrp_script hand_down { script "/etc/keepalived/run.sh" #这里放着一个shell脚本,注意权限问题 interval 1 weight -2 } run.sh #!/bin/bash if [ -f /etc/keepalived/down ]; then exit 1 else exit 0 fi
这段脚本和其他的配置段是平级的,不存在包含关系。上面只是定义脚本,还没有去调用,调用脚本需要在 vrrp_instance 中定义,定义格式如下,track_script 是用来监控脚本的,track_interface 是用来监控端口的。
vrrp_instance VI_1 { ........ track_script { chk_schedown } }
配置完成后重启keepalived,然后在 /etc/keepalived/ 下创建 down文件就可以将某个路由降级为备用节点。
基于LVS实现高可用的配置方法:
基于LVS的nat模式下实现高可用需要有vip和dip,且是可动的,dip是调度器与后端集群通讯的ip,vip是客户端请求的ip,当vip变动时,dip也要vip跟着变动,也就是说vip和dip必须同时在一个调度器上。
vrrp_svnc_group VG_1{ group { VI_1 #name of vrrp_instance (below) VI_2 #one for each moveable IP } } vrrp_instance VI_1 { eth0 vip } vrrp_instance VI_1 { eth0 dip }
两遍都出现VIP现象:
这种情况是两个主机通讯问题造成的,关闭防火墙或设置响应的规则即可解决。
双主模式
一本情况下两个调度器只有一个是正常工作的,还有一个就会处于闲置状态,这样会造成资源浪费,如果把两个调度器都使用起来呢,首先要将域名解析到两个IP上,这样访问者会被分流到两个IP上,两个调度器上正常工作时各自配置一个IP,也是VIP,当其中一个调度器宕机就将另一个作为备用节点,也就是两个vip在一个主机上。
配置过程:
将每个主机上的 keepalived 都配置两个 vrrp_instance ,且如下配置都是不一样的。
state 一个为主的MASTER,一个为备用的BACKUP。
virtual_router_id 虚拟路由ID,同一组要一样,因为这是不同的两组,所以要不一样。
priority 优先级,抢占模式各自的主节点要比备用的优先级高。
virtual_ipaddress 使用的vip也要不一样。
两个主机的配置是一样的模式,注意双主模式不要限定组播地址 vrrp_mcast_group4 这样会导致只有一组生效,因为默认不同的组的组播地址是不一样的。
global_defs { notification_email { root@localhost } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node1.zhuqiyang.com } vrrp_script chk_schedown { script "/etc/keepalived/run.sh" interval 2 weight -2 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 99 advert_int 1 authentication { auth_type PASS auth_pass fa2a8dae } virtual_ipaddress { 192.168.96.139/24 } track_script { chk_schedown } }
实例配置:
这是其中一个的配置,另一个配置根据上面的条件做响应修改即可。
#这是双主模型,单组下面这个不加即可。
vrrp_instance VI_2 { state MASTER interface ens33 virtual_router_id 61 priority 100 advert_int 1 authentication { auth_type PASS auth_pass fa2a8saex } virtual_ipaddress { 192.168.96.140/24 } track_script { chk_schedown } }
通过脚本发送通知
当主机状态改变时,需要发送信息通知给管理员,keepalived可以通过写脚本的方式发送邮件。具体配置为在实例vrrp_instance 中配置如下内容,每个实例都要配置响应的脚本内容。
vrrp_instance VI_1 { ....... notify_master "/etc/keepalived/test.sh master" notify_backup "/etc/keepalived/test.sh backup" notify_fault "/etc/keepalived/notify.sh fault" } 这个notify.sh的内容如下,也可以自定义内容。 #!/bin/bash vip=192.168.96.139 contact='root@localhost' notify() { mailsubject="`hostname` to be $1: $vip floating" mailbody="`date '+%F %H:%M:%S'`: vrrp transition, `hostname` changed to be $1" echo $mailbody | mail -s "$mailsubject" $contact } case "$1" in master) notify master # /etc/rc.d/init.d/haproxy start exit 0 ;; backup) notify backup # /etc/rc.d/init.d/haproxy stop exit 0 ;; fault) notify fault # /etc/rc.d/init.d/haproxy stop exit 0 ;; *) echo 'Usage: `basename $0` {master|backup|fault}' exit 1 ;; esac
nginx高可用集群
先配置后端的服务器集群,每台主机上都安装好httpd服务,然后再在两个调度器上分别安装上nginx,再配置 upstream ,然后再在location中配置proxy_pass 。
upstream webservers { server 192.168.96.128:80 weight=1; server 192.168.96.130:80 weight=1; }
上面这个upstream 配置在 http{} 内即可。
location / { proxy_pass http://webservers/; }
这个location 配置在 server{} 中。
后端的集群主机中在各自的主页写上不一样的内容以便调试区分。这些工作完成后就可以在开启 keepalived 服务了,然后访问vip就可以看到负载均衡的高可用服务了。
nginx宕机处理:
当nginx意外宕机但是 keepalived 依然运行,虽然这时候已近不能提供服务但是vip任然在当前的主机上,这时候应该将当前主机的keepalived降权为备用主机,让正常服务的nginx主机作为调度器。实现这个功能就是将 vrrp_script { } 中设置为检测nginx主机是否服务正常,如果不正常则将主机降权为备用节点,然后设置 track_script { } 去跟踪设置的脚本即可。
在chk_nginx.sh脚本中的内容如下,就是检测nginx服务是否正常。
#!/bin/bash killall -0 nginx &> /dev/null exit $?
下面这个是追踪脚本chk_nginx的设置。
track_script { chk_nginx }
设置完成后重启keepalived服务,然后将nginx停止服务,看备用节点是否将vip抢过去了。
一般情况下如果nginx宕机了需要将nginx修复上线,如果修复不了就备用节点成为主节点,当nginx宕机了如何修复呢,可以在notify的触发事件中重启nginx服务。只要在触发的脚本中添加重启nginx服务的命令即可。
#!/bin/bash vip=192.168.96.139 contact='root@localhost' notify() { mailsubject="`hostname` to be $1: $vip floating" mailbody="`date '+%F %H:%M:%S'`: vrrp transition, `hostname` changed to be $1" echo $mailbody | mail -s "$mailsubject" $contact } case "$1" in master) notify master systemctl restart nginx.service exit 0 ;; backup) notify backup systemctl restart nginx.service exit 0 ;; fault) notify fault # /etc/rc.d/init.d/haproxy stop exit 0 ;; *) echo 'Usage: `basename $0` {master|backup|fault}' exit 1 ;; esac
双主模式高可用集群:
双主模型(active/active)高可用集群的实现就是创建两个vrrp实例,其中一个为主另一个则为备用,这样两台调度器就可以同时进行工作了,利用域名解析将域名解析到两个vip,一个配置实例如下,红色的表示不一样的地方。
! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from root@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node4.zhuqiyang.com } vrrp_script hand_down { script "/etc/keepalived/run.sh" interval 1 weight -2 } vrrp_script chk_nginx { # 这个脚本检测要先定义然后才能在下面引用,否者不生效 script "/etc/keepalived/chk_nginx.sh" interval 1 weight -2 } vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass fa2a8dae } virtual_ipaddress { 192.168.96.139/24 dev ens33 label ens33:0 } track_script { chk_nginx } 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 ens33 virtual_router_id 61 priority 99 advert_int 1 authentication { auth_type PASS auth_pass fa2av8da9 } virtual_ipaddress { 192.168.96.140/24 dev ens33 label ens33:1 } track_script { chk_nginx } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" }
配置完成后尝试着将其中一个调度器的nginx服务关闭,在另一个调度器上查看是两个vip是否已经配置上,然后在启动停掉的nginx服务,再看看vip是否被抢回来,两个vip分别配置在两个调度器上。
快速配置
快速使用配置:
! 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 k1 # 主机名 vrrp_skip_check_adv_addr #vrrp_strict # 遵守严格的VRRP协议,不支持单播,否者会添加DROP的iptables规则 vrrp_garp_interval 0 vrrp_gna_interval 0 script_user root # 运行检测脚本的用户 enable_script_security # 运行检测脚本的用户要加 } vrrp_script check_port { # 这个脚本检测要先定义后使用,否者不生效 script "/etc/keepalived/check_port.sh" # 注意给这个脚本赋于执行权限 interval 2 # 检测时间间隔 weight -20 # 检测失败后对权重的操作 } vrrp_instance VI_1 { state MASTER # 节点状态,必须大写 可选值:MASTER|BACKUP interface eth0 virtual_router_id 51 # 相同集群id要一样 priority 100 # 节点优先级 advert_int 1 authentication { auth_type PASS auth_pass 123456 # 同一个集群密码要一样 } virtual_ipaddress { # 虚拟地址 192.168.199.95/24 dev eth0 label eth0:0 } track_script { # 引用检测脚本 check_port } }
参数说明:
! Configuration File for keepalived global_defs { #全局定义部分 notification_email { #设置报警邮件地址,可设置多个 acassen@firewall.loc #接收通知的邮件地址 } notification_email_from test0@163.com #设置 发送邮件通知的地址 smtp_server smtp.163.com #设置 smtp server 地址,可是ip或域名.可选端口号 (默认25) smtp_connect_timeout 30 #设置 连接 smtp server的超时时间 router_id LVS_DEVEL #主机标识,用于邮件通知 vrrp_skip_check_adv_addr vrrp_strict #严格执行VRRP协议规范,此模式不支持节点单播 vrrp_garp_interval 0 vrrp_gna_interval 0 script_user keepalived_script #指定运行脚本的用户名和组。默认使用用户的默认组。如未指定,默认为keepalived_script 用户,如无此用户,则使用root enable_script_security #如果路径为非root可写,不要配置脚本为root用户执行。 } vrrp_instance VI_1 { #vrrp 实例部分定义,VI_1自定义名称 state MASTER #指定 keepalived 的角色,必须大写 可选值:MASTER|BACKUP interface ens33 #网卡设置,lvs需要绑定在网卡上,realserver绑定在回环口。区别:lvs对访问为外,realserver为内不易暴露本机信息 virtual_router_id 51 #虚拟路由标识,是一个数字,同一个vrrp 实例使用唯一的标识,MASTER和BACKUP 的 同一个 vrrp_instance 下 这个标识必须保持一致 priority 100 #定义优先级,数字越大,优先级越高。 advert_int 1 #设定 MASTER 与 BACKUP 负载均衡之间同步检查的时间间隔,单位为秒,两个节点设置必须一样 authentication { #设置验证类型和密码,两个节点必须一致 auth_type PASS auth_pass 1111 } virtual_ipaddress { #设置虚拟IP地址,可以设置多个虚拟IP地址,每行一个 192.168.119.130 } track_script { #脚本监控状态 chk_nginx_service #可加权重,但会覆盖声明的脚本权重值。chk_nginx_service weight -20 } notify_master "/etc/keepalived/start_haproxy.sh start" #当前节点成为master时,通知脚本执行任务 notify_backup "/etc/keepalived/start_haproxy.sh stop" #当前节点成为backup时,通知脚本执行任务 notify_fault "/etc/keepalived/start_haproxy.sh stop" #当当前节点出现故障,执行的任务; } virtual_server 192.168.119.130 80 { #定义RealServer对应的VIP及服务端口,IP和端口之间用空格隔开 delay_loop 6 #每隔6秒查询realserver状态 lb_algo rr #后端调试算法(load balancing algorithm) lb_kind DR #LVS调度类型NAT/DR/TUN #persistence_timeout 60 同一IP的连接60秒内被分配到同一台realserver protocol TCP #用TCP协议检查realserver状态 real_server 192.168.119.120 80 { weight 1 #权重,最大越高,lvs就越优先访问 TCP_CHECK { #keepalived的健康检查方式HTTP_GET | SSL_GET | TCP_CHECK | SMTP_CHECK | MISC connect_timeout 10 #10秒无响应超时 retry 3 #重连次数3次 delay_before_retry 3 #重连间隔时间 connect_port 80 #健康检查realserver的端口 } } }
不抢回vip:
vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 nopreempt # 不抢回VIP authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 192.168.199.95/24 dev eth0 label eth0:0 } }