三.keepalived介绍及工作原理

一、keepalived的介绍

Keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP功能。因此,Keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx、Haproxy、MySQL等)的高可用解决方案软件。

Keepalived软件主要是通过VRRP协议实现高可用功能的。VRRP是Virtual Router Redundancy Protocol(虚拟路由器冗余协议)的缩写,VRRP出现的目的就是为了解决静态路由单点故障问题的,它能够保证当个别节点宕机时,整个网络可以不间断地运行。所以,Keepalived一方面具有配置管理LVS的功能,同时还具有对LVS下面节点进行健康检查的功能,另一方面也可实现系统网络服务的高可用功能。

keepalived:
    vrrp协议:Virtual Router Redundancy Protocol
术语:
  虚拟路由器:Virtual Router
  虚拟路由器标识:VRID(0-255),唯一标识虚拟路由器
  物理路由器:
  master:主设备
  backup:备用设备
  priority:优先级
  VIP:Virtual IP
  VMAC:Virutal MAC (00-00-5e-00-01-VRID)
通告:心跳,优先级等;周期性
工作方式:抢占式,非抢占式
安全工作:
  认证:
  无认证
  简单字符认证:预共享密钥
  MD5
工作模式:
  主/备:单虚拟路径器
  主/主:主/备(虚拟路径器1),备/主(虚拟路径器2)

二、Keepalived服务的重要功能

1、管理LVS负载均衡软件

早期的LVS软件,需要通过命令行或脚本实现管理,并且没有针对LVS节点的健康检查功能。为了解决LVS的这些使用不便的问题,Keepalived就诞生了,可以说,Keepalived软件起初是专为解决LVS的问题而诞生的。因此,Keepalived和LVS的感情很深,它们的关系如同夫妻一样,可以紧密地结合,愉快地工作。Keepalived可以通过读取自身的配置文件,实现通过更底层的接口直接管理LVS的配置以及控制服务的启动、停止等功能,这使得LVS的应用更加简单方便了。

2、实现对LVS集群节点健康检查功能(healthcheck)

Keepalived可以通过在自身的keepalived.conf文件里配置LVS的节点IP和相关参数实现对LVS的直接管理;除此之外,当LVS集群中的某一个甚至是几个节点服务器同时发生故障无法提供服务时,Keepalived服务会自动将失效的节点服务器从LVS的正常转发队列中清除出去,并将请求调度到别的正常节点服务器上,从而保证最终用户的访问不受影响;当故障的节点服务器被修复以后,Keepalived服务又会自动地把它们加入到正常转发队列中,对客户提供服务。

3、作为系统网络服务的高可用功能(failover)

Keepalived可以实现任意两台主机之间,例如Master和Backup主机之间的故障转移和自动切换,这个主机可以是普通的不能停机的业务服务器,也可以是LVS负载均衡、Nginx反向代理这样的服务器。

Keepalived高可用功能实现的简单原理为,两台主机同时安装好Keepalived软件并启动服务,开始正常工作时,由角色为Master的主机获得所有资源并对用户提供服务,角色为Backup的主机作为Master主机的热备;当角色为Master的主机失效或出现故障时,角色为Backup的主机将自动接管Master主机的所有工作,包括接管VIP资源及相应资源服务;而当角色为Master的主机故障修复后,又会自动接管回它原来处理的工作,角色为Backup的主机则同时释放Master主机失效时它接管的工作,此时,两台主机将恢复到最初启动时各自的原始角色及工作状态。

三、Keepalived高可用故障切换转移原理

Keepalived高可用服务对之间的故障切换转移,是通过VRRP(Virtual Router Redundancy Protocol,虚拟路由器冗余协议)来实现的。

在Keepalived服务正常工作时,主Master节点会不断地向备节点发送(多播的方式)心跳消息,用以告诉备Backup节点自己还活着,当主Master节点发生故障时,就无法发送心跳消息,备节点也就因此无法继续检测到来自主Master节点的心跳了,于是调用自身的接管程序,接管主Master节点的IP资源及服务。而当主Master节点恢复时,备Backup节点又会释放主节点故障时自身接管的IP资源及服务,恢复到原来的备用角色。

 

四、keepalived的工作原理

1、Keepalived高可用对之间是通过VRRP通信的

1)VRRP,全称Virtual Router Redundancy Protocol,中文名为虚拟路由冗余协议,VRRP的出现是为了解决静态路由的单点故障。

2)VRRP是通过一种竞选协议机制来将路由任务交给某台VRRP路由器的。

3)VRRP用IP多播的方式(默认多播地址(224.0.0.18))实现高可用对之间通信。

4)工作时主节点发包,备节点接包,当备节点接收不到主节点发的数据包的时候,就启动接管程序接管主节点的资源。备节点可以有多个,通过优先级竞选,但一般Keepalived系统运维工作中都是一对。

5)VRRP使用了加密协议加密数据,但Keepalived官方目前还是推荐用明文的方式配置认证类型和密码。

2、Keepalived服务的工作原理

1)Keepalived高可用对之间是通过VRRP进行通信的,VRRP是通过竞选机制来确定主备的,主的优先级高于备,因此,工作时主会优先获得所有的资源,备节点处于等待状态,当主挂了的时候,备节点就会接管主节点的资源,然后顶替主节点对外提供服务。

2)在Keepalived服务对之间,只有作为主的服务器会一直发送VRRP广播包,告诉备它还活着,此时备不会抢占主,当主不可用时,即备监听不到主发送的广播包时,就会启动相关服务接管资源,保证业务的连续性。接管速度最快可以小于1秒。

keepalived:
  vrrp协议的软件实现,原生设计目的为了高可用ipvs服务
功能:
  1、vrrp协议完成地址流动
  2、为vip地址所在的节点生成ipvs规则(在配置文件中预先定义)
  3、为ipvs集群的各RS做健康状态检测
  4、基于脚本调用接口通过执行脚本完成脚本中定义的功能,进而影响集群事务,以此支持nginx、haproxy等服务

五、keepalived配置文件说明

1、HA Cluster 配置准备:

(1) 各节点时间必须同步:ntp, chrony
(2) 确保iptables及selinux不会成为阻碍
(3) 各节点之间可通过主机名互相通信(对KA并非必须):建议使用/etc/hosts文件实现
(4) 各节点之间的root用户可以基于密钥认证的ssh服务完成互相通信(对KA并非必须)

2、keepalived的安装包及程序环境

  keepalived.x86_64 0:1.3.5-16.el7 

程序环境:

主配置文件:/etc/keepalived/keepalived.conf
主程序文件:/usr/sbin/keepalived
Unit File:/usr/lib/systemd/system/keepalived.service
Unit File的环境配置文件:/etc/sysconfig/keepalived

3、配置文件组成:

TOP HIERACHY
  GLOBAL CONFIGURATION
  Global definitions
     Static routes/addresses
  VRRPD CONFIGURATION
  VRRP synchronization group(s):vrrp同步组
  VRRP instance(s):即一个vrrp虚拟路由器
LVS CONFIGURATION
  Virtual server group(s)
  Virtual server(s):ipvs集群的vs和rs

4、配置语法

配置虚拟路由器:
vrrp_instance <STRING> {
....
}
#专用参数:
#state MASTER|BACKUP:当前节点在此虚拟路由器上的初始状态;只能有一个是MASTER,余下的都应该为BACKUP
#interface IFACE_NAME:绑定为当前虚拟路由器使用的物理接口
#virtual_router_id VRID:当前虚拟路由器惟一标识,范围是0-255
#priority 100:当前物理节点在此虚拟路由器中的优先级;范围1-254
#advert_int 1:vrrp通告的时间间隔,默认1s

authentication { #认证机制
  auth_type AH|PASS
  auth_pass <PASSWORD> 仅前8位有效
}
virtual_ipaddress { #虚拟IP
  <IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>
  192.168.200.17/24 dev eth1
  192.168.200.18/24 dev eth2 label eth2:1
}
track_interface { #配置监控网络接口,一旦出现故障,则转为FAULT状态 实现地址转移
  eth0
  eth1
  …
}

#nopreempt:定义工作模式为非抢占模式
#preempt_delay 300:抢占式模式,节点上线后触发新选举操作的延迟时长,默认模式

#定义通知脚本:
#notify_master <STRING>|<QUOTED-STRING>:
#当前节点成为主节点时触发的脚本

#notify_backup <STRING>|<QUOTED-STRING>:
#当前节点转为备节点时触发的脚本

#notify_fault <STRING>|<QUOTED-STRING>:
#当前节点转为“失败”状态时触发的脚本

#notify <STRING>|<QUOTED-STRING>:
#通用格式的通知触发机制,一个脚本可完成以上三种状态的转换时的通知

5、单主配置示例

5.1MASTER端配置

! Configuration File for keepalived
global_defs {
  notification_email {
    root@localhost
  }
  notification_email_from keepalived@localhost
  smtp_server 127.0.0.1
  smtp_connect_timeout 30
  router_id node1 #主机名,在另一结点为node2
  vrrp_mcast_group4 224.0.100.100
}

vrrp_instance VI_1 {
  state MASTER #在另一个结点上为BACKUP
  interface eth0
  virtual_router_id 6 #多个节点必须相同
  priority 100 #在另一个结点上为90
  advert_int 1 #通告间隔1s
  authentication {
    auth_type PASS #预共享密钥认证
    auth_pass 571f97b2
  }
  virtual_ipaddress {
    172.18.100.66/16 dev eth0 label eth0:0
  }
  track_interface {
    eth0
  }
}

5.2BACKUP端配置

! Configuration File for keepalived
global_defs {
  notification_email {
    root@localhost
  }
  notification_email_from keepalived@localhost
  smtp_server 127.0.0.1
  smtp_connect_timeout 30
  router_id node2 #主机名,在另一结点为node1
  vrrp_mcast_group4 224.0.100.100
}

vrrp_instance VI_1 {
  state BACKUP#在另一个结点上为MASTER
  interface eth0
  virtual_router_id 6 #多个节点必须相同
  priority 90 #在另一个结点上为100
  advert_int 1 #通告间隔1s
  authentication {
    auth_type PASS #预共享密钥认证
    auth_pass 571f97b2
  }
  virtual_ipaddress {
    172.18.100.66/16 dev eth0 label eth0:0
  }
  track_interface {
    eth0
  }
}

6、脚本调用

在vrrp_instance VI_1 语句块最后面加下面行

notify_master "/etc/keepalived/notify.sh master"

notify_backup "/etc/keepalived/notify.sh backup"

notify_fault "/etc/keepalived/notify.sh fault"

master与backup配置一样

! Configuration File for keepalived
global_defs {
  notification_email {
    root@localhost
  }
  notification_email_from keepalived@localhost
  smtp_server 127.0.0.1
  smtp_connect_timeout 30
  router_id node2 #主机名,在另一结点为node1
  vrrp_mcast_group4 224.0.100.100
}

vrrp_instance VI_1 {
  state BACKUP#在另一个结点上为MASTER
  interface eth0
  virtual_router_id 6 #多个节点必须相同
  priority 90 #在另一个结点上为100
  advert_int 1 #通告间隔1s
  authentication {
    auth_type PASS #预共享密钥认证
    auth_pass 571f97b2
  }
  virtual_ipaddress {
    172.18.100.66/16 dev eth0 label eth0:0
  }
  track_interface {
    eth0
  }
  notify_master "/etc/keepalived/notify.sh master"
  notify_backup "/etc/keepalived/notify.sh backup"
  notify_fault "/etc/keepalived/notify.sh fault"
}

通知脚本

#!/bin/bash
#
contact='root@localhost'
notify() {
  mailsubject="$(hostname) to be $1, vip floating"
  mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
  echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
master)
  notify master
  ;;
backup)
  notify backup
  ;;
fault)
  notify fault
  ;;
*)
  echo "Usage: $(basename $0) {master|backup|fault}"
  exit 1
  ;;
esac

7、邮件设置

配置发送邮件的邮箱设置:
vim ~/.mailrc 或 /etc/mail.rc
set from=29308620@qq.com
set smtp=smtp.qq.com
set smtp-auth-user=29308620@qq.com
set smtp-auth-password=lzhdjmtznbftbiai
set smtp-auth=login
set ssl-verify=ignore
测试:echo test mail | mail –s test 29308620@qq.com

8、双主模型示例

node1

! Configuration File for keepalived
global_defs {
  notification_email {
    root@localhost
  }
  notification_email_from keepalived@localhost
  smtp_server 127.0.0.1
  smtp_connect_timeout 30
  router_id node1
  vrrp_mcast_group4 224.0.100.100
  }
  vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 6
    priority 100
    advert_int 1
  authentication {
    auth_type PASS
    auth_pass 571f97b2
  }
  virtual_ipaddress {
    172.16.0.10/16 dev eth0
  }
}

 vrrp_instance VI_2 {
    state BACKUP
    interface eth0
    virtual_router_id 8
    priority 98
    advert_int 1
    authentication {
      auth_type PASS
      auth_pass 578f07b2
    }
    virtual_ipaddress {
      172.16.0.11/16 dev eth0
    }
}

node2

! Configuration File for keepalived
global_defs {
  notification_email {
    root@localhost
  }
  notification_email_from keepalived@localhost
  smtp_server 127.0.0.1
  smtp_connect_timeout 30
  router_id node2
  vrrp_mcast_group4 224.0.100.100
  }
  vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 6
    priority 98
    advert_int 1
  authentication {
    auth_type PASS
    auth_pass 571f97b2
  }
  virtual_ipaddress {
    172.16.0.10/16 dev eth0
  }
}

 vrrp_instance VI_2 {
    state MASTER
    interface eth0
    virtual_router_id 8
    priority 100
    advert_int 1
    authentication {
      auth_type PASS
      auth_pass 578f07b2
    }
    virtual_ipaddress {
      172.16.0.11/16 dev eth0
    }
}

9、虚拟服务器

配置参数:
virtual_server IP port | virtual_server fwmark int
{
...
real_server {
...
}
...
}


delay_loop <INT>:检查后端服务器的时间间隔
lb_algo rr|wrr|lc|wlc|lblc|sh|dh:定义调度方法
lb_kind NAT|DR|TUN:集群的类型
persistence_timeout <INT>:持久连接时长
protocol TCP:服务协议,仅支持TCP
sorry_server <IPADDR> <PORT>:所有RS故障时,备用服务器地址
real_server <IPADDR> <PORT>
{
  weight <INT> RS权重
  notify_up <STRING>|<QUOTED-STRING> RS上线通知脚本
  notify_down <STRING>|<QUOTED-STRING> RS下线通知脚本
  HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHEC K { ... }:定义当前主机的健康状态检测方法
}

HTTP_GET|SSL_GET:应用层检测
HTTP_GET|SSL_GET {
   url {
   path <URL_PATH>:定义要监控的URL
   status_code <INT>:判断上述检测机制为健康状态的响应码
   digest <STRING>:判断为健康状态的响应的内容的校验码
   }
connect_timeout <INTEGER>:连接请求的超时时长
nb_get_retry <INT>:重试次数
delay_before_retry <INT>:重试之前的延迟时长
connect_ip <IP ADDRESS>:向当前RS哪个IP地址发起健康状态检测请求
connect_port <PORT>:向当前RS的哪个PORT发起健康状态检测请求
bindto <IP ADDRESS>:发出健康状态检测请求时使用的源地址
bind_port <PORT>:发出健康状态检测请求时使用的源端口
}

传输层检测 TCP_CHECK
TCP_CHECK {
    connect_ip <IP ADDRESS>:向当前RS的哪个IP地址发起健康状态检测请求
    connect_port <PORT>:向当前RS的哪个PORT发起健康状态检测请求
    bindto <IP ADDRESS>:发出健康状态检测请求时使用的源地址
    bind_port <PORT>:发出健康状态检测请求时使用的源端口
    connect_timeout <INTEGER>:连接请求的超时时长
}

六、示例

6.1单主模型IPVS示例

MASTER节点配置

高可用的ipvs集群示例master节点:
! Configuration File for keepalived
global_defs {
  notification_email {
    root@localhost
  }
  notification_email_from keepalived@localhost
  smtp_server 127.0.0.1
  smtp_connect_timeout 30
  router_id node1
  vrrp_mcast_group4 224.0.100.10
}

vrrp_instance VI_1 {
  state MASTER
  interface eth0
  virtual_router_id 6
  priority 100
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass 571f97b2
  }
  virtual_ipaddress {
     172.16.0.10/16 dev eth0
  }
  notify_master "/etc/keepalived/notify.sh master"
  notify_backup "/etc/keepalived/notify.sh backup"
  notify_fault "/etc/keepalived/notify.sh fault"
  }
  
  virtual_server 172.16.0.10 80 {
    delay_loop 3
    lb_algo rr
    lb_kind DR
    protocol TCP
    sorry_server 127.0.0.1 80
    real_server 172.16.0.11 80 {
      weight 1
      HTTP_GET {
          url {
             path /
             status_code 200
         }
         connect_timeout 1
         nb_get_retry 3
         delay_before_retry 1
     }
    }
  
  
   real_server 172.16.0.12 80 {
      weight 1
      HTTP_GET {
         url {
            path /
            status_code 200
         }
        connect_timeout 1
        nb_get_retry 3
        delay_before_retry 1
      }
   }
}

BACKUP节点

高可用的ipvs集群示例BACKUP节点:
! Configuration File for keepalived
global_defs {
  notification_email {
    root@localhost
  }
  notification_email_from keepalived@localhost
  smtp_server 127.0.0.1
  smtp_connect_timeout 30
  router_id node2 
  vrrp_mcast_group4 224.0.100.10
}

vrrp_instance VI_1 {
  state BACKUP
  interface eth0
  virtual_router_id 6
  priority 90
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass 571f97b2
  }
  virtual_ipaddress {
     172.16.0.10/16 dev eth0
  }
  notify_master "/etc/keepalived/notify.sh master"
  notify_backup "/etc/keepalived/notify.sh backup"
  notify_fault "/etc/keepalived/notify.sh fault"
  }
  
  virtual_server 172.16.0.10 80 {
    delay_loop 3
    lb_algo rr
    lb_kind DR
    protocol TCP
    sorry_server 127.0.0.1 80
    real_server 172.16.0.11 80 {
      weight 1
      HTTP_GET {
          url {
             path /
             status_code 200
         }
         connect_timeout 1
         nb_get_retry 3
         delay_before_retry 1
     }
    }
  
  
   real_server 172.16.0.12 80 {
      weight 1
      HTTP_GET {
         url {
            path /
            status_code 200
         }
        connect_timeout 1
        nb_get_retry 3
        delay_before_retry 1
      }
   }
}

6.2双主模式的lvs集群

 

双主模式的lvs集群,拓扑、实现过程;

 

配置示例(一个节点):

! Configuration File for keepalived
global_defs {
  notification_email {
  root@localhost
  }
  notification_email_from kaadmin@localhost
  smtp_server 127.0.0.1
  smtp_connect_timeout 30
  router_id node1
  vrrp_mcast_group4 224.0.100.100
}

vrrp_instance VI_1 {
  state MASTER
  interface eth0
  virtual_router_id 6
  priority 100
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass f1bf7fde
  }
  virtual_ipaddress {
    172.16.0.80/16 dev eth0 label eth0:0
  }
  
 track_interface {
    eth0
 }
 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 eth0
  virtual_router_id 8
  priority 98
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass f2bf7ade
  }
  
virtual_ipaddress {
  172.16.0.90/16 dev eth0 label eth0:1
}
track_interface {
  eth0
}
  notify_master "/etc/keepalived/notify.sh master"
  notify_backup "/etc/keepalived/notify.sh backup"
  notify_fault "/etc/keepalived/notify.sh fault"
}

virtual_server fwmark 3 {
  delay_loop 2
  lb_algo rr
  lb_kind DR
  nat_mask 255.255.0.0
  protocol TCP
  sorry_server 127.0.0.1 80
  real_server 172.16.0.11 80 {
    weight 1
    HTTP_GET {
      url {
        path /
        status_code 200
      }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 3
  }
}

real_server 172.16.0.12 80 {
  weight 1
  HTTP_GET {
    url {
      path /
      status_code 200
    }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 3
   }
  }
}

七、keepalived调用脚本进行资源监控

1、keepalived调用外部的辅助脚本进行资源监控,并根据监控的结果状态能实现优先动态调整
2、vrrp_script:自定义资源监控脚本,vrrp实例根据脚本返回值,公共定义,可被多个实例调用,定义在vrrp实例之外
3、track_script:调用vrrp_script定义的脚本去监控资源,定义在实例之内,调用事先定义的vrrp_script
4、分两步:(1) 先定义一个脚本;(2) 调用此脚本
vrrp_script <SCRIPT_NAME> {
  script ""
  interval INT
  weight -INT
}
track_script {
  SCRIPT_NAME_1
  SCRIPT_NAME_2
}

示例:高可用nginx服务

! Configuration File for keepalived
global_defs {
  notification_email {
    root@localhost
  }
  notification_email_from keepalived@localhost
  smtp_server 127.0.0.1
  smtp_connect_timeout 30
  router_id node1
  vrrp_mcast_group4 224.0.100.100
}

vrrp_script chk_down {
  script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"
  interval 1
  weight -20
}
vrrp_script chk_nginx {
  script “/usr/bin/killall -0 nginx "
  interval 1
  weight -20
  fall 2 #2次检测失败为失败
  rise 1 #1次检测成功为成功
}

vrrp_instance VI_1 {
  state MASTER
  interface eth0
  virtual_router_id 14
  priority 100
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass 571f97b2
  }
  virtual_ipaddress {
    172.18.0.93/16 dev eth0
  }
  track_script {
    chk_down  #调用前面的vrrp_script chk_down脚本
    chk_nginx #调用前面的vrrp_script chk_nginx脚本
  }
  notify_master "/etc/keepalived/notify.sh master"
  notify_backup "/etc/keepalived/notify.sh backup"
  notify_fault "/etc/keepalived/notify.sh fault"
}

notify.sh脚本

#!/bin/bash
#
contact='root@localhost'
notify() {
  mailsubject="$(hostname) to be $1, vip floating"
  mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
  echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
master)
  notify master
  ;;
backup)
  notify backup
  ;;
fault)
  notify fault
  ;;
*)
  echo "Usage: $(basename $0) {master|backup|fault}"
  exit 1
  ;;
esac

chk_nginx脚本

#!/bin/bash
killall -0 nginx > /dev/null
if [ $? -ne 0 ];then
    systemctl stop keepalived
fi

 

 

八、同步组

 

 

LVS NAT模型VIP和DIP需要同步,需要同步组

vrrp_sync_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_2 {
  eth1
  dip
}

  

posted @ 2020-09-17 19:00  yaowx  阅读(8152)  评论(0编辑  收藏  举报