高可用-Keepalived
全局定义(globaldefinnition)
这一部分用来设置keepalived的故障通知机制和RouterID标识。
1 | !Configuration File for keepalived |
大括号“{}”用于分割区块,需要成对出现。如果少了半个,keepalived也不会报错,但也得不到预期效果。
VRRP实例定义区块部分
这个部分主要用来定义具体服务的实例配置,包括Keepalived主备状态、接口、优先级、认证方式和IP信息等。
1 | #定义一个vrrp_instance实例,名字是VI_1,每个vvrp_instance实例都可以认为是Keepalived中的一个业务服务。 |
高可用单实例
配置主机
切换目录
1 | cd /etc/keepalived/ |
备份配置文件
1 | cp keepalived.conf{,.ori} |
清空配置文件
1 | \ > keepalived.conf |
编写配置文件
1 | vim keeplived.conf |
配置文件内容
1 | global_defs { |
检查并启动keepalived
1 | systemctl start keepalived |
检查IP情况
1 | ip addr|grep 192.168.1.120 |
配置备机
切换目录
1 | cd /etc/keepalived/ |
备份配置文件
1 | cp keepalived.conf{,.ori} |
清空配置文件
1 | \ > keepalived.conf |
编写配置文件
1 | vim keeplived.conf |
配置文件内容
1 | global_defs { |
检查并启动keepalived
1 | systemctl start keepalived |
这里因为没有接管,所以不应该有返回
如果有,就证明脑裂了。
检查通信情况,iptables/firewalld
检查配置文件,例如virtual_router_id是否不一致
1 | ip addr|grep 192.168.1.120 |
高可用测试
暂停主节点keepalived服务或关机
1 | systemctl stop keepalived |
分别在主节点和备节点上检查ip状态(若主节点已关机则不用检查主节点)
备节点应该拿到了VIP
1 | ip addr|grep 192.168.1.120 |
重启主节点服务
1 | systemctl start keepalived |
检查VIP状态,主节点应当拿回了VIP
1 | ip addr|grep 192.168.1.120 |
配置差别
Keepalived 参数差别 | MASTER 节点特殊参数 | BACKUP 节点特殊参数 |
---|---|---|
router_id(唯一标识) | routrer_id web01 | routrer_id web02 |
state | state MASTER | state BACKUP |
priority | priority 150 | priority 100 |
“脑裂”问题
什么是脑裂
在指定时间内两台高可用服务无法检测到对他心跳消息,各自取得资源以及服务所有权,而此时两台高可用服务器都会去抢占同样的资源,这样会导致同一个IP或服务在两端同时存在发生冲突,最严重的就是两台主机抢占同一个IVP地址,当用户写入数据时,可能会分别写入两端,造成两端数据不一致或数据丢失,这种情况就被成为脑裂。
导致脑裂发生的原因
高可用服务器之间对心跳链路故障,导致无法正常通信。
- 心跳线坏了(断裂、老化)
- 网卡以及相关驱动坏了,IP配置以及冲突问题(网卡直连)
- 心跳线之间连接设备故障(网卡及交换机)
- 仲裁机器出问题(采用仲裁方案)
高可用服务器对上开启了iptables防火墙阻挡了心跳消息传输
高可用服务器上心跳网卡地址等信息配置不正确
其他服务配置不当等原因,如心跳方式不同、心跳广播冲突、软件BUG等
同一VRRP实例virtual_router_id参数两端配置不一样
解决脑裂常见方案
- 使用串行电缆和一台电缆链接,同时使用两条心跳线路,做线路高可用。
- 检测到脑裂时强行关闭一个心跳节点(需要特殊设备支持,如Stonith、fence)。相当于备节点收不到心跳消息,发送关机命令通过单路的线路来关闭
- 做好对脑裂的状态监控(邮件、手机短信、值班)报警,发生脑裂时第一时间人为介入仲裁。如百度的报警短信可以区分上下行,管理员可以通过短信回复数字或字符串返回给服务器,让服务器根据指令自动操作。或者开发简单app,第一时间点点点操作。
常见的keepalived脑裂解决方案
互联网应用服务器,前端web负载均衡的的高可用,对于普通业务一般是可以接受的,对于数据库和存储服务不可以接受。
- 如果开启防火墙,一定要开放心跳消息通过,一般采用定向IP段可通过。
- 可以拉一条以太网线或者串口线作为线路冗余
- 开发监测程序通过监控软件(如Nagios)监测脑裂
生产判断脑裂思路:
- 简单思路:备节点出现VIP就报警,有两种情况,一是主节点宕机了,备节点接管;二是主机没宕,脑裂了,无论是哪一种都要进行报警,然后人工查看。
- 严谨思路:备节点出现VIP,主节点以及对应服务仍然存活,说明脑裂了
Keepalived双实例双主机配置
规划
HOSTNAME | IP | 说明 |
---|---|---|
web01 | 192.168.1.55 | VIP:192.168.1.100(绑定A服务 www.xxx.com) |
web02 | 192.168.1.56 | VIP:192.168.1.101(绑定B服务 bbs.yyy.com) |
配置web01
在原来的单实例基础上增加一个实例(至于你们怎么搭建服务,我建议用nginx测试)
1 | global_defs { |
配置web02
建议直接scp然后改一改
1 | global_defs { |
web01、web02上都重启服务
1 | systemctl restart keepalived |
web01、web02分别查看ip
1 | ip add|egrep “192.168.1.100|192.168.1.101” |
轮流暂停keepalived服务,同时查看未暂停服务的web服务器,是否拿到了IP
其中一个暂停了服务,另一个服务器应当会拿到两个ip
1 | systemctl stop keepalived |
在停止服务的服务器上,重新启动之前暂停的服务,再次查看
应当看到服务器把ip拿回来了
1 | ip add|egrep “192.168.1.100|192.168.1.101” |
配置区别
web01 | web02 |
---|---|
state MASTER | state BACKUP |
priority 150 | priority 100 |
state BACKUP | state MASTER |
priority 100 | priority 150 |
主要区别
- state(状态)
- priority(权重/优先级)
优先级决定了VIP在哪个机器上初始运行
Nginx配合Keeplived
逻辑架构图
配置两边nginx
1 | cd /pwd/nginx/conf/ |
nginx内容
1 | worker_processes 1; |
配置keepalived服务
配置web01
1 | global_defs { |
配置web02
1 | global_defs { |
配置DNS解析
1 | 192.168.1.100 www.xxx.com |
两边重启nginx服务
在web页面进入www.xxx.com
此时关闭web01高可用服务或者关闭服务器
在nginx页面刷新页面
查看web02的IP状态
1 | ip addd|grep 192.168.1.100 |
开启web01,查看ip
1 | ip addd|grep 192.168.1.100 |
web重新访问 www.hanpi.com
状态应该处于正常
监听网卡上不存在的IP地址
如果配置使用了”listen 192.168.1.100:80;“ 指定IP监听服务,而本地上没有这个IP,nginx就会报错。
如果实施双主(即主备)同时提供不同的服务,配置文件里制定了IP监听,备节点就会因为网卡不存在实际IP而报错。
出现上面的问题原因在于物理网卡上没有与配置文件里监听的IP相对应的IP,我们要让Nginx服务在网卡上没有指定监听的IP时也能启动,不报错。
解决办法
是在/etc/sysctl.conf中加入如下内核参数。
1 | net.ipv4.ip_nonlocal_bind = 1 |
表示启动nginx而忽略配置中监听的ip是否存在,同样适用于Haproxy。
快速写入,刷新生效
1 | echo “net.ipv4.ip_nonlocal_bind = 1” >> /etc/sysctl.conf |
1 | sysctl -p |
解决服务宕后keepalived仍运行
默认情况下,Keepalived软件只有在对方机器宕机或者Keepalived停止的时候会接管业务。生产环境中,有业务服务停止的Keepalived还在工作的情况,这种时候就会造成数据丢失。
方法一
写守护进程脚本来处理。当Nginx业务出现问题时,就停掉本地的Keepalived服务,实现飘逸接管。
编写脚本
1 | vim /pwd/check_nginx.sh |
启动脚本
1 | sh /pwd/check_nginx.sh & |
检查脚本运行情况
1 | ps -ef | grep check |
查看端口
1 | lsof -I :80 |
停止nginx,查看是否切换
1 | systemctl stop nginx |
查看nginx状态
1 | systemctl status nginx |
再次检查nginx
1 | netstat -lntup|grep nginx |
在备节点上查看
1 | ip add|grep 192.168.1.100 |
方法二
使用keepalived的配置文件参数触发脚本
1 | vim check_nginx_proxy.sh |
授权
1 | chmod +x check_nginx_proxy.sh |
检查授权
1 | ls -l check_nginx_proxy.sh |
keepalived配置如下
1 | global_defs { |
测试脚本
检查端、服务、ip
1 | lsof -i :80 |
停止nginx服务
1 | systemctl stop nginx |
再次检查
1 | lsof -i :80 |
查看日志
1 | cat /var/log/messages | grep Keepalived |
多组Keepalived局域网内冲突
如果在同一局域网内部署了多组Keepalived服务器,而又未使用专门的心跳线通信时,可能会发生接管故障。
Keepalived高可用是通过VRRP协议实现的,VRRP协议默认通过IP多播实现的高可用服务对之间的通信,如果一个局域网内存在多组Keepalived服务器对,就会造成IP多播地址冲突问题,不同组的Keepalived都会使用默认的224.0.0.18作为多播地址。
所以我们需要在同组Keepalived服务器的所有配置文件中指定独立的多播地址。
指定多播地址
示例:
1 | global_defs { |
指定配置文件接收Keepalived服务日志
日志集成,懂得都懂
将KEEPALIVED_OPTIONS=”-D” 修改为 KEEPALIVED_OPTIONS=”-D -d -S 0”
1 | vim /ect/sysconfig/keepalived |
修改keepalived配置文件
快速替换
1 | sed -i ’14 s# KEEPALIVED_OPTIONS=”-D”# KEEPALIVED_OPTIONS=”-D -d -S 0”#g’ /etc/sysconfig/keepalived |
检查
1 | sed -n ‘14p’ /etc/sysconfig/keepalived |
说明,查看 /etc/sysconfig/keepalived 里注释获得以上说明
1 | # --dump-conf -d 导出备份数据。 |
修改系统日志配置文件
修改rsslog配置文件,尾部添加以下两行内容
1 | vim /etc/rsyslog.conf |
在如下信息的第一列尾部添加”;local0.none”,注意有分号。
表示来自local0设备的所有日志信息不再记录与/var/log/messages
1 | *.info;mail.one;authpriv.none;cron.none;local0.none /var/log/messages |
配置完成,重启rsyslog服务
1 | systemctl restart rsyslog.service |
重启keepaliaved,查看日志
1 | systemctl restart keepalived |
可以在/var/log/messages上设置对/avr/log/keepalived.log进行轮询,防止单个日志文件变大
编写监测Keepalived “脑裂”的脚本
检测思路:在备节点上执行脚本,如果可以ping通主节点并且备节点有VIP就报警,人工介入检查是否发生了”脑裂”。
编写脚本
1 | vim check_split_brain.sh |
测试脚本
1 | sh check_split_brain.sh |
关闭web01,查看web02报警情况
1 | systemctl stop nginx |
web02报警正常,重启web01服务,查看恢复情况
1 | systemctl start nginx |