一、keepalived简介
  keepalived是集群管理中保证集群高可用的一个服务软件,其功能类似于,用来防止单点故障。

二、vrrp协议
2.1 vrrp协议简介

  在现实的网络环境中,两台需要通信的主机大多数情况下并没有直接的物理连接,对于这样的情况,他们之间的路由怎么选择的呢?主机如何选定到达目的主机的下一跳路由,这是一个问题,通常解决办法有两种:

在主机上使用动态路由协议
在主机上配置静态路由
  很明显,在主机上配置动态路由协议是非常不且实际的,因为管理、维护成本以及是否支持等诸多问题,那么配置静态路由就变得十分的流行,实际上,这种方式我们至今一直在用。但是路由器(或者说默认网关)却经常成为单点。就算配置了多个静态路由,却因为只有重启网络才生效变得不实用。
  VRRP的目的就是为了解决静态路由单点故障问题!
VRRP通过一种竞选协议来动态的将路由任务交给LAN中虚拟路由器的某台VRRP路由器,这里看来很绕,因为有两个挂件名词:虚拟路由器和VRRP路由器。
VRRP路由器
  VRRP路由器就是一台路由器,只不过上面运行了VRRPD这样的程序,来实现VRRP协议,这是物理的路由器,一台VRRP路由器可以位于多个虚拟路由器。
VRRP虚拟路由器
  所谓虚拟,就是说不并不是实际存在的,是一个逻辑而不是物理的路由器,虚拟路由器通常由多台VRRP路由器通过某种方式组成,就好比这些物理的路由器都丢到一个池(pool)里面去,整个pool对外看起来就像是一台路由器,但其实内部有很多台,虚拟路由器的标识称为VRID。
2.2 vrrp工作机制

  VRRP通过竞选协议来实现虚拟路由器的功能,所有的协议报文都是通过IP多播包(多播地址224.0.0.18)形式发送的。虚拟路由器由VRID(范围0-255)和一组IP地址组成。所以,在一个虚拟路由器中,不管谁是MASTER,对外都是相同的MAC和IP(称之为VIP)。客户端主机并不需要因为MASTER的改变而修改自己的路由配置,对他们来说这种主从切换是透明的。
  在一个虚拟路由器中,只有作为MASTER的VRRP路由器会一直发送VRRP组播包,BACKUP不会抢占MASTER,除非它的优先级(priority)更高。当MASTER不可用时(BAKCUP收不到组播包),多台BACKUP中优先级最高的这台会被抢占为MASTER。这种抢占是非常迅速的(< 1s),以保证服务的连续性。
  出于安全性考虑,VRRP包使用了加密协议进行加密。

三、keepalived实战环境准备(配置部分可以参考前面的博文:使用haproxy实现反向代理负载均衡实战)
node1:haproxy+httpd
node2:haproxy+httpd
mini1: httpd

四、keepalived实战
4.1 安装keepalived

分别在两台haproxy的server node1和node2上安装keeepalived,并启动

# yum install -y keepalived
启动apache、haproxy和keepalived

systemcl start haproxy
systemcl enable haproxy systemcl start haproxy
systemcl enable haproxy systemctl start keepalived
systemctl enable keepalived

[root@node1 ~]# cd /etc/keepalived/

[root@node1 keepalived]# vim keepalived.conf

! Configuration File for keepalived
global_defs {
notification_email { #keepalived切换时发送email的对象,可以多个,每行一个
root@chinasoft.com
}
notification_email_from haproxy-ha@chinasoft.com #邮件来自哪里,haproxy-ha代表给haproxy做高可用
smtp_server 127.0.0.1 #本地配置的smtp
smtp_connect_timeout 30 #连接smtp超时时间30s
router_id haproxy-ha #运行haproxy_ha集群的标识,每个集群一个
}
vrrp_script chk_haproxy {
script "/etc/keepalived/scripts/haproxy_chk.sh" # 状态监测脚本,当haproxy进程挂掉时,关闭keepalived,可以有效防止vip的随意漂移
interval 5
weight -2
} vrrp_instance VI_1 { # vrrp实例的名字,根据业务定义
interface eth0 # 该实例绑定的绑卡设备,centos7要注意默认不是eth0需要改为对应的如:ens33
state MASTER # 指定instance的初始状态,在两台router都启动后,马上发上竞选出Master,这里的state Master并不代表一直是Master
virtual_router_id 51 # VRIP,范围0~255,默认51
priority 50 # 权重值,用来竞选,MASTER要高于BACKUP至少50,node2权重值修改为150
advert_int 5 # 竞选检查间隔,默认1s
authentication { # 设置验证,防止局域网多个keepalived配置混乱
auth_type PASS
auth_pass haproxy_ha
} virtual_ipaddress { #设置的虚拟ip地址
192.168.3.201
192.168.3.202
} track_script {
chk_haproxy
} }

编写haproxy状态检测脚本
# cat /etc/keepalived/scripts/haproxy_chk.sh

#!/bin/bash
# auto check haproxy process
killall -0 haproxy if [[ $? -ne 0 ]];then
/usr/bin/systemctl stop keepalived
fi

将配置文件拷贝到node2上,并更改优先级和角色为BACKUP

[root@node1 ~]# scp /etc/keepalived/keepalived.conf 192.168.3.200:/etc/keepalived/
[root@node1 ~]# scp /etc/keepalived/scripts/haproxy_chk.sh 192.168.3.200:/etc/keepalived/scripts/
[root@linux-node2 keepalived]# sed -i 's#priority 100#priority 150#g' keepalived.conf
[root@linux-node2 keepalived]# sed -i 's#state MASTER#state BACKUP#g' keepalived.conf

重新启动两台keepalived,此时直接访问虚拟VIP如:192.18.3.202是可以直接访问的(生产环境直接将域名绑定在虚拟IP上即可实现访问)

# systemctl restart keepalived.service

查看两台keepalived的虚拟ip情况

[root@node1 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:3b:dc:7e brd ff:ff:ff:ff:ff:ff
inet 192.168.3.140/24 brd 192.168.3.255 scope global dynamic eth0
valid_lft 64981sec preferred_lft 64981sec
inet 192.168.3.201/32 scope global eth0
valid_lft forever preferred_lft forever
inet 192.168.3.202/32 scope global eth0
valid_lft forever preferred_lft forever
[root@node2 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:fe:67:7c brd ff:ff:ff:ff:ff:ff
inet 192.168.3.200/24 brd 192.168.3.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fefe:677c/64 scope link
valid_lft forever preferred_lft forever

抓组播包,可以看出检查竞选的频率为4s,MASTER为node1(权重值为150)

[root@node1 ~]# tcpdump -n 'host 224.0.0.18'

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
09:14:34.916207 IP 192.168.3.12 > 224.0.0.18: VRRPv2, Advertisement, vrid 36, prio 150, authtype simple, intvl 1s, length 20
09:14:35.917550 IP 192.168.3.12 > 224.0.0.18: VRRPv2, Advertisement, vrid 36, prio 150, authtype simple, intvl 1s, length 20
09:14:36.918762 IP 192.168.3.12 > 224.0.0.18: VRRPv2, Advertisement, vrid 36, prio 150, authtype simple, intvl 1s, length 20
09:14:37.237311 IP 192.168.3.140 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 4s, length 68
09:14:37.919298 IP 192.168.3.12 > 224.0.0.18: VRRPv2, Advertisement, vrid 36, prio 150, authtype simple, intvl 1s, length 20
09:14:38.920860 IP 192.168.3.12 > 224.0.0.18: VRRPv2, Advertisement, vrid 36, prio 150, authtype simple, intvl 1s, length 20
09:14:39.921685 IP 192.168.3.12 > 224.0.0.18: VRRPv2, Advertisement, vrid 36, prio 150, authtype simple, intvl 1s, length 20
09:14:40.922149 IP 192.168.3.12 > 224.0.0.18: VRRPv2, Advertisement, vrid 36, prio 150, authtype simple, intvl 1s, length 20
09:14:41.238014 IP 192.168.3.140 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 4s, length 68
09:14:41.923613 IP 192.168.3.12 > 224.0.0.18: VRRPv2, Advertisement, vrid 36, prio 150, authtype simple, intvl 1s, length 20
09:14:42.925114 IP 192.168.3.12 > 224.0.0.18: VRRPv2, Advertisement, vrid 36, prio 150, authtype simple, intvl 1s, length 20
09:14:43.925975 IP 192.168.3.12 > 224.0.0.18: VRRPv2, Advertisement, vrid 36, prio 150, authtype simple, intvl 1s, length 20
09:14:44.927657 IP 192.168.3.12 > 224.0.0.18: VRRPv2, Advertisement, vrid 36, prio 150, authtype simple, intvl 1s, length 20
09:14:45.239277 IP 192.168.3.140 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 4s, length 68

此时停用node1(192.168.3.140)上的haproxy服务或者keepalived服务,vip会发生漂移,当node1的keepalived和haproxy重新启动时,vip会再次发生漂移返回原master节点,即发生了vip的抢夺

五、keepalived设置不抢占资源
  当MASTER出现问题后,BACKUP会竞选出新的MASTER,那么当之前的MASTER重新ONLINE后,是继续成为MASTER还是变成BACKUP呢?默认情况下,之前的MASTER起来后悔继续抢占成为MASTER,也就是说,整个过程需要发生两次切换。
    1)MASTER -> BACKUP
    2) BACKUP -> MASTER
  这样对业务频繁的切换是不能容忍的,因此我们希望MASTER起来后成为BACKUP,所以要设置不抢占。keepalived里面提供了nopreempt这个配置,但是这个配置只能用在state为BACKUP的机器上,但是我们明明希望的是MASTER不进行抢占,没办法,MASTER的state也要设置成BACKUP,也就是说两台keepalived的state都要设置成BACKUP。
具体配置为
  1)两台的state处都修改为backup
  2)最开始最为MASTER的keepalived的在instance配置端加上nopreempt参数,当此keepalived节点挂了,bakcup将抢占为主,原master恢复后不抢占。

六、配置脚本keepalived不争抢资源功能

# cat /etc/keepalived/keepalived.conf

! Configuration File for keepalived
global_defs {
notification_email {
root@chinasoft.com
}
notification_email_from haproxy-ha@chinasoft.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id haproxy-ha
}
vrrp_script chk_haproxy {
script "/etc/keepalived/scripts/haproxy_chk.sh"
interval 5
weight -2
} vrrp_instance VI_1 {
interface eth0
state BACKUP # 两个keepalived节点初始状态都配置为BACKUP
virtual_router_id 240
priority 100
advert_int 5
nopreempt # 两个keepalived节点都添加不争抢资源选项
authentication {
auth_type PASS
auth_pass haproxy_ha
} virtual_ipaddress {
192.168.3.201
192.168.3.202
} track_script {
chk_haproxy
} }

七、裂脑
7.1 解释裂脑

  在“双机热备”高可用(HA)系统中,当联系2个节点的“心跳线”断开时,本来为一整体、动作协调的HA系统,就分裂成为2个独立的个体。由于相互失去了联系,都以为是对方出了故障,2个节点上的HA软件像“裂脑人”一样,“本能”地争抢“共享资源”、争起“应用服务”,就会发生严重后果:或者共享资源被瓜分、2边“服务”都起不来了;或者2边“服务”都起来了,但同时读写“共享存储”,导致数据损坏(常见如数据库轮询着的联机日志出错)。
  运行于备用主机上的Heartbeat可以通过以太网连接检测主服务器的运行状态,一旦其无法检测到主服务器的“心跳”则自动接管主服务器的资源。通常情况下,主、备服务器间的心跳连接是一个独立的物理连接,这个连接可以是串行线缆、一个由“交叉线”实现的以太网连接。Heartbeat甚至可同时通过多个物理连接检测主服务器的工作状态,而其只要能通过其中一个连接收到主服务器处于活动状态的信息,就会认为主服务器处于正常状态。从实践经验的角度来说,建议为Heartbeat配置多条独立的物理连接,以避免Heartbeat通信线路本身存在单点故障。

7.2 产生裂脑的原因

高可用服务器之间心跳线链路故障,导致无法正常通信
1)心跳线坏了(线路老化或者意外断了)
2)网卡及相关驱动坏了,IP配置及冲突问题,网卡直连
3)心跳线间链接的设备故障(网卡及交换机)
4)仲裁的机器或者仲裁方案出问题
高可用服务器对上开启了iptables防火墙阻挡了信条消息传输
高可用服务器对上心跳网卡地址等信息配置不争取额,导致发送心跳失败
启发服务配置不当等原因,如心跳方式不同,心跳广播冲突,软件BUG等
7.3 防止发生裂脑的措施

同时使用穿线电缆和以太网电缆连接,同时用两条线路,这样一条线路坏了,另一个还是好的,依然能传送心跳信息。
当检测到裂脑时强行关闭一个心跳节点,需要特殊设备(Stonith,fence)。相当于程序上备节点发现心跳线故障,发送关机命令到主节点。
做好对脑力额的监控报警(邮件短信值班等),发生问题时人为第一时间介入仲裁,降低损失。当然,在实施高可用方案时,要根据业务需求确定是否能容忍这样的损失,对于一般的网站常规业务,这个损失是可控的。
启用磁盘锁,正在服务一方锁主共享磁盘,裂脑发生时,让对方完全无法抢占。

学习Keepalived(二)的更多相关文章

  1. crawler4j 学习(二)

    crawler4j 学习(二) 实现控制器类以制定抓取的种子(seed).中间数据存储的文件夹.并发线程的数目: public class Controller { public static voi ...

  2. 从零开始学习jQuery (二) 万能的选择器

    本系列文章导航 从零开始学习jQuery (二) 万能的选择器 一.摘要 本章讲解jQuery最重要的选择器部分的知识. 有了jQuery的选择器我们几乎可以获取页面上任意的一个或一组对象, 可以明显 ...

  3. Android Animation学习(二) ApiDemos解析:基本Animators使用

    Android Animation学习(二) ApiDemos解析:基本Animatiors使用 Animator类提供了创建动画的基本结构,但是一般使用的是它的子类: ValueAnimator.O ...

  4. AspectJ基础学习之二搭建环境(转载)

    AspectJ基础学习之二搭建环境(转载) 一.下载Aspectj以及AJDT 上一章已经列出了他的官方网站,自己上去download吧.AJDT是一个eclipse插件,开发aspectj必装,他可 ...

  5. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  6. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  7. MyBatis学习系列二——增删改查

    目录 MyBatis学习系列一之环境搭建 MyBatis学习系列二——增删改查 MyBatis学习系列三——结合Spring 数据库的经典操作:增删改查. 在这一章我们主要说明一下简单的查询和增删改, ...

  8. MyBatis学习 之 二、SQL语句映射文件(2)增删改查、参数、缓存

    目录(?)[-] 二SQL语句映射文件2增删改查参数缓存 select insert updatedelete sql parameters 基本类型参数 Java实体类型参数 Map参数 多参数的实 ...

  9. MyBatis学习 之 二、SQL语句映射文件(1)resultMap

    目录(?)[-] 二SQL语句映射文件1resultMap resultMap idresult constructor association联合 使用select实现联合 使用resultMap实 ...

  10. UML学习(二)-----类图

    UML学习(二)-----类图 http://www.cnblogs.com/silent2012/archive/2011/09/07/2169946.html http://www.cnblogs ...

随机推荐

  1. BI工具的选择标准有哪些?

    作为企业的IT部门如果没有良好的BI工具支持,IT部门将会十分容易陷入困境.那么面对多元化的BI工具市场,IT部门如何选择BI工具呢?BI工具选择的标准又是什么?Smartbi将为大家做一个简单的解答 ...

  2. 如何搭建老板想要的dashborad管理驾驶舱,这篇文章值得一看!

    随着企业管理向精细化发展和信息化步伐的加快,企业采集到的市场客户及内部管理数据越来越多.越来越趋向于实时,系统大量的信息给企业带来了一个问题:管理者怎么用这些数据才能掌握企业动态,做出及时关键的决策? ...

  3. Hive常用函数大全-字符串函数

    1.字符串长度函数:length(X)(返回字符串X的长度) select length('qwerty') from table --6 2.字符串反转函数:reverse(X)(返回字符串X反转的 ...

  4. 无法将具有语句体的lambda表达式转换为表达式树

    很早就碰到了这个问题,当时也没有深入的研究,趁着空闲,遂把这个问题研究清楚. (一)普通案例 下面从一个普通的案例入手,下面准备两个List集合,都是放在内存里面的(需要模拟到远端执行的时候,我们是通 ...

  5. 经验分享:分析如何使程序在Linux下后台运行---Linux就该这么学!

    转至:https://www.cnblogs.com/maoju/p/13848740.html 一.为什么要使程序在后台执行   我们计算的程序都是周期很长的,通常要几个小时甚至一个星期.我们用的环 ...

  6. Linux系统最重要的工具——Shell学习笔记

    一.为什么学习Shell脚本语言 1.Shell脚本语言是实现Linux/UNIX系统管理及自动化运维必备的重要工具,Linux/UNIX系统底层及 基础应用软件的核心大都涉及Shell脚本的内容. ...

  7. oj教程--学习顺序

    1.数组 2.排序 3.递归 4.栈 5.队列 6.链表 7.二叉树 8.大数或高精度 9.枚举 10.搜索 11.字符串问题 12.贪心 13.最短路径 14.动态规划

  8. Java课程设计---新建项目及导入如何jar包

    1.新建项目 2.添加lib并导入mysql驱动jar包 3.项目目录结构介绍 为了将项目划分清楚,下面将新建如下几个包

  9. Spark分区数、task数目、core数目、worker节点数目、executor数目梳理

    Spark分区数.task数目.core数目.worker节点数目.executor数目梳理 spark隐式创建由操作组成的逻辑上的有向无环图.驱动器执行时,它会把这个逻辑图转换为物理执行计划,然后将 ...

  10. Python:输入关键字进行百度搜索并爬取搜索结果

    学习自:手把手教你用Python爬取百度搜索结果并保存 - 云+社区 - 腾讯云 如何利用python模拟百度搜索,Python交流,技术交流区,鱼C论坛 指定关键字,对其进行百度搜索,保存搜索结果, ...