[TOC]html
最近由于工做须要在看keepalived,而官方文档一页把所有的配置和说明列了出来,没有分类,东西不少但殊不知道那些是我须要的,网上找文章,发现也很少,并且仍是有些坑,因而记录一下,顺便吐槽下这个markdown,流程图都不支持,排版还有些问题。python
摘自: http://seanlook.com/2015/5/18/nginx-keepalived-ha/linux
Keepalived是一个基于VRRP协议来实现的服务高可用方案,能够利用其来避免IP单点故障,相似的工具还有heartbeat、corosync、pacemaker。可是它通常不会单独出现,而是与其它负载均衡技术(如lvs、haproxy、nginx)一块儿工做来达到集群的高可用。nginx
摘自: http://seanlook.com/2015/5/18/nginx-keepalived-ha/git
VRRP全称 Virtual Router Redundancy Protocol,即 虚拟路由冗余协议。能够认为它是实现路由器高可用的容错协议,即将N台提供相同功能的路由器组成一个路由器组(Router Group),这个组里面有一个master和多个backup,但在外界看来就像一台同样,构成虚拟路由器,拥有一个虚拟IP(vip,也就是路由器所在局域网内其余机器的默认路由),占有这个IP的master实际负责ARP相应和转发IP数据包,组中的其它路由器做为备份的角色处于待命状态。master会发组播消息,当backup在超时时间内收不到vrrp包时就认为master宕掉了,这时就须要根据VRRP的优先级来选举一个backup当master,保证路由器的高可用。shell
在VRRP协议实现里,虚拟路由器使用 00-00-5E-00-01-XX 做为虚拟MAC地址,XX就是惟一的 VRID (Virtual Router IDentifier),这个地址同一时间只有一个物理路由器占用。在虚拟路由器里面的物理路由器组里面经过多播IP地址 224.0.0.18 来定时发送通告消息。每一个Router都有一个 1-255 之间的优先级别,级别最高的(highest priority)将成为主控(master)路由器。经过下降master的优先权可让处于backup状态的路由器抢占(pro-empt)主路由器的状态,两个backup优先级相同的IP地址较大者为master,接管虚拟IP。json
graph TD C1[客户端1] --> B(虚拟IP: 10.0.0.100) C2[客户端2] --> B B --> K1[keepalived主机] B --> K2[keepalived备机] K1 --> A1[服务1: 10.0.0.1] K1 --> A2[服务1: 10.0.0.2] K2 --> A3[服务2: 10.0.0.3] K2 --> A4[服务1: 10.0.0.4]
上面是markdown的流程图,这个编辑器不支持,下面是我从新截的图: vim
经过对虚拟IP的访问,便可访问到后端对应的服务;后端
注意,防火墙也处理好对应的端口,好比: 后端服务: 10.0.0.1:8080,则10.0.0.1要开放8080端口,由于须要被keepalived主机访问;同时keepalived主机也须要开启8080端口,由于须要被客户端访问。安全
sudo yum -y install keepalived
官网下载最新版2.0.0版的[keepalived](http://keepalived.com/download 最新版2.0.12有bug,每次重启keepalived后都须要从新reload firewalld。建议使用2.0.0版本。
解压
进入目录
开始安装,依次执行
# 须要跑这个才能自动生成系统服务文件(keepalived.service) # 2.0.0版本没有这个,直接执行下面的步骤便可,也会自动创建系统服务文件 #./build_setup # 安装配置,默认就能够 ./configure # 编译安装 sudo make && sudo make install
安装过程当中可能会失败,提示缺乏依赖,依赖在解压的目录下的INSTALL文件有说明,在这里贴一下RedHat发行版及其衍生版的,其余发行版的本身看吧:
RedHat based systems (RedHat Enterprise/CentOS/Fedora) ------------------------------------------------------ The following build packages are needed: make autoconf automake (to build from git source tree rather than tarball) The following libraries need to be installed: openssl-devel libnl3-devel ipset-devel iptables-devel libnfnetlink-devel For magic file identification support: file-devel For SNMP support: net-snmp-devel For DBUS support: glib2-devel For JSON support: json-c-devel For PCRE support pcre2-devel For nftables support libnftnl-devel libmnl-devel For building the documentation, the following packages need to be installed: Fedora: python-sphinx (will pull in: python2-sphinx_rtd_theme) CentOS-and-friends: python-sphinx epel-release python-sphinx_rtd_theme For latex or pdf files, the following are also needed: Fedora: latexmk python-sphinx-latex CentOS-and-friends: latexmk texlive texlive-titlesec texlive-framed texlive-threeparttable texlive-wrapfig texlive-multirow
安装完成后的主要目录:
配置文件 /usr/local/etc/keepalived/keepalived.conf keepalived启动配置文件 /usr/local/etc/sysconf/keepalived
由于keepalived的默认配置文件位置是: /etc/keepalived/keepalived.conf,因此须要将实际的文件文职软链接到这里,固然也能够在/usr/local/etc/syscofig/keepalived里面配置增长选项: -f 配置文件路径,这样的形式来更改配置文件路径。本文是以创建软链接的方式
sudo ln -s /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf
这样就算是安装完成了。
sudo firewall-cmd --reload
固然,测试机器关闭防火墙也就一劳永逸了,记得要同时关闭selinux。selinux的保护机制致使跟踪脚本不能执行某些操做(例如:重启某项服务等),解决方法是修改对应脚本的安全上下文类型,详细看下面的配置说明(2.0.0版本不须要修改安全上下文类型了)。
# Centos 7 systemctl start keepalived.service
或者
# Centos 6 service keepalived start
摘自: http://seanlook.com/2015/5/18/nginx-keepalived-ha/,有额外添加和补充。
global_defs项
- notification_email : keepalived在发生诸如切换操做时须要发送email通知地址,后面的 smtp_server 相比也都知道是邮件服务器地址。也能够经过其它方式报警,毕竟邮件不是实时通知的。
- router_id : 机器标识,一般可设为hostname。故障发生时,邮件通知会用到。
vrrp_instance项
- state : 只能为两个值之一:MASTER或BACKUP(必须大写)。指定instance(Initial)的初始状态,就是说在配置好后,这台服务器的初始状态就是这里指定的,但这里指定的不算,仍是得要经过竞选经过优先级来肯定。若是这里设置为MASTER,但如若他的优先级不及另一台,那么这台在发送通告时,会发送本身的优先级,另一台发现优先级不如本身的高,那么他会就回抢占为MASTER。
- interface : 实例绑定的网卡,由于在配置虚拟IP的时候必须是在已有的网卡上添加的。
- mcast_src_ip : 发送多播数据包时的源IP地址(默认是224.0.0.28,使用默认的就能够了)。这里注意了,这里实际上就是在那个地址上发送VRRP通告,这个很是重要,必定要选择稳定的网卡端口来发送,这里至关于heartbeat的心跳端口,若是没有设置那么就用默认的绑定的网卡的IP,也就是interface指定的IP地址。
- virtual_router_id :0~255, 这里设置VRID,这里很是重要,相同的VRID为一个组,他将决定多播的MAC地址。
- priority : 1~254,数字越大优先级越高。设置本节点的优先级,优先级高的为master
- advert_int : 检查间隔,默认为1秒。这就是VRRP的定时器,MASTER每隔这样一个时间间隔,就会发送一个advertisement报文以通知组内其余路由器本身工做正常。
- authentication : 定义认证方式和密码,主从必须同样。
- virtual_ipaddress : 这里设置的就是VIP,也就是虚拟IP地址,他随着state的变化而增长删除,当state为master的时候就添加,当state为backup的时候删除,这里主要是有优先级来决定的,和state设置的值没有多大关系,这里能够设置多个IP地址。
- track_script : 引用VRRP脚本,即在 vrrp_script 部分指定的名字。按期运行它们来改变优先级,并最终引起主备切换。
- uncast_src_ip : 单播地址,即本机ip。
- uncast_peer : 接收单播地址(BACKUP ip),配置在{}里面,能够多个。
vrrp_script
告诉 keepalived 在什么状况下切换,因此尤其重要。能够有多个 vrrp_script。
- script : 本身写的检测脚本。也能够是一行命令如killall -0 nginx。
- interval 2 : 每2s检测一次。
- weight -5 : 检测失败(脚本返回非0)则优先级 -5。
- fall 2 : 检测连续 2 次失败才算肯定是真失败。会用weight减小优先级(1-255之间)。
- rise 1 : 检测 1 次成功就算成功。但不修改优先级。
这里要说明一下script通常有2种写法:
上文 vrrp_script 配置部分,killall -0 nginx属于第1种状况,/etc/keepalived/check_nginx.sh属于第2种状况(脚本中关闭keepalived)。我的更倾向于经过shell脚本判断,但有异常时exit 1,正常退出exit 0,而后keepalived根据动态调整的 vrrp_instance 优先级选举决定是否抢占VIP:
其余状况,本来配置的优先级不变,即配置文件中priority对应的值。
提示:
以上能够作到利用脚本检测业务进程的状态,并动态调整优先级从而实现主备切换。
如下打上勾为必须配置,其余为可选配置。
修改虚拟ip(vip)实例:
vrrp_instance_VI_1 { state MASTER # 若是是备机,则改成BACKUP, 必须大写 # 主机能够启用非抢占模式,当主机宕机,备机提高为主机后,宕机的主机又恢复了正常了,这是会发生再次抢占;主机开启非抢占模式,就能避免在正常运行状态的的切换了 nopreempt # 非抢占模式 instance enp0s3 # 修改为对应的网卡名称 # 其余配置 # ... virtual_ipaddress { 10.0.0.100 # 修改为指定的ip地址(同网段) } # 可选配置,定时执行指定的脚本配置 # 能够用于指定执行间隔地执行服务检查脚本 # 脚本检查到某些服务状态或者进程状态,能够作相应的处理: # 1.返回正常或非正常的退出码(exit code),能够用于更新当前机器的优先级, # 前提是配置为抢占模式,前提是没有配置为非抢占模式(默认就是抢占模式) # 2.检查到服务或进程异常,就关闭当前的keepalived进程,而后备机会经过选举来提高为主机 # 3.其余操做 # 重要:若是要配置,则必须在vrrp_instance_XX前声明: # vrrp_script 脚本名称 { # 脚本内容 # } # 而后在下面节点内声明脚本名称,能够声明多个,用空格或者回车隔开 track_script { 脚本名称 } }
vrrp script示例,必须声明在vrrp_instance节点前:
vrrp_script check-nginx { script "pidof nginx" }
或
vrrp_script check-nginx { script "/etc/keepalived/check_nginx.sh" interval 3 # 要比arp通告时间长,脚本里面若是有sleep的话,也要比sleep的时间长 weight 50 # 检测正常或者异常(exit code = 0 或者 = 1),正常,优先级加50;反之,减50 fall 2 # 跟踪脚本返回2次exit code = 1,才算是一次异常;即发生两次exit code = 1,优先级才减一次50 rise 1 # 跟踪脚本返回1次exit code = 0, 算是一次正常;即发生两次exit code = 0, 优先级加一次50; # user root 脚本执行用户,取默认就好 }
简单检查nginx进程是否存在,实际上nginx进程正常运行并不表明服务就是正常的,应该同时检查后端服务时候正常,check_nginx.sh:
#!/bin/bash count=$(ps -C nginx --no-heading | wc -l) if [ "$count" = "0" ]; then systemctl start nginx.service sleep 2 count=$(ps -C nginx --no-heading | wc -l) exit 1 else exit 0 fi
若是须要再虚拟一个其余网卡的vip,能够复制多一份vrrp_instance进行修改。
修改完后,复制或者同步修改好的配置文件到备机,记得修改备机的state为BACKUP和优先级prority, 优先级必须比主机的优先级低。
若是在不关闭主机keepalived进程的状况下,想要使某台备机提高为主机,能够修改优先级大于当前主机优先级50,重启备机keepalived便可。官方文档:
#for electing MASTER, highest priority wins. #to be MASTER, make this 50 more than on other machines. priority 100
若是防火墙使用firewalld管理:
firewall-cmd --zone=public --add-port=80/tcp --permanent
开启80端口
所有部署了keepalived的主机都须要开启vrrp支持。
# 添加规则 firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface enp0s3 --destination 224.0.0.18 --protocol vrrp -j ACCEPT # 重启防火墙 firewall-cmd --reload
enp0s3对应网卡名称, 224.0.0.18是keepalived的组播地址。
vim /etc/sysconfig/iptables # 添加配置 -A INPUT -i 网卡名称 -p vrrp -s 主/备IP -j ACCEPT
# master uncast_src_ip 10.0.0.1 uncast_peer { 10.0.0.2 } # backup uncast_src_ip 10.0.0.2 uncast_peer { 10.0.0.1 }
keepalived的默认日志路径是: /var/log/message
如下以日志路径/var/log/keepalived.log
为例:
keepalived --help 能够查看支持的配置
修改前: KEEPALIVED_OPTIONS="-D"
, 修改后: KEEPALIVED_OPTIONS="-D -d -S 0"
上面的0表示的是系统级别的日志存放路径local0.*
, 在/etc/rsyslog.conf
里面最后面增长:
local0.* /var/log/keepalived.log
sudo systemctl restart rsyslog.service
再重启keepalived服务:
sudo systemctl restart keepalived.service
若是上述必需配置都已经配置好了,还 是不能访问,那就是配置有问题了,请检查各个配置是否有拼写错误等缘由。
日志: Healthcheck child process(14203) died: Respawning
解决方法: 删除多无或无效的vrrp_server节点。 vrrp_server是用于lvs的负载均衡的,如无用能够删掉。 参考这里
/../../检查脚本.sh exited due to signal 15
解决方法: 脚本里的休眠时间要小于vrrp_script里面设置的执行间隔interval;
缘由:selinux的保护机制。
解决方法: 1.关闭selinux。临时关闭: setenfource 0; 永久关闭: 修改
/etc/selinux/config
里的SELINUX属性,enfourcing为强制开启,permissive为宽容,disabled为关闭,设置为后两个之一就能够。2.修改跟踪脚本的安全上下文的类型为
keepalived_unconfined_script_exec_t
,以脚本'/etc/keepalived/check_nginx.sh'为例: sudo chcon -v -t keepalived_unconfined_script_exec_t /etc/keepalived/check_nginx.sh 使用ls命令的Z选项查看,发现已经修改了,以下图:
2019-02-17更新:新版本(2.0.12)不须要修改安全上下文类型也可使用跟踪脚本重启nginx。
2019-02-18更新:版本2.0.0可使用,相比1.3版本,主机恢复正常运行状态,从新抢占期间服务不可用的时间短了不少,几乎无感,相比最新版本2.0.12,不须要修改脚本安全上下文类型的同时,每次重启也无需reload firewalld。建议使用此版本。
ip addr
发`现网卡上也已经产生了虚拟ip,但却访问不了,ip也ping不通:检查防火墙是否已经开启了vrrp协议支持,就算以前已经配置好了,从新安装后也须要reload一下防火墙配置
sudo firewall-cmd --reload
,坑。 2019-02-17更新: 这个是新版本keepalived的问题,每次从新启动都须要reload一下firwalld,还没找到官方的解决方案,不知道是否是bug,只能新建脚原本启动了,记得修改keepalived.service对应项,或者下降keepalived的版本,不知道具体从哪一个版本开始有这个问题,1.3或者1.4的没问题。
2019-02-18更新: 建议使用2.0.0版本,暂时未发现bug,每次重启keepalived也不用reload firewald, 主机恢复后抢占期间服务不可用的状况,几乎无感。
诸如"received 1 ahtu, exception 0!", 或者 "bogus ..., exception 1!"
解决方法: 统一所有主机的keepalived版本。(这种状况也有多是virtual_route_id冲突,若是版本同样的状况下, 检查一下。)