keeplived

1.全局定义(globaldefinnition)

这一部分用来设置keepalived的故障通知机制和RouterID标识。

示例:

  1. Configuration File for keepalived
  2. global_defs {
  3. notification-email
  4. [897959443@qq.com](mailto:897959443@qq.com) #需要抵达的邮箱地址
  5. [xilingkunpeng@hotmail.com](mailto:xilingkunpeng@hotmail.com) #需要抵达的邮箱地址
  6. }
  7. notification_email_from [897959443@qq.com](mailto:897959443@qq.com) #用于发送的邮箱
  8. smtp_server smtp.qq.com #stmp服务器
  9. smtp_connect_timeout 30 #设置超时时间
  10. router_id LVS_DEVEL #keepalived路由标识(router_id)。在统一局域网内,这个标识应该是唯一的。

大括号“{}”用于分割区块,需要成对出现。如果少了半个,keepalived也不会报错,但也得不到预期效果。

2.VRRP实例定义区块部分

这个部分主要用来定义具体服务的实例配置,包括Keepalived主备状态、接口、优先级、认证方式和IP信息等。

示例:

定义一个vrrp_instance实例,名字是VI_1,每个vvrp_instance实例都可以认为是Keepalived中的一个业务服务。

keepalived中可以有多个这一的实例,备节点也要存在相同的实例才能进行故障切换接管。

vrrp_instance VI_1 {    

  state MASTER     #角色为master,其他节点应当为BACKUP,才能进行顺利的故障接管

  interface ens33    #网络通信接口,要确定好具体是哪一块网卡


  \#虚拟路由ID,这个标识最好是一个数字,并且在一keepalived中是唯一的。

\#但是MASTER和BACKUP中保持一致,否则会出现”脑裂”问题。

  virtual_router_id 51  

  priority 100      #优先级/权重为100,master要比backup大

  advert_int 1       #同步时间间隔,master和bakcup之间的通信检查时间,默认为1s


\#往下都是权限认证配置,包括认证类型(auth_type)和认证密码(auth_pass),认证类型有PASS(Simple Passwd(suggested))。

\#AH(ipasec(not recommended))两种,官方推荐类型为PASS。密码为明文模式,最好不要超过8个字符,推荐用4个字符。
 \#同一VRRP实例的master和backup使用相同密码才能通信。

  authentication {  

    auth_type PASS

    auth_pass 123456    //定义密码,这个密码自定义

  }

\#虚拟IP(VIP)地址,可以配置多个虚拟IP(VIP)。
 \#配置时,最好指定子网掩码和VIP绑定的网络接口,否则默认验码是32位。绑定的网卡要和前面的interface保持一直。

\#这里就是和我们工作中需要和域名绑定的IP,即和配置的高可用服务监听保持一直。

  virtual_ipaddress {

    192.168.1.10  #定义VIP_1

    192.168.1.20  #定义VIP_2

    192.168.1.30  #定义VIP_3

  }

  track_script {

    chk_nginx   //定义监控脚本,这里和上面vrr_script后面的字符串保持一致

  }

}

3.高可用单实例

3.1 配置主机

切换目录

cd /etc/keepalived/

备份配置文件

cp keepalived.conf{,.ori}

清空配置文件

\>keepalived.conf

编写配置文件

vim keeplived.conf

配置文件内容

global_defs {

  router_id web01       #<== ID为web01,不同的keepalived.conf此ID要唯一。

}

vrrp_instance VI_1 {       #<== 实例名字为VI_1,相同实例的备节点名字要和这个相同。

  state MASTER         #<== 状态为MASTER,备节点状态要为BACKUP。

  interface ens33       #<== 通信接口为ens33,对于此参数,备节点和主节点相同。

  virtual_router_id 51      #<== 实例ID为51,在同一keepalived.conf配置文件内是唯一。

  priority 150          #<== 优先级为150,备节点的优先级要小于主节点的优先级。

  advert_int 1         #<== 通信检查时间间隔1秒。

  authentication {  

    auth_type PASS     #<== PASS认证类型,对于此参数,备节点设置要和主节点相同。

    auth_pass 123456    #<== 密码是123456,对于此参数,备节点设置要和主节点相同。

  }

  virtual_ipaddress {

    192.168.1.120 dev ens33 label eth33:0

\#<== 虚拟IP,即VIP,子网验码为24位,绑定接口为eth0,别名为eth33:0,对于此参数,备节点要和主系欸但设置相同。

  }

}

\#提示:此处设置的虚拟IP为192.168.1.120,即为域名网站绑定的IP。

检查并启动keepalived

ps -ef |grep keep|grep -v grep
systemctl start keepalived
ps -ef |grep keep|grep -v grep

检查IP情况

ip addr|grep 192.168.1.120

3.2 配置备机

切换目录

cd /etc/keepalived/

备份配置文件

cp keepalived.conf{,.ori}

清空配置文件

\>keepalived.conf

编写配置文件

vim keeplived.conf

配置文件内容

global_defs {

  router_id web02       #<== ID为web02,不同的keepalived.conf此ID要唯一。

}

vrrp_instance VI_1 {       #<== 实例名字为VI_1,相同实例的备节点名字要和这个相同。

  state MASTER         #<== 状态为MASTER,备节点状态要为BACKUP。

  interface ens33       #<== 通信接口为ens33,对于此参数,备节点和主节点相同。

  virtual_router_id 51      #<== 实例ID为51,在同一keepalived.conf配置文件内是唯一。

  priority 100          #<== 优先级为100,备节点的优先级要小于主节点的优先级。

  advert_int 1         #<== 通信检查时间间隔1秒

  authentication {  

    auth_type PASS     #<== PASS认证类型,对于此参数,备节点设置要和主节点相同。

    auth_pass 123456    #<== 密码是123456,对于此参数,备节点设置要和主节点相同。

  }

  virtual_ipaddress {

    192.168.1.120 dev ens33 label eth33:0

\#<== 虚拟IP,即VIP,子网验码为24位,绑定接口为eth0,别名为eth33:0,对于此参数,备节点要和主系欸但设置相同。

  }

}

\#提示:此处设置的虚拟IP为192.168.1.120,即为域名网站绑定的IP。

检查并启动keepalived

ps -ef |grep keep|grep -v grep
systemctl start keepalived
ps -ef |grep keep|grep -v grep

这里因为没有接管,所以不应该有返回

如果有,就证明脑裂了。1

1.检查通信情况,iptables/firewalld

2.检查配置文件,例如virtual_router_id是否不一致

ip addr|grep 192.168.1.120

3.3 高可用测试

暂停主节点keepalived服务或关机

systemctl stop keepalived
or
shutdown -h now

分别在主节点和备节点上检查ip状态(若主节点已关机则不用检查主节点)

备节点应该拿到了VIP

ip addr|grep 192.168.1.120

重启主节点服务

systemctl start keepalived

检查VIP状态,主节点应当拿回了VIP

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

4.”脑裂”问题

4.1 什么是脑裂

在指定时间内两台高可用服务无法检测到对他心跳消息,各自取得资源以及服务所有权,而此时两台高可用服务器都会去抢占同样的资源,这样会导致同一个IP或服务在两端同时存在发生冲突,最严重的就是两台主机抢占同一个IVP地址,当用户写入数据时,可能会分别写入两端,造成两端数据不一致或数据丢失,这种情况就被成为脑裂。

4.2 导致脑裂发生的原因

常见原因:

(1)高可用服务器之间对心跳链路故障,导致无法正常通信。

□心跳线坏了(断裂、老化)

□网卡以及相关驱动坏了,IP配置以及冲突问题(网卡直连)

□心跳线之间连接设备故障(网卡及交换机)

□仲裁机器出问题(采用仲裁方案)

(2)高可用服务器对上开启了iptables防火墙阻挡了心跳消息传输

(3)高可用服务器上心跳网卡地址等信息配置不正确

(4)其他服务配置不当等原因,如心跳方式不同、心跳广播冲突、软件BUG等

(5)同一VRRP实例virtual_router_id参数两端配置不一样

4.3 解决脑裂常见方案

(1)使用串行电缆和一台电缆链接,同时使用两条心跳线路,做线路高可用。

(2)检测到脑裂时强行关闭一个心跳节点(需要特殊设备支持,如Stonith、fence)。相当于备节点收不到心跳消息,发送关机命令通过单路的线路来关闭

(3)做好对脑裂的状态监控(邮件、手机短信、值班)报警,发生脑裂时第一时间人为介入仲裁。如百度的报警短信可以区分上下行,管理员可以通过短信回复数字或字符串返回给服务器,让服务器根据指令自动操作。或者开发简单app,第一时间点点点操作。

4.4 常见的keepalived脑裂解决方案

互联网应用服务器,前端web负载均衡的的高可用,对于普通业务一般是可以接受的,对于数据库和存储服务不可以接受。

□如果开启防火墙,一定要开放心跳消息通过,一般采用定向IP段可通过。

□可以拉一条以太网线或者串口线作为线路冗余

□开发监测程序通过监控软件(如Nagios)监测脑裂

生产判断脑裂思路:

(1)简单思路:备节点出现VIP就报警,有两种情况,一是主节点宕机了,备节点接管;二是主机没宕,脑裂了,无论是哪一种都要进行报警,然后人工查看。

(2)严谨思路:备节点出现VIP,主节点以及对应服务任然存活,说明脑裂了

5.Keepalived双实例双主机配置

5.1 规划

HOSTNAME IP 说明
web01 192.168.1.55 VIP:192.168.1.100(绑定A服务 www.hanpi.com)
web02 192.168.1.56 VIP:192.168.1.101(绑定B服务 bbs.91sepi.com)

5.2 配置web01

在原来的单实例基础上增加一个实例(至于你们怎么搭建服务,我建议用nginx测试)

global_defs {

  router_id web01       

}

vrrp_instance VI_1 {       

  state MASTER         

  interface ens33       

  virtual_router_id 51      

  priority 150          

  advert_int 1         

  authentication {  

    auth_type PASS     

    auth_pass 1234     

  }

  virtual_ipaddress {

    192.168.1.100 dev ens33 label eth33:0

  }

}



vrrp_instance VI_2 {       

  state BACKUP         

  interface ens33       

  virtual_router_id 52      

  priority 100          

  advert_int 1         

  authentication {  

    auth_type PASS     

    auth_pass 5678     

  }

  virtual_ipaddress {

    192.168.1.101 dev ens33 label eth33:1

  }

}

5.3 配置web02

建议直接scp然后改一改

global_defs {

  router_id web02       

}

vrrp_instance VI_1 {       

  state BACKUP         

  interface ens33       

  virtual_router_id 51      

  priority 100          

  advert_int 1         

  authentication {  

    auth_type PASS     

    auth_pass 1234     

  }

  virtual_ipaddress {

    192.168.1.100 dev ens33 label eth33:0

  }

}



vrrp_instance VI_2 {       

  state MASTER         

  interface ens33       

  virtual_router_id 52      

  priority 150          

  advert_int 1         

  authentication {  

    auth_type PASS     

    auth_pass 5678     

  }

  virtual_ipaddress {

    192.168.1.101 dev ens33 label eth33:1

  }

}

5.4 web01、web02上都重启服务

systemctl rstart keepalived

5.5 web01、web02分别查看ip

ip add|egrep “192.168.1.100|192.168.1.101”

5.6 轮流暂停keepalived服务,同时查看未暂停服务的web服务器,是否拿到了了IP

其中一个暂停了服务,另一个服务器应当会拿到两个ip

systemctl stop keepalived

ip add|egrep “192.168.1.100|192.168.1.101”

5.7 在停止服务的服务器上,重新启动之前暂停的服务,再次查看

应当看到服务器把ip拿回来了

ip add|egrep “192.168.1.100|192.168.1.101”

5.8 配置区别

web01 web02
state MASTER state BACKUP
priority 150 priority 100
state BACKUP state MASTER
priority 100 priority 150

5.9 主要区别

□state(状态)

□priority(权重/优先级)

优先级决定了VIP在哪个机器上初始运行

6.Nginx配合Keeplived

6.1 逻辑架构图

img

6.2 配置两边nginx

cd /pwd/nginx/conf/

vim nginx.conf

nginx内容

worker_processes 1;

events {

  worker_connections 1024;

}

http {

  include    mime.types;

  default_type   /pwd/octet-stream;

  sendfile   on;

  keepalive_timeout  65;

  upstream www_pools {          #<== 这里定义了web服务器池,包含了100、101两个web节点。



    server 192.168.1.100:80 weight=1;

    server 192.168.1.101:80 weight=1;

  }

  server {                 #<== 这里定义了代理的负载均衡域名虚拟主机。

   listen      192.168.1.55:80;      #<==这里指定了IP监听。

   server_name [www.hanpi.com](http://www.hanpi.com);

   location / {

   proxy_pass  https://www_pools;     #<== 访问[www.hanpi.com](http://www.hanpi.com),请求发送给www_pools里面的节点。



   proxy_set_header  Host  $host;

   }

  }

}

6.3 配置keepalived服务

6.3.1 配置web01

global_defs {

  router_id web01       

}

vrrp_instance VI_1 {       

  state MASTER         

  interface ens33       

  virtual_router_id 51      

  priority 150          

  advert_int 1         

  authentication {  

    auth_type PASS     

    auth_pass 1234     

  }

  virtual_ipaddress {

    192.168.1.100 dev ens33 label eth33:0

  }

}

6.3.2 配置web02

global_defs {

  router_id web02       

}

vrrp_instance VI_1 {       

  state BACKUP         

  interface ens33       

  virtual_router_id 51      

  priority 100          

  advert_int 1         

  authentication {  

    auth_type PASS     

    auth_pass 1234     

  }

  virtual_ipaddress {

    192.168.1.100 dev ens33 label eth33:0

  }

}

6.4 配置DNS解析

192.168.1.100 [www.hanpi.com](http://www.hanpi.com)

6.5 两边重启nginx服务

在web页面进入www.hanpi.com

此时关闭web01高可用服务或者关闭服务器

在nginx页面刷新页面

6.6 查看web02的IP状态

ip addd|grep 192.168.1.100

6.7 开启web01,查看ip

ip addd|grep 192.168.1.100

web重新访问 www.hanpi.com

状态应该处于正常

7.监听网卡上不存在的IP地址

如果配置使用了”listen 192.168.1.100:80;“ 指定IP监听服务,而本地上没有这个IP,nginx就会报错。

如果实施双主(即主备)同时提供不同的服务,配置文件里制定了IP监听,备节点就会因为网卡不存在实际IP而报错。

出现上面的问题原因在于物理网卡上没有与配置文件里监听的IP相对应的IP,我们要让Nginx服务在网卡上没有指定监听的IP时也能启动,不报错。

7.1 解决办法是在/etc/sysctl.conf中加入如下内核参数。

net.ipv4.ip_nonlocal_bind = 1

表示启动nginx而忽略配置中监听的ip是否存在,同样适用于Haproxy。

7.2 快速写入

echo “net.ipv4.ip_nonlocal_bind = 1” >> /etc/sysctl.conf

7.3 刷新生效

sysctl -p

8.解决服务宕后keepalived仍运行

默认情况下,Keepalived软件只有在对方机器宕机或者Keepalived停止的时候会接管业务。生产环境中,有业务服务停止的Keepalived还在工作的情况,这种时候就会造成数据丢失。

8.1 方法一:

写守护进程脚本来处理。当Nginx业务出现问题时,就停掉本地的Keepalived服务,实现飘逸接管。

8.1.1 编写脚本

vim /pwd/check_nginx.sh

8.1.2 脚本内容

#!/bin/sh

while true

do

  if [ ‘netstat -lntup|grep nginx|wc -l’-ne 1 ];then

      systemctl stop keepalived

      break

  fi

    sleep 5

done

8.1.3 启动脚本

sh /pwd/check_nginx.sh &

8.1.4 检查脚本运行情况

ps -ef | grep check

8.1.5 查看端口

lsof -I :80

8.1.6 停止nginx,查看是否切换

systemctl stop nginx

8.1.7 查看nginx状态

systemctl status nginx

8.1.8 再次检查nginx

netstat -lntup|grep nginx

8.1.9 在备节点上查看

ip add|grep 192.168.1.100

8.2 方法二:

8.2.1 使用keepalived的配置文件参数触发脚本

vim check_nginx_proxy.sh

8.2.2 脚本内容

#!/bin/sh

if [ ‘netstat -lntup|grep nginx|wc -l’ -ne 1 ];then

  system stop keeplived

fi

8.2.3 授权

chmod +x check_nginx_proxy.sh

8.2.4 检查授权

ls -l check_nginx_proxy.sh

8.2.5 keepalived配置如下

global_defs {

  router_id web01       

}

vrrp_script chk_nginx_proxy{         #<== 定义VRRP脚本,检查HTTP端口。

  script “/pwd/check_nginx_proxy.sh”  #<== 执行脚本,当Nginx服务器出现问题时,就停掉Keepalived服务。



  interval 2             #<== 时间间隔2s。

  weight 2

}



vrrp_instance VI_1 {       

  state MASTER         

  interface ens33       

  virtual_router_id 51      

  priority 150        

  advert_int 1         

  authentication {  

    auth_type PASS     

    auth_pass 1234     

  }

  virtual_ipaddress {

    192.168.1.100 dev ens33 label eth33:0

  }

  tarck_script {

  check_nginx_proxy         #<== 触发检查。

  }

}

8.2.6 测试脚本

8.2.6.1 检查端、服务、ip
lsof -i :80

ps -ef | grep keep

ip add|grep 192.168.1.100

8.2.6.2 停止nginx服务
systemctl stop nginx

8.2.6.3 再次检查
lsof -i :80

ps -ef | grep keep

ip add|grep 192.168.1.100

8.2.6.4 查看日志
cat /var/log/messages | grep Keepalived

9.多组Keepalived局域网内冲突

如果在同一局域网内部署了多组Keepalived服务器,而又未使用专门的心跳线通信时,可能会发生接管故障。

Keepalived高可用是通过VRRP协议实现的,VRRP协议默认通过IP多播实现的高可用服务对之间的通信,如果一个局域网内存在多组Keepalived服务器对,就会造成IP多播地址冲突问题,不同组的Keepalived都会使用默认的224.0.0.18作为多播地址。

所以我们需要在同组Keepalived服务器的所有配置文件中指定独立的多播地址。

9.1 指定多播地址 示例:

global_defs {

  router_id LVS_01

  vrrp_mcast_group4 224.0.0.20      #<== 这玩意就是多播地址

}

10.指定配置文件接收Keepalived服务日志

日志集成,懂得都懂

将KEEPALIVED_OPTIONS=”-D” 修改为 KEEPALIVED_OPTIONS=”-D -d -S 0”

vim /ect/sysconfig/keepalived

10.1 修改keepalived配置文件

10.1.1 快速替换

sed -i ’14 s# KEEPALIVED_OPTIONS=”-D”# KEEPALIVED_OPTIONS=”-D -d -S 0”#g’ /etc/sysconfig/keepalived

10.1.2 检查

sed -n ‘14p’ /etc/sysconfig/keepalived

说明,查看 /etc/sysconfig/keepalived 里注释获得以上说明

—dump-conf -d 导出备份数据。

—log-detail -D 详细日志。

—log-facility -S 设置本地的syslog设备,编号0-7(default=LOG_DAEMON)。

-S 0 表示指定为local0设备。

10.2 修改系统日志配置文件

10.2.1 修改rsslog配置文件

vim /etc/rsyslog.conf

10.2.2 尾部添加以下两行内容

这两行表示local0设备的所有日志信息都记录到了 /var/log/keepalived.log 文件

#keepalived

local0.*       /var/log/keepalived.log

10.2.3 在如下信息的第一列尾部添加”;local0.none”,注意有分号。

表示来自local0设备的所有日志信息不再记录与/var/log/messages

*.info;mail.one;authpriv.none;cron.none;local0.none /var/log/messages

10.2.4 配置完成,重启rsyslog服务

systemctl restart rsyslog.service

10.2.5 重启keepaliaved,查看日志

systemctl restart keepalived

tail -f /var/log/keepalived.log

可以在/var/log/messages上设置对/avr/log/keepalived.log进行轮询,防止单个日志文件变大

11.编写监测Keepalived “脑裂”的脚本

检测思路:在备节点上执行脚本,如果可以ping通主节点并且备节点有VIP就报警,人工介入检查是否发生了”脑裂”。

11.1 编写脚本

vim check_split_brain.sh

脚本内容

#!/bin/sh

web01_vip = 192.168.1.100

web01_ip = 192.168.1.55

while true

do

ping -c 2 -W3 $web01_ip &>/dev/null

  if [ $? -eq 0 -a ‘ip add|grep “web01_ip”|wc -1’ -eq 1 ]

    then

      echo “ha is split brain.waring.”

else

      echo “hs is ok”

fi

sleep 5

done

11.2 测试脚本

sh check_split_brain.sh

11.2.1 关闭web01,查看web02报警情况

shutdown -h now

or

systemctl stop nginx

11.2.2 web02报警正常,重启web01服务,查看恢复情况

systemctl start nginx

11.2.3 测试完成后整合到Nagios或者Zabbix里