高可用集群KEEPALIVED

avatar
作者
猴君
阅读量:0

目录

一、集群相关概念简述

1、集群的分类

2.系统可用性的计算公式

 3.系统故障

 4.实现高可用

二.keepalived

1.Keepalived介绍

2.keepalived相关概念 

3.VRRP协议与工作原理 

VRRP相关术语 

 VRRP相关技术

 4.keepalived功能

 5.Keepalived体系结构

 6.keepalived环境准备

7.keepalived相关配置文件

安装软件包

配置文件参数详解

全局配置

配置虚拟路由器

keepalived虚拟路由管理

keepalived虚拟路由的通讯设定

keepalived日志独立

keepalived独立子配置文件

keepalived非抢占和延迟抢占

非抢占模式 nopreempt

延迟抢占preempt_delay

VIP单播配置

 组播变单播实验

邮件通知

实现 Keepalived 状态切换的通知脚本

通知脚本类型

脚本的调用方法

创建通知脚本

实现 master/master 的 Keepalived 双主架构

实现IPVS的高可用

IPVS相关配置

虚拟服务器配置结构

virtual server (虚拟服务器)的定义格式

虚拟服务器配置

应用层监测

TCP监测

实战案例

keepalived+lvs实现高可用

实现HAProxy高可用

实现其它应用的高可用性 VRRP Script

VRRP Script 配置 

定义 VRRP script

调用 VRRP script

利用脚本实现主从角色切换

实战案例

haproxy+keepalived实现高可用


一、集群相关概念简述

HA是High Available缩写,是双机集群系统简称,指高可用性集群,是保证业务连续性的有效解决方案,一般有两个或两个以上的节点,且分为活动节点及备用节点。

1、集群的分类

  • LB:负载均衡集群
    • lvs负载均衡
    • nginx反向代理
    • HAProxy
  • HA:高可用集群
    • heartbeat
    • keepalived
    • redhat5 : cman + rgmanager , conga(WebGUI) --> RHCS(Cluster Suite)集群套件
    • redhat6 : cman + rgmanager , corosync + pacemaker
    • redhat7 : corosync + pacemaker
    • 数据库,redis
  • HPC:高性能集群
  • SPoF: Single Point of Failure,解决单点故障

2.系统可用性的计算公式

SLAService-Level Agreement 服务等级协议(提供服务的企业与客户之间就服务的品质、水准、性能等方面所达成的双方共同认可的协议或契约)
A=MTBF/(MTBF+MTTR)
  • A:高可用性,指标:95%, 99%, 99.5%, ...., 99.999%,99.9999%等
  • MTBF:平均无故障时间
  • MTTR:平均修复时间

 3.系统故障

硬件故障:设计缺陷、wear out(损耗)、非人为不可抗拒因素 软件故障:设计缺陷 bug

 4.实现高可用

提升系统高用性的解决方案:降低MTTR- Mean Time To Repair(平均故障时间) 解决方案:建立冗余机制
active/passive /active/active 双主 active --> HEARTBEAT --> passive active <--> HEARTBEAT <--> active

二.keepalived

1.Keepalived介绍

 Keepalived是Linux下一个轻量级别的高可用解决方案。高可用(High Avalilability,HA),其实两种不同的含义:广义来讲,是指整个系统的高可用行,狭义的来讲就是之主机的冗余和接管,

   它与HeartBeat RoseHA 实现相同类似的功能,都可以实现服务或者网络的高可用,但是又有差别,HeartBeat是一个专业的、功能完善的高可用软件,它提供了HA 软件所需的基本功能,比如:心跳检测、资源接管,检测集群中的服务,在集群节点转移共享IP地址的所有者等等。HeartBeat功能强大,但是部署和使用相对比较麻烦,

与HeartBeat相比,Keepalived主要是通过虚拟路由冗余来实现高可用功能,虽然它没有HeartBeat功能强大,但是Keepalived部署和使用非常的简单,所有配置只需要一个配置文件即可以完成,

Keepalived起初是为LVS设计的,专门用来监控集群系统中各个服务节点的状态,它根据TCP/IP参考模型的第三、第四层、第五层交换机制检测每个服务节点的状态,如果某个服务器节点出现异常,或者工作出现故障,Keepalived将检测到,并将出现的故障的服务器节点从集群系统中剔除,这些工作全部是自动完成的,不需要人工干涉,需要人工完成的只是修复出现故障的服务节点。

  后来Keepalived又加入了VRRP的功能,VRRP(Vritrual Router Redundancy Protocol,虚拟路由冗余协议)出现的目的是解决静态路由出现的单点故障问题,通过VRRP可以实现网络不间断稳定运行,因此Keepalvied 一方面具有服务器状态检测和故障隔离功能,另外一方面也有HA cluster功能.

2.keepalived相关概念 

  • vrrp协议:Virtual Redundant Routing Protocol 虚拟冗余路由协议
  • Virtual Router:虚拟路由器
  • VRID(0-255):虚拟路由器标识
  • master:主设备,当前工作的设备
  • backup:备用设备
  • priority:优先级,优先级越大优先工作,具体情况示工作方式决定
  • VIP:虚拟IP地址,正真向客户服务的IP地址
  • VMAC:虚拟MAC地址(00-00-5e-00-01-VRID)
  • 抢占式:如果有优先级高的节点上线,则将此节点转为master
  • 非抢占式:即使有优先级高的节点上线,在当前master工作无故障的情况运行抢占;等到此master故障后重新按优先级选举master
  • 心跳:master将自己的心跳信息通知集群内的所有主机,证明自己正常工作
  • 安全认证机制:
    • 无认证:任何主机都可成为集群内主机,强烈不推荐
    • 简单的字符认证:使用简单的密码进行认证
    • AH认证
  • sync group:同步组,VIP和DIP配置到同一物理服务器上
  • MULTICAST:组播,多播
  • Failover:master故障,故障切换,故障转移
  • Failback:故障节点重新上线,故障切回

3.VRRP协议与工作原理 

在现实的网络环境中。主机之间的通信都是通过配置静态路由或者(默认网关)来完成的,而主机之间的路由器一旦发生故障,通信就会失效,因此这种通信模式当中,路由器就成了一个单点瓶颈,为了解决这个问题,就引入了VRRP协议。

VRRP可以将两台或者多台物理路由器设备虚拟成一个虚拟路由,这个虚拟路由器通过虚拟IP(一个或者多个)对外提供服务,而在虚拟路由器内部十多个物理路由器协同工作,同一时间只有一台物理路由器对外提供服务,这台物理路由设备被成为:主路由器(Master角色),一般情况下Master是由选举算法产生,它拥有对外服务的虚拟IP,提供各种网络功能,如:ARP请求,ICMP 数据转发等,而且其它的物理路由器不拥有对外的虚拟IP,也不提供对外网络功能,仅仅接收MASTER的VRRP状态通告信息,这些路由器被统称为“BACKUP的角色”,当主路由器失败时,处于BACKUP角色的备份路由器将重新进行选举,产生一个新的主路由器进入MASTER角色,继续提供对外服务,整个切换对用户来说是完全透明的。

   每个虚拟路由器都有一个唯一的标识号,称为VRID,一个VRID与一组IP地址构成一个虚拟路由器,在VRRP协议中,所有的报文都是通过IP多播方式发送的,而在一个虚拟路由器中,只有处于Master角色的路由器会一直发送VRRP数据包,处于BACKUP角色的路由器只会接受Master角色发送过来的报文信息,用来监控Master运行状态,一一般不会发生BACKUP抢占的情况,除非它的优先级更高,而当MASTER不可用时,BACKUP也就无法收到Master发过来的信息,于是就认定Master出现故障,接着多台BAKCUP就会进行选举,优先级最高的BACKUP将称为新的MASTER,这种选举角色切换非常之快,因而保证了服务的持续可用性。

VRRP相关术语 

VRRP路由器:执行VRRP协议一个或多个实例的路由器

虚拟路由器:由一个Master路由器和多个Backup路由器组成。当中,不管Master路由器还是Backup路由器都是一台VRRP路由器,下行设备将虚拟路由器当做默认网关。

VRID:虚拟路由器标识,在同一个VRRP组内的路由器必须有相同的VRID,事实上VRID就相当于一个公司的名称,每一个员工介绍自己时都要包括公司名称,表明自己是公司的一员,相同的道理,VRID表明了这个路由器属于这个VRRP组。

Master路由器:虚拟路由器中承担流量转发任务的路由器

Backup路由器:当一个虚拟路由器中的Master路由器出现问题时,可以取代Master路由器工作的路由器

虚拟IP地址:虚拟路由器的IP地址,一个虚拟路由器能够拥有一个或多个虚拟IP地址。

IP地址拥有者:接口IP和虚拟路由器IP地址同样的路由器就叫做IP地址拥有者。

主IP地址:从物理接口设置的IP地址中选择,一个选择规则是总是选用第一个IP地址,VRRP通告报文总是用主IP地址作为该报文IP包头的源IP。

虚拟MAC地址:组成方式是00-00-5E-00-01-{VRID},前三个字节00-00-5E是IANA组织分配的,接下来的两个字节00-01是为VRRP协议指定的,最后的VRID是虚拟路由器标识,取值范围[1,255]

 VRRP相关技术

通告:心跳,优先级等;周期性 工作方式:抢占式,非抢占式 安全认证: 无认证 简单字符认证:预共享密钥 MD5 工作模式: /备:单虚拟路由器 /主:主/备(虚拟路由器1),备/主(虚拟路由器2

 4.keepalived功能

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

 5.Keepalived体系结构

Keepalived起初是为LVS设计的,由于Keeplalived可以实现对集群节点的状态检测,而IPVS可以实现负载均衡功能,因此,Keepalived借助于第三方模块IPVS就可以很方便地搭建一套负载均衡系统,在这里有个误区,由于Keepalived可以和IPVS一起很好的工作,所以会有人以为Keepalived就是一个负载均衡软件,这种理解是错误,

在Keepalived当中IPVS模块是可配置的,如果需要负载均衡功能,可以在编译Keepalived时开打负载均衡功能,也可以通过编译参数关闭。

   NetLINK模块主要用于实现一些高级路由框架和一些相关参数的网络功能,完成用户空间层Netlink Reflector模块发来的各种网络请求。

    这个图我们可以看到用户空间层(user space),是建立在内核空间层之上的(kernel sapce),

用户空间层,主要有4个部分

       Scheduler I/O Multiplexer 是一个I/O复用分发调度器,它负载安排Keepalived所有内部的任务请求,

       Memory Mngt 是一个内存管理机制,这个框架提供了访问内存的一些通用方法       

       Control Plane  是keepalived的控制版面,可以实现对配置文件编译和解析

       Core componets  这部分主要保护了下面5个部分

             1.Watchdog:是计算机可靠领域中极为简单又非常有效的检测工具,Keepalived正是通过它监控Checkers和VRRP进程的。

             2.Checkers: 这是Keepalived最基础的功能,也是最主要的功能,可以实现对服务器运行状态检测和故障隔离。

             3.VRRP Stack: 这时keepalived后来引用VRRP功能,可以实现HA集群中失败切换功能。

             4.IPVS wrapper: 这个是IPVS功能的一个实现,IPVS warrper模块将可以设置好的IPVS规则发送的内核空间并且提供给IPVS模块,最终实现IPVS模块的负载功能。

             5.Netlink Reflector:用来实现高可用集群Failover时虚拟IP(VIP)的设置和切换 ,

Netlink Reflector的所有请求最后都发送到内核空间层的NETLINK 模块来完成。

 6.keepalived环境准备

要求:各节点时间必须同步:ntp,chrony, 关闭防火墙和selinux 

7.keepalived相关配置文件

软件包名:keepalived  主程序文件:/usr/sbin/keepalived 主配置文件:/etc/keepalived/keepalived.conf 配置文件示例:/usr/share/doc/keepalived/ Unit File:/lib/systemd/system/keepalived.service Unit File的环境配置文件:/etc/sysconfig/keepalived

安装软件包

# yum install keepalived 

配置文件参数详解

全局配置
! Configuration File for keepalived global_defs { notification_email { 594233887@qq.com #keepalived 发生故障切换时邮件发送的目标邮箱,可以按行区分写多个 timiniglee-zln@163.com } notification_email_from keepalived@KA1.timinglee.org #发邮件的地址 smtp_server 127.0.0.1 #邮件服务器地址 smtp_connect_timeout 30 #邮件服务器连接timeout router_id KA1.timinglee.org #每个keepalived主机唯一标识 #建议使用当前主机名,但多节点重名不影响 vrrp_skip_check_adv_addr #对所有通告报文都检查,会比较消耗性能 #启用此配置后,如果收到的通告报文和上一个报文是同一 #个路由器,则跳过检查,默认值为全检查 vrrp_strict #严格遵循vrrp协议             #启用此项后以下状况将无法启动服务:             #1.无VIP地址             #2.配置了单播邻居             #3.在VRRP版本2中有IPv6地址             #建议不加此项配置 vrrp_garp_interval 0 #报文发送延迟,0表示不延迟 vrrp_gna_interval 0 #消息发送延迟 vrrp_mcast_group4 224.0.0.18 #指定组播IP地址范围: }
配置虚拟路由器
vrrp_instance VI_1 { state MASTER interface eth0 #绑定为当前虚拟路由器使用的物理接口,如:eth0,可以和VIP不在一个网卡 virtual_router_id 51 #每个虚拟路由器惟一标识,范围:0-255,每个虚拟路由器此值必须唯一                      #否则服务无法启动                      #同属一个虚拟路由器的多个keepalived节点必须相同                      #务必要确认在同一网络中此值必须唯一 priority 100         #当前物理节点在此虚拟路由器的优先级,范围:1-254                      #值越大优先级越高,每个keepalived主机节点此值不同 advert_int 1         #vrrp通告的时间间隔,默认1s authentication {     #认证机制 auth_type AH|PASS    #AH为IPSEC认证(不推荐),PASS为简单密码(建议使用) uth_pass 1111        #预共享密钥,仅前8位有效                      #同一个虚拟路由器的多个keepalived节点必须一样 } virtual_ipaddress {     #虚拟IP,生产环境可能指定上百个IP地址 <IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL> 172.25.254.100     #指定VIP,不指定网卡,默认为eth0,注意:不指定/prefix,默认32 172.25.254.101/24 dev eth1 172.25.254.102/24 dev eth2 label eth2:1 } }
keepalived虚拟路由管理

实验环境

设备角色IP
ka1keepalived1192.168.10.170/24
ka2keepalived2192.168.19.180/24
webserver1real server192.168.10.220/24
webserver2real server192.168.10.230/24

 注:vip设置为192.168.10.240/24

四台主机全部关闭防火墙和selinux

webserver1,webserver2上安装web服务,后面的测试可以更加清晰的看出结果

[root@webserver1 ~]# yum install httpd -y [root@webserver1 ~]# echo webserver1 - 192.168.10.220 > /var/www/html/index.html [root@webserver1 ~]# systemctl restart httpd.service  [root@webserver1 ~]# curl 192.168.10.220 webserver1 - 192.168.10.220 
[root@webserver2 ~]# yum install httpd -y [root@webserver2 ~]# echo webserver2 - 192.168.10.230 > /var/www/html/index.html [root@webserver2 ~]# systemctl restart httpd.service  [root@webserver2 ~]# curl 192.168.10.230 webserver2 - 192.168.10.230 

ka1,ka2上安装keepalived软件包

[root@ka1 ~]# yum install keepalived -y 
[root@ka2 ~]# yum install keepalived -y

在ka1上进行配置

[root@ka1 ~]# vim /etc/keepalived/keepalived.conf   # 全局设定 global_defs {    notification_email {      2948250195@qq.com       # 发送邮件通知给谁    }    notification_email_from keep@li.org    #发送的邮件从哪来    smtp_server 127.0.0.1                # 邮件服务器ip     smtp_connect_timeout 30              # 连接邮件服务器的超时时间    router_id ka1                        # 虚拟路由的id    vrrp_skip_check_adv_addr             # 同一来源的只检测一次 #   vrrp_strict                         # 强制使用vrrp协议    vrrp_garp_interval 0                     vrrp_gna_interval 0    vrrp_mcast_group4 224.0.0.18        # 接收通告数据的IP地址(组播地址)  }   # 虚拟路由器配置  vrrp_instance VI_1 {     state MASTER                 # 主设备     interface ens33              # vip使用的真实设备是谁     virtual_router_id 100        # 虚拟路由id(唯一的)     priority 100                 # 优先级     advert_int 1     authentication {         auth_type PASS           # 发通告带的信息         auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口         192.168.10.240/24 dev ens33 label ens33:0     } }  
[root@ka1 ~]# systemctl restart keepalived.service  # 重启服务
[root@ka1 ~]# ifconfig  ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.170  netmask 255.255.255.0  broadcast 192.168.10.255         inet6 fe80::20c:29ff:feea:fe5a  prefixlen 64  scopeid 0x20<link>         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet)         RX packets 88607  bytes 6246698 (5.9 MiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 65079  bytes 4618871 (4.4 MiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.240  netmask 255.255.255.0  broadcast 0.0.0.0         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet)  # vip 为 192.168.10.240 

ka2和ka1配置相同,所以我们可以使用scp,进行复制

[root@ka1 ~]# scp /etc/keepalived/keepalived.conf  root@192.168.10.180:/etc/keepalived/keepalived.conf  The authenticity of host '192.168.10.180 (192.168.10.180)' can't be established. ECDSA key fingerprint is SHA256:Yrid63PgwDQh7wiaQmCGsLuxK3Cht8v/wekHTAza/XI. ECDSA key fingerprint is MD5:d7:be:70:41:82:ff:81:40:5b:a7:40:10:d1:0c:ca:bf. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.10.180' (ECDSA) to the list of known hosts. root@192.168.10.180's password:  keepalived.conf                                           100% 4143     4.5MB/s   00:00     

唯一要变的就是我们将ka1当作主设备,ka2当作从,使用需要改两个配置

[root@ka1 ~]# vim /etc/keepalived/keepalived.conf   vrrp_instance VI_1 {     state BACKUP                 # 从设备     interface ens33              # vip使用的真实设备是谁     virtual_router_id 100        # 虚拟路由id(唯一的)     priority 80                 # 优先级改为80,两个设备优先级不一样     advert_int 1     authentication {         auth_type PASS           # 发通告带的信息         auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口         192.168.10.240/24 dev ens33 label ens33:0     } } 
[root@ka2 ~]# systemctl restart keepalived.service 

测试:

[root@ka1 ~]# tcpdump -i ens33 -nn host 224.0.0.18  [root@ka1 ~]# tcpdump -i ens33 -nn host 224.0.0.18 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes 19:06:36.826789 IP 192.168.10.170 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 19:06:37.828337 IP 192.168.10.170 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 19:06:38.829688 IP 192.168.10.170 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 19:06:39.831263 IP 192.168.10.170 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 19:06:40.832678 IP 192.168.10.170 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 19:06:41.833834 IP 192.168.10.170 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20  # 使用tcpdump进行抓包 # -i 就是ens33接收到底数据 # -nn 表示不做解析 # host指定观察的那个ip # 224.0.0.18 组播地址

ka1的优先级高于ka2所以正常情况看不到ka2的数据。若此时ka1发生故障,ka2则会迅速补上,此时在ka1上的vip也会跑到ka2上

[root@ka1 ~]# systemctl stop keepalived.service  [root@ka1 ~]# tcpdump -i ens33 -nn host 224.0.0.18 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes 19:09:39.386202 IP 192.168.10.180 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 80, authtype simple, intvl 1s, length 20 19:09:40.387629 IP 192.168.10.180 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 80, authtype simple, intvl 1s, length 20 19:09:41.388011 IP 192.168.10.180 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 80, authtype simple, intvl 1s, length 20 19:09:42.389522 IP 192.168.10.180 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 80, authtype simple, intvl 1s, length 20 19:09:43.390689 IP 192.168.10.180 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 80, authtype simple, intvl 1s, length 20 19:09:44.391255 IP 192.168.10.180 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 80, authtype simple, intvl 1s, length 20  
[root@ka2 ~]# ifconfig  ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.180  netmask 255.255.255.0  broadcast 192.168.10.255         inet6 fe80::20c:29ff:fe2c:7bd  prefixlen 64  scopeid 0x20<link>         ether 00:0c:29:2c:07:bd  txqueuelen 1000  (Ethernet)         RX packets 119533  bytes 8259027 (7.8 MiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 39657  bytes 3009635 (2.8 MiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.240  netmask 255.255.255.0  broadcast 0.0.0.0         ether 00:0c:29:2c:07:bd  txqueuelen 1000  (Ethernet)  

因为默认是抢占模式,当ka1好了之后,vip则会跑到ka1上,流量也会回到ka1上

[root@ka1 ~]# systemctl start keepalived.service  [root@ka1 ~]# ifconfig  ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.170  netmask 255.255.255.0  broadcast 192.168.10.255         inet6 fe80::20c:29ff:feea:fe5a  prefixlen 64  scopeid 0x20<link>         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet)         RX packets 92906  bytes 6566009 (6.2 MiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 67173  bytes 4781344 (4.5 MiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.240  netmask 255.255.255.0  broadcast 0.0.0.0         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet) 
[root@ka1 ~]# tcpdump -i ens33 -nn host 224.0.0.18 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes 19:13:06.604998 IP 192.168.10.170 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 19:13:07.605229 IP 192.168.10.170 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 19:13:08.605816 IP 192.168.10.170 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 19:13:09.606386 IP 192.168.10.170 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 
keepalived虚拟路由的通讯设定

此时ka1,ka2是ping不通vip的,因为防止被攻击,所有的数据流量打过来后可能会有恶意攻击,我们最终的数据流量是要转到real server上的,所以他默认会把你的vip访问功能给🈲掉

[root@ka1 ~]# ping 192.168.10.240 PING 192.168.10.240 (192.168.10.240) 56(84) bytes of data. ^Z [7]+  已停止               ping 192.168.10.240 
[root@ka1 ~]# iptables -nL Chain INPUT (policy ACCEPT) target     prot opt source               destination          DROP       all  --  0.0.0.0/0            0.0.0.0/0            match-set keepalived dst  Chain FORWARD (policy ACCEPT) target     prot opt source               destination           Chain OUTPUT (policy ACCEPT) target     prot opt source               destination          

这就是导致ping不通的原因---- match-set keepalived dst

如果要想ping通,就需要在配置文件中添加参数 ka1,ka2相同

global_defs {    notification_email {      2948250195@qq.com       # 发送邮件通知给谁    }    notification_email_from keep@li.org    #发送的邮件从哪来    smtp_server 127.0.0.1                # 邮件服务器ip    smtp_connect_timeout 30              # 连接邮件服务器的超时时间    router_id ka1                        # 虚拟路由的id    vrrp_skip_check_adv_addr             # 同一来源的只检测一次    vrrp_strict                         # 强制使用vrrp协议    vrrp_garp_interval 0    vrrp_gna_interval 0    vrrp_mcast_group4 224.0.0.18        # 接收通告数据的IP地址(组播地址)    vrrp_iptables         }  # 在最后一行添加 # 或者将vrrp_strict 注释掉,效果相同

测试:

[root@ka1 ~]# ping 192.168.10.240 PING 192.168.10.240 (192.168.10.240) 56(84) bytes of data. 64 bytes from 192.168.10.240: icmp_seq=1 ttl=64 time=0.021 ms 64 bytes from 192.168.10.240: icmp_seq=2 ttl=64 time=0.028 ms 64 bytes from 192.168.10.240: icmp_seq=3 ttl=64 time=0.035 ms 64 bytes from 192.168.10.240: icmp_seq=4 ttl=64 time=0.034 ms ^C --- 192.168.10.240 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 2998ms rtt min/avg/max/mdev = 0.021/0.029/0.035/0.007 ms [root@ka1 ~]# iptables -nL Chain INPUT (policy ACCEPT) target     prot opt source               destination           Chain FORWARD (policy ACCEPT) target     prot opt source               destination           Chain OUTPUT (policy ACCEPT) target     prot opt source               destination          
keepalived日志独立

默认情况下keepalived的日志和其他的服务是捆在一起的

要想将其日志独立出来就要修改其配置文件

[root@ka1 ~]# vim /etc/sysconfig/keepalived    # Options for keepalived. See `keepalived --help' output and keepalived(8) and # keepalived.conf(5) man pages for a list of all options. Here are the most # common ones : # # --vrrp               -P    Only run with VRRP subsystem. # --check              -C    Only run with Health-checker subsystem. # --dont-release-vrrp  -V    Dont remove VRRP VIPs & VROUTEs on daemon stop. # --dont-release-ipvs  -I    Dont remove IPVS topology on daemon stop. # --dump-conf          -d    Dump the configuration data. # --log-detail         -D    Detailed log messages. # --log-facility       -S    0-7 Set local syslog facility (default=LOG_DAEMON) #  KEEPALIVED_OPTIONS="-D -S 6" # 指定采集日志用的id是6,0-7都行 

重启服务

[root@ka1 ~]# systemctl restart keepalived.service  

编辑rsyslog.conf文件

 #### RULES ####  # Log all kernel messages to the console. # Logging much else clutters up the screen. #kern.*                                                 /dev/console  # Log anything (except mail) of level info or higher. # Don't log private authentication messages! *.info;mail.none;authpriv.none;cron.none                /var/log/messages  # The authpriv file has restricted access. authpriv.*                                              /var/log/secure  # Log all the mail messages in one place. mail.*                                                  -/var/log/maillog   # Log cron stuff cron.*                                                  /var/log/cron  # Everybody gets emergency messages *.emerg                                                 :omusrmsg:*  # Save news errors of level crit and higher in a special file. uucp,news.crit                                          /var/log/spooler  # Save boot messages also to boot.log local7.*                                                /var/log/boot.log local6.*                                                /var/log/keepalived.log  

在rules模块下可以添加 将日志采集在那个文件中,可以自定义,local加id 

重启服务

[root@ka1 ~]# systemctl restart rsyslog.service  

测试:

[root@ka1 ~]# systemctl restart rsyslog.service  [root@ka1 ~]# ll /var/log/keepalived.log  -rw-------. 1 root root 55473 8月  12 19:40 /var/log/keepalived.log [root@ka1 ~]# tail -f /var/log/keepalived.log  Aug 12 19:40:20 ka1 Keepalived_healthcheckers[3771]: Adding sorry server [192.168.200.200]:1358 to VS [10.10.10.2]:1358 Aug 12 19:40:20 ka1 Keepalived_healthcheckers[3771]: Removing alive servers from the pool for VS [10.10.10.2]:1358 Aug 12 19:40:20 ka1 Keepalived_healthcheckers[3771]: Remote SMTP server [127.0.0.1]:25 connected. Aug 12 19:40:20 ka1 Keepalived_healthcheckers[3771]: SMTP alert successfully sent. Aug 12 19:40:20 ka1 Keepalived_healthcheckers[3771]: Timeout connecting server [192.168.201.100]:443. Aug 12 19:40:20 ka1 Keepalived_healthcheckers[3771]: Check on service [192.168.201.100]:443 failed after 3 retry. Aug 12 19:40:20 ka1 Keepalived_healthcheckers[3771]: Removing service [192.168.201.100]:443 from VS [192.168.200.100]:443 Aug 12 19:40:20 ka1 Keepalived_healthcheckers[3771]: Lost quorum 1-0=1 > 0 for VS [192.168.200.100]:443 Aug 12 19:40:20 ka1 Keepalived_healthcheckers[3771]: Remote SMTP server [127.0.0.1]:25 connected. Aug 12 19:40:20 ka1 Keepalived_healthcheckers[3771]: SMTP alert successfully sent. ^Z [8]+  已停止               tail -f /var/log/keepalived.log 
keepalived独立子配置文件
当生产环境复杂时, /etc/keepalived/keepalived.conf 文件中内容过多,不易管理 将不同集群的配置,比如:不同集群的VIP配置放在独立的子配置文件中利用include 指令可以实现包含子配置文件格式:
include /path/file     可以指定一个路径
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf  }  # vrrp_instance VI_1 { #    state MASTER                 # 主设备 #    interface ens33              # vip使用的真实设备是谁 #    virtual_router_id 100        # 虚拟路由id(唯一的) #    priority 100                 # 优先级 #    advert_int 1 #    authentication { #        auth_type PASS           # 发通告带的信息 #        auth_pass 1111 #    } #    virtual_ipaddress {            # vip id     # 设定网卡子接口 #        192.168.10.240/24 dev ens33 label ens33:0 #    } #} include "/etc/keepalived/conf.d/*.conf"      # 将以上注释的内容指定在这个文件中   # 我们将以上的内容独立出来,放在一个新的文件里面,include指向新文件,前提是一定要有这个文件

[root@ka1 ~]# mkdir  -p /etc/keepalived/conf.d [root@ka1 ~]# vim  /etc/keepalived/conf.d/192.168.10.240.conf  vrrp_instance VI_1 {     state MASTER                 # 主设备     interface ens33              # vip使用的真实设备是谁     virtual_router_id 100        # 虚拟路由id(唯一的)     priority 100                 # 优先级     advert_int 1     authentication {         auth_type PASS           # 发通告带的信息         auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口         192.168.10.240/24 dev ens33 label ens33:0     } }   [root@ka1 ~]# systemctl restart keepalived.service  

测试:

[root@ka1 ~]# ifconfig  ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.170  netmask 255.255.255.0  broadcast 192.168.10.255         inet6 fe80::20c:29ff:feea:fe5a  prefixlen 64  scopeid 0x20<link>         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet)         RX packets 107150  bytes 7643447 (7.2 MiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 75971  bytes 5480440 (5.2 MiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.240  netmask 255.255.255.0  broadcast 0.0.0.0         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet) 

注意:将原配置文件独立出来后,原来的文件要么注释掉,要么删掉,否则独立出来的文件会和之前的文件冲突

keepalived非抢占和延迟抢占
非抢占模式 nopreempt
默认为抢占模式preempt,即当高优先级的主机恢复在线后,会抢占低先级的主机的master角色, 这样会使vipKA主机中来回漂移,造成网络抖动, 建议设置为非抢占模式 nopreempt ,即高优先级主机恢复后,并不会抢占低优先级主机的master角色 非抢占模块下,如果原主机down, VIP迁移至的新主机, 后续也发生down,仍会将VIP迁移回原主机

注意:要关闭 VIP抢占,必须将各 keepalived 服务器state配置为BACKUP  

ka1,和ka2配置相同

vim /etc/keepalived/keepalived.conf  }   vrrp_instance VI_1 {     state BACKUP                      interface ens33              # vip使用的真实设备是谁      virtual_router_id 100        # 虚拟路由id(唯一的)      priority 100                 # 优先级      advert_int 1      nopreempt     authentication {         auth_type PASS           # 发通告带的信息          auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口           192.168.10.240/24 dev ens33 label ens33:0     } }   # 设置非抢占模式   需要将state 改为 BACKUP 以及加一行参数 nopreempt
[root@ka2 ~]# vim /etc/keepalived/keepalived.conf vrrp_instance VI_1 {     state BACKUP                      interface ens33              # vip使用的真实设备是谁     virtual_router_id 100        # 虚拟路由id(唯一的)     priority 80                 # 优先级     advert_int 1     nopreempt         authentication {          auth_type PASS           # 发通告带的信息         auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口         192.168.10.240/24 dev ens33 label ens33:0 

我先重启ka2再重启ka1,vip将会跑到ka2上,并且不会回去,当ka2挂掉,vip才会回去,不管优先级

[root@ka2 ~]# ifconfig  ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.180  netmask 255.255.255.0  broadcast 192.168.10.255         inet6 fe80::20c:29ff:fe2c:7bd  prefixlen 64  scopeid 0x20<link>         ether 00:0c:29:2c:07:bd  txqueuelen 1000  (Ethernet)         RX packets 142318  bytes 10033173 (9.5 MiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 45810  bytes 3472473 (3.3 MiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.240  netmask 255.255.255.0  broadcast 0.0.0.0         ether 00:0c:29:2c:07:bd  txqueuelen 1000  (Ethernet) 
[root@ka2 ~]# systemctl stop keepalived.service  
[root@ka1 ~]# ifconfig  ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.170  netmask 255.255.255.0  broadcast 192.168.10.255         inet6 fe80::20c:29ff:feea:fe5a  prefixlen 64  scopeid 0x20<link>         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet)         RX packets 111441  bytes 7967231 (7.5 MiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 78058  bytes 5653940 (5.3 MiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.240  netmask 255.255.255.0  broadcast 0.0.0.0         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet)  
延迟抢占preempt_delay

抢占延迟模式,即优先级高的主机恢复后,不会立即抢回VIP,而是延迟一段时间(默认300s)再抢回VIP

preempt_delay # #指定抢占延迟时间为#s,默认延迟300s

注意:需要各keepalived服务器stateBACKUP,并且不要启用 vrrp_strict
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf  vrrp_instance VI_1 {     state BACKUP     interface ens33              # vip使用的真实设备是谁     virtual_router_id 100        # 虚拟路由id(唯一的)     priority 100                      preempt_delay 10s         # 抢占延迟10s     advert_int 1 #   nopreempt      authentication {         auth_type PASS           # 发通告带的信息         auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口         192.168.10.240/24 dev ens33 label ens33:0     } 
[root@ka2 ~]# vim /etc/keepalived/keepalived.conf    vrrp_instance VI_1 {     state BACKUP     interface ens33              # vip使用的真实设备是谁     virtual_router_id 100        # 虚拟路由id(唯一的)     priority 80                 # 优先级     advert_int 1     preempt_delay 10s #   nopreempt     authentication {          auth_type PASS           # 发通告带的信息         auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口         192.168.10.240/24 dev ens33 label ens33:0     } 

测试:由于pa1的优先级高于pa2,我先启动pa2 ,down掉pa1,vip会到pa2上,我再启动pa1,vip不会立刻回到pa1上,而是10秒后

[root@ka2 ~]# systemctl restart keepalived.service  [root@ka2 ~]# ifconfig  ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.180  netmask 255.255.255.0  broadcast 192.168.10.255         inet6 fe80::20c:29ff:fe2c:7bd  prefixlen 64  scopeid 0x20<link>         ether 00:0c:29:2c:07:bd  txqueuelen 1000  (Ethernet)         RX packets 146839  bytes 10374458 (9.8 MiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 47473  bytes 3611473 (3.4 MiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536         inet 127.0.0.1  netmask 255.0.0.0         inet6 ::1  prefixlen 128  scopeid 0x10<host>         loop  txqueuelen 1000  (Local Loopback)         RX packets 607  bytes 44033 (43.0 KiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 607  bytes 44033 (43.0 KiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0 
[root@ka1 ~]# date  2024年 08月 12日 星期一 20:19:31 CST [root@ka1 ~]# systemctl restart keepalived.service  [root@ka1 ~]# ifconfig  ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.170  netmask 255.255.255.0  broadcast 192.168.10.255         inet6 fe80::20c:29ff:feea:fe5a  prefixlen 64  scopeid 0x20<link>         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet)         RX packets 115304  bytes 8272918 (7.8 MiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 79935  bytes 5800622 (5.5 MiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.240  netmask 255.255.255.0  broadcast 0.0.0.0         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet)  lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536         inet 127.0.0.1  netmask 255.0.0.0         inet6 ::1  prefixlen 128  scopeid 0x10<host>         loop  txqueuelen 1000  (Local Loopback)         RX packets 942  bytes 69116 (67.4 KiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 942  bytes 69116 (67.4 KiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  [root@ka1 ~]# date  2024年 08月 12日 星期一 20:19:48 CST #差不多就是这个意思  
VIP单播配置
默认keepalived主机之间利用多播相互通告消息,会造成网络拥塞,可以替换成单播,减少网络流量
[!NOTE] 注意:启用 vrrp_strict 时,不能启用单播
#在所有节点vrrp_instance语句块中设置对方主机的IP,建议设置为专用于对应心跳线网络的地址,而非使 用业务网络 unicast_src_ip <IPADDR> #指定发送单播的源IP unicast_peer { <IPADDR> #指定接收单播的对方目标主机IP ...... } #启用 vrrp_strict 时,不能启用单播,否则服务无法启动,并在messages文件中记录下面信息 Jun 16 17:50:06 centos8 Keepalived_vrrp[23180]: (m44) Strict mode does not support authentication. Ignoring. Jun 16 17:50:06 centos8 Keepalived_vrrp[23180]: (m44) Unicast peers are notsupported in strict mode Jun 16 17:50:06 centos8 Keepalived_vrrp[23180]: Stopped - used 0.000606 user time, 0.000000 system time Jun 16 17:50:06 centos8 Keepalived[23179]: Keepalived_vrrp exited with permanent error CONFIG. Terminating Jun 16 17:50:06 centos8 systemd[1]: keepalived.service: Succeeded. Jun 16 17:50:06 centos8 Keepalived[23179]: Stopped Keepalived v2.0.10 (11/12,2018)
 组播变单播实验

ka1和ka2互相进行通告

 [root@ka1 ~]# vim /etc/keepalived/keepalived.conf   global_defs {    notification_email {      2948250195@qq.com       # 发送邮件通知给谁    }    notification_email_from keep@li.org    #发送的邮件从哪来    smtp_server 127.0.0.1                # 邮件服务器ip    smtp_connect_timeout 30              # 连接邮件服务器的超时时间    router_id ka1                        # 虚拟路由的id    vrrp_skip_check_adv_addr             # 同一来源的只检测一次 #   vrrp_strict                         #注释此行,与vip单播模式冲突    vrrp_garp_interval 0    vrrp_gna_interval 0    vrrp_mcast_group4 224.0.0.18        # 接收通告数据的IP地址(组播地址) #   vrrp_iptables }   vrrp_instance VI_1 {     state MASTER     interface ens33              # vip使用的真实设备是谁     virtual_router_id 100        # 虚拟路由id(唯一的)     priority 100 #    preempt_delay 10s         # 抢占延迟10s     advert_int 1 #   nopreempt     authentication {         auth_type PASS           # 发通告带的信息         auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口         192.168.10.240/24 dev ens33 label ens33:0     }     unicast_src_ip 192.168.10.170        # 发送源,就是本机ip     unicast_peer {         192.168.10.180                   # 接收源,就是对端也就是ka2     } 
[root@ka2 ~]# vim /etc/keepalived/keepalived.conf  global_defs {    notification_email {      2948250195@qq.com       # 发送邮件通知给谁    }    notification_email_from keep@li.org    #发送的邮件从哪来    smtp_server 127.0.0.1                # 邮件服务器ip    smtp_connect_timeout 30              # 连接邮件服务器的超时时间    router_id ka1                        # 虚拟路由的id    vrrp_skip_check_adv_addr             # 同一来源的只检测一次 #   vrrp_strict                         # 注释此行,与vip单播模式冲突    vrrp_garp_interval 0    vrrp_gna_interval 0    vrrp_mcast_group4 224.0.0.18        # 接收通告数据的IP地址(组播地址) #   vrrp_iptables  vrrp_instance VI_1 {     state BACKUP     interface ens33              # vip使用的真实设备是谁     virtual_router_id 100        # 虚拟路由id(唯一的)     priority 80                 # 优先级     advert_int 1 #    preempt_delay 10s #   nopreempt     authentication {          auth_type PASS           # 发通告带的信息         auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口         192.168.10.240/24 dev ens33 label ens33:0     }     unicast_src_ip 192.168.10.180        # 发送源,就是本机ip     unicast_peer {         192.168.10.170     } 

测试:

[root@ka1 ~]# tcpdump -i ens33 -nn src host 192.168.10.170 and dst 192.168.10.180  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes 09:43:21.998624 IP 192.168.10.170 > 192.168.10.180: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 09:43:23.005985 IP 192.168.10.170 > 192.168.10.180: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 09:43:24.011231 IP 192.168.10.170 > 192.168.10.180: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 09:43:25.017003 IP 192.168.10.170 > 192.168.10.180: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 09:43:26.017906 IP 192.168.10.170 > 192.168.10.180: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 09:43:27.024354 IP 192.168.10.170 > 192.168.10.180: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20  # 在170上看180到170的数据 # 在180上看170到180的数据
邮件通知

当两台keepalived主机出现问题,或者身份发生转换时,通过邮件的形式告知运维人员

安装邮件发送工具
[root@ka1 ~]# yum install mailx -y 
[root@ka2 ~]# yum install mailx -y 

 可以使用qq或者网易邮箱,打开账号与安全,开启POP3/IMAP/SMTP/Exchange/CardDAV 授权码,他会给你一个授权码,将授权码添加到/etc/mail.rc(邮件客户端的配置文件)文件中

[root@ka1 ~]# vim /etc/mail.rc  '''''''''''省略''''''''''''''''''''' set from=               # 后面添加你用哪一个邮箱,填上账号 set smtp=smtp.qq.com set smtp-auth-user=   # 填自己的邮箱号 set smtp-auth-password= # 这个就是给你的授权码 set smtp-auth=login     # 表示登陆 set ssl-verify=ignore   # 不用加密协议   # 在文件的最后面加上 

另一台主机同样配置。

测试:

[root@ka1 ~]# echo hello world | mail -s test 跟上你的邮箱账号 

实现 Keepalived 状态切换的通知脚本
通知脚本类型
当前节点成为主节点时触发的脚本
notify_master <STRING>|<QUOTED-STRING>
当前节点转为备节点时触发的脚本
notify_backup <STRING>|<QUOTED-STRING>
当前节点转为失败状态时触发的脚本
notify_fault <STRING>|<QUOTED-STRING>
通用格式的通知触发机制,一个脚本可完成以上三种状态的转换时的通知
notify <STRING>|<QUOTED-STRING>
当停止VRRP时触发的脚本
notify_stop <STRING>|<QUOTED-STRING>
脚本的调用方法
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"
创建通知脚本
[root@KA1 ~]# vim /etc/keepalived/mail.sh    # 自己创建文件 #!/bin/bash mail_dest='填邮箱账号'    mail_send() { mail_subj="$HOSTNAME to be $1 vip 转移"           # 邮件的标题 mail_mess="`date +%F\ %T`: vrrp 转移,$HOSTNAME 变为 $1"  #邮件的正文 echo "$mail_mess" | mail -s "$mail_subj" $mail_dest     # echo发邮件 } case $1 in master) mail_send master ;; backup) mail_send backup ;; fault) mail_send fault ;; *) exit 1 ;; esac
[root@ka1 ~]# chmod +x /etc/keepalived/mail.sh # 给它一个可执行的权限

调度:

[root@ka1 ~]# vim /etc/keepalived/keepalived.conf   vrrp_instance VI_1 {     state MASTER     interface ens33              # vip使用的真实设备是谁     virtual_router_id 100        # 虚拟路由id(唯一的)     priority 100     advert_int 1     authentication {         auth_type PASS           # 发通告带的信息         auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口         192.168.10.240/24 dev ens33 label ens33:0     }     unicast_src_ip 192.168.10.170     unicast_peer {         192.168.10.180    }    notify_master "/etc/keepalived/mail.sh master"    notify_backup "/etc/keepalived/mail.sh backup"    notify_fault "/etc/keepalived/mail.sh fault" } 

ka1,ka2配置相同

测试:
[root@ka1 ~]# bash /etc/keepalived/mail.sh 

[root@ka2 ~]# bash /etc/keepalived/mail.sh 

停止ka1keepalived服务,vip跑到ka2上自动发邮件

[root@ka1 ~]# systemctl stop keepalived.service

开启ka1,vip回到ka1上,自动发邮件

[root@ka1 ~]# systemctl start keepalived.service 

 

实现 master/master Keepalived 双主架构
master/slave的单主架构,同一时间只有一个Keepalived对外提供服务,此主机繁忙,而另一台主机却很空闲,利用率低下,可以使用master/master的双主架构,解决此问题。
master/master 的双主架构: 即将两个或以上VIP分别运行在不同的keepalived服务器,以实现服务器并行提供web访问的目的,提高服务器资源利用率

 ka1上配置

[root@ka1 ~]# vim /etc/keepalived/keepalived.conf  vrrp_instance VI_1 {     state MASTER     interface ens33              # vip使用的真实设备是谁     virtual_router_id 100        # 虚拟路由id(唯一的)     priority 100     advert_int 1     authentication {         auth_type PASS           # 发通告带的信息         auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口         192.168.10.240/24 dev ens33 label ens33:0     } #    unicast_src_ip 192.168.10.170 #    unicast_peer { #        192.168.10.180 #    } } # include "/etc/keepalived/conf.d/*.conf"      # 将以上注释的内容指定在这个文件中   vrrp_instance VI_2 {     state BACKUP #备     interface ens33     virtual_router_id 200     priority 80     advert_int 1     authentication {         auth_type PASS         auth_pass 1111     }     virtual_ipaddress {         192.168.10.245 dev ens33 label ens33:1     } }  

ka2

}   vrrp_instance VI_2 {     state MASTER               # zhu     interface ens33              # vip使用的真实设备是谁     virtual_router_id 200        # 虚拟路由id(唯一的)     priority 100                 # 优先级     advert_int 1 #    preempt_delay 10s #   nopreempt     authentication {          auth_type PASS           # 发通告带的信息         auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口         192.168.10.245/24 dev ens33 label ens33:1     }     unicast_src_ip 192.168.10.180        # 发送源,就是本机ip     unicast_peer {         192.168.10.170     } } .。。。。。省略。。。。。。。

测试:第一个vip应该在ka1上,第二个vip应该在ka2上

[root@ka1 ~]# ifconfig  ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.170  netmask 255.255.255.0  broadcast 192.168.10.255         inet6 fe80::20c:29ff:feea:fe5a  prefixlen 64  scopeid 0x20<link>         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet)         RX packets 30093  bytes 2256607 (2.1 MiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 20992  bytes 1524476 (1.4 MiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.240  netmask 255.255.255.0  broadcast 0.0.0.0         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet) 
[root@ka2 ~]# ifconfig  ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.180  netmask 255.255.255.0  broadcast 192.168.10.255         inet6 fe80::20c:29ff:fe2c:7bd  prefixlen 64  scopeid 0x20<link>         ether 00:0c:29:2c:07:bd  txqueuelen 1000  (Ethernet)         RX packets 22361  bytes 1479856 (1.4 MiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 10536  bytes 831566 (812.0 KiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.245  netmask 255.255.255.0  broadcast 0.0.0.0         ether 00:0c:29:2c:07:bd  txqueuelen 1000  (Ethernet) 
实现IPVS的高可用

相当于使用keepalived结合lvs去组成一个既具备高可用,又具备负载均衡的集群

keepalived解决了vip的问题

IPVS相关配置
虚拟服务器配置结构
virtual_server IP port { ... real_server { ... } real_server { ... } … }
virtual server (虚拟服务器)的定义格式
virtual_server IP port #定义虚拟主机IP地址及其端口 virtual_server fwmark int #ipvs的防火墙打标,实现基于防火墙的负载均衡集群 virtual_server group string #使用虚拟服务器组
虚拟服务器配置
virtual_server IP port { #VIP和PORT delay_loop <INT> #检查后端服务器的时间间隔 lb_algo rr|wrr|lc|wlc|lblc|sh|dh #定义调度方法 lb_kind NAT|DR|TUN #集群的类型,注意要大写 persistence_timeout <INT> #持久连接时长 protocol TCP|UDP|SCTP #指定服务协议,一般为TCP sorry_server <IPADDR> <PORT> #所有RS故障时,备用服务器地址 real_server <IPADDR> <PORT> { #RS的IP和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_CHECK { ... } #定义当前主机健康状 态检测方法 } } #注意:括号必须分行写,两个括号写在同一行,如: }} 会出错
应用层监测
应用层检测:HTTP_GET|SSL_GET
HTTP_GET|SSL_GET { url { path <URL_PATH> #定义要监控的URL status_code <INT> #判断上述检测机制为健康状态的响应码,一般为 200 } connect_timeout <INTEGER> #客户端请求的超时时长, 相当于haproxy的timeout server nb_get_retry <INT> #重试次数 delay_before_retry <INT> #重试之前的延迟时长 connect_ip <IP ADDRESS> #向当前RS哪个IP地址发起健康状态检测请求 connect_port <PORT> #向当前RS的哪个PORT发起健康状态检测请求 bindto <IP ADDRESS> #向当前RS发出健康状态检测请求时使用的源地址 bind_port <PORT> #向当前RS发出健康状态检测请求时使用的源端口 }
TCP监测
TCP_CHECK { connect_ip <IP ADDRESS> #向当前RS的哪个IP地址发起健康状态检测请求 connect_port <PORT> #向当前RS的哪个PORT发起健康状态检测请求 bindto <IP ADDRESS> #发出健康状态检测请求时使用的源地址 bind_port <PORT> #发出健康状态检测请求时使用的源端口 connect_timeout <INTEGER> #客户端请求的超时时长 #等于haproxy的timeout server }
实战案例
keepalived+lvs实现高可用

实现单主的 LVS-DR 模式

在webserver1和webserver上将其环回设置为vip,以及对它们的arp广播进行一个只进不出的设定。

[root@webserver1 ~]# ip a a 192.168.10.240/32 dev lo # 临时设定 [root@webserver1 ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000     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     inet 192.168.10.240/32 scope global 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 group default qlen 1000     link/ether 00:0c:29:6c:ee:7d brd ff:ff:ff:ff:ff:ff     inet 192.168.10.220/24 brd 192.168.10.255 scope global noprefixroute ens33        valid_lft forever preferred_lft forever     inet6 fe80::20c:29ff:fe6c:ee7d/64 scope link        valid_lft forever preferred_lft forever 
[root@webserver2 ~]# ip a  a 192.168.10.240/32 dev lo  [root@webserver2 ~]# ip  a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000     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     inet 192.168.10.240/32 scope global 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 group default qlen 1000     link/ether 00:0c:29:f0:40:f5 brd ff:ff:ff:ff:ff:ff     inet 192.168.10.230/24 brd 192.168.10.255 scope global noprefixroute ens33        valid_lft forever preferred_lft forever     inet6 fe80::20c:29ff:fef0:40f5/64 scope link        valid_lft forever preferred_lft forever 
[root@webserver1 ~]# sysctl -a | grep arp dev.parport.default.spintime = 500 dev.parport.default.timeslice = 200 net.ipv4.conf.all.arp_accept = 0 net.ipv4.conf.all.arp_announce = 2 net.ipv4.conf.all.arp_filter = 0 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.all.arp_notify = 0 net.ipv4.conf.all.proxy_arp = 0 net.ipv4.conf.all.proxy_arp_pvlan = 0 net.ipv4.conf.default.arp_accept = 0 net.ipv4.conf.default.arp_announce = 0 net.ipv4.conf.default.arp_filter = 0 net.ipv4.conf.default.arp_ignore = 0 net.ipv4.conf.default.arp_notify = 0 net.ipv4.conf.default.proxy_arp = 0 net.ipv4.conf.default.proxy_arp_pvlan = 0 net.ipv4.conf.ens33.arp_accept = 0 net.ipv4.conf.ens33.arp_announce = 0 net.ipv4.conf.ens33.arp_filter = 0 net.ipv4.conf.ens33.arp_ignore = 0 net.ipv4.conf.ens33.arp_notify = 0 net.ipv4.conf.ens33.proxy_arp = 0 net.ipv4.conf.ens33.proxy_arp_pvlan = 0 net.ipv4.conf.lo.arp_accept = 0 net.ipv4.conf.lo.arp_announce = 2 net.ipv4.conf.lo.arp_filter = 0 net.ipv4.conf.lo.arp_ignore = 1 net.ipv4.conf.lo.arp_notify = 0 net.ipv4.conf.lo.proxy_arp = 0 net.ipv4.conf.lo.proxy_arp_pvlan = 0 sysctl: reading key "net.ipv6.conf.all.stable_secret" sysctl: reading key "net.ipv6.conf.default.stable_secret" sysctl: reading key "net.ipv6.conf.ens33.stable_secret" sysctl: reading key "net.ipv6.conf.lo.stable_secret" 

可以在这里面复制粘贴,然后光修改参数即可

 [root@webserver1 ~]# vim /etc/sysctl.d/arp.conf # 可以自己创建文件  net.ipv4.conf.all.arp_announce=2 net.ipv4.conf.all.arp_ignore=1 net.ipv4.conf.lo.arp_announce = 2 net.ipv4.conf.lo.arp_ignore = 1 
 [root@webserver1 ~]# sysctl --system       # 刷新生效 * Applying /usr/lib/sysctl.d/00-system.conf ... * Applying /usr/lib/sysctl.d/10-default-yama-scope.conf ... kernel.yama.ptrace_scope = 0 * Applying /usr/lib/sysctl.d/50-default.conf ... kernel.sysrq = 16 kernel.core_uses_pid = 1 kernel.kptr_restrict = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.promote_secondaries = 1 net.ipv4.conf.all.promote_secondaries = 1 fs.protected_hardlinks = 1 fs.protected_symlinks = 1 * Applying /etc/sysctl.d/99-sysctl.conf ... * Applying /etc/sysctl.d/arp.conf ... net.ipv4.conf.all.arp_announce = 2 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.lo.arp_announce = 2 net.ipv4.conf.lo.arp_ignore = 1 * Applying /etc/sysctl.conf ... 

webserver1和webserver2配置相同,我们可以使用scp复制

[root@webserver1 ~]# scp /etc/sysctl.d/arp.conf root@192.168.10.230:/etc/sysctl.d/arp.conf The authenticity of host '192.168.10.230 (192.168.10.230)' can't be established. ECDSA key fingerprint is SHA256:Yrid63PgwDQh7wiaQmCGsLuxK3Cht8v/wekHTAza/XI. ECDSA key fingerprint is MD5:d7:be:70:41:82:ff:81:40:5b:a7:40:10:d1:0c:ca:bf. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.10.230' (ECDSA) to the list of known hosts. root@192.168.10.230's password: arp.conf                                                                                                                    100%  131   251.9KB/s   00:00 
[root@webserver2 ~]# sysctl --system * Applying /usr/lib/sysctl.d/00-system.conf ... * Applying /usr/lib/sysctl.d/10-default-yama-scope.conf ... kernel.yama.ptrace_scope = 0 * Applying /usr/lib/sysctl.d/50-default.conf ... kernel.sysrq = 16 kernel.core_uses_pid = 1 kernel.kptr_restrict = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.promote_secondaries = 1 net.ipv4.conf.all.promote_secondaries = 1 fs.protected_hardlinks = 1 fs.protected_symlinks = 1 * Applying /etc/sysctl.d/99-sysctl.conf ... * Applying /etc/sysctl.d/arp.conf ... net.ipv4.conf.all.arp_announce = 2 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.lo.arp_announce = 2 net.ipv4.conf.lo.arp_ignore = 1 * Applying /etc/sysctl.conf ... 

在ka1上下载一个ipvsadm软件包,查看ipvs规则

[root@ka1 ~]# yum install ipvsadm -y 

在keepalived主机上配置策略

[root@ka1 ~]# vim /etc/keepalived/keepalived.conf   virtual_server 192.168.10.240 80 {           # 这就相当于使用ipvsadm -A 添加虚拟主机,ip就是vip     delay_loop 6     lb_algo wrr     lb_kind DR #    persistence_timeout 50     protocol TCP ###################################################     real_server 192.168.10.220 80 {     # 这就是相当于ipvsadm -a 添加真实主机         weight 1         HTTP_GET {             url {               path /               digest_code 200             }             connect_timeout 3             nb_get_retry 2             delay_before_retry 2         }     } ###################################################     real_server 192.168.10.230 80 {         weight 1         HTTP_GET {             url {               path /               digest_code 200             }             connect_timeout 3             nb_get_retry 2             delay_before_retry 2         }     }  

webserver2和1相同

[root@ka2 ~]# vim /etc/keepalived/keepalived.conf  virtual_server 192.168.10.240 80 {     delay_loop 6     lb_algo wrr     lb_kind DR #   persistence_timeout 50     protocol TCP #############################################     real_server 192.168.10.220 80 {         weight 1         HTTP_GET {             url {               path /               digest_code 200             }             connect_timeout 3              nb_get_retry 2             delay_before_retry 2         }     } #############################################     real_server 192.168.10.230 80 {         weight 1         HTTP_GET {             url {               path /               digest_code 200             }             connect_timeout 3             nb_get_retry 2             delay_before_retry 2         }     } 
[root@ka1 ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags   -> RemoteAddress:Port           Forward Weight ActiveConn InActConn TCP  192.168.10.240:80 wrr   -> 192.168.10.220:80            Route   1      0          0   -> 192.168.10.230:80            Route   1      0          0 TCP  10.10.10.2:1358 rr persistent 50   -> 192.168.200.2:1358           Masq    1      0          0   -> 192.168.200.3:1358           Masq    1      0          0 TCP  10.10.10.3:1358 rr persistent 50   -> 192.168.200.4:1358           Masq    1      0          0   -> 192.168.200.5:1358           Masq    1      0          0 

查看策略,这些策略都是通过添加keepalived配置文件生成的

测试:访问vip

注:lvs是不提供后端检测的,就是你写完策略以后,不管它是不是好的,都往上仍,现在结合keepalived之后达到的效果就它可以检测你的策略是不是好的,后台的real server是否是正常的,如果real server异常,它就会被踢出我们的策略当中,如果有正常了,就会自动加入到我们的策略当中,全程都是自动的。

此时我们的ka2上面的策略是不生效的,因为ka2上面没有vip,当我们的ka1down掉,vip就会自动跑到我们的ka2上,此次ka2上的策略生效,不会影响我们客户的正常访问。

我们可以通过测试来看出

后台两个real server正常的情况下,策略是这样的

[root@ka1 ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags   -> RemoteAddress:Port           Forward Weight ActiveConn InActConn TCP  192.168.10.240:80 wrr   -> 192.168.10.220:80            Route   1      0          0   -> 192.168.10.230:80            Route   1      0          0 TCP  10.10.10.2:1358 rr persistent 50   -> 192.168.200.2:1358           Masq    1      0          0   -> 192.168.200.3:1358           Masq    1      0          0 

现在我把webserver1(192,.168.10.220)上的web服务down掉,我们再来看策略

[root@ka1 ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags   -> RemoteAddress:Port           Forward Weight ActiveConn InActConn TCP  192.168.10.240:80 wrr   -> 192.168.10.230:80            Route   1      0          0 TCP  10.10.10.2:1358 rr persistent 50   -> 192.168.200.2:1358           Masq    1      0          0   -> 192.168.200.3:1358           Masq    1      0          0 

我们可以使用watch来监控,这样看的更加清晰,是动态的

[root@ka1 ~]# watch -n 1 ipvsadm -Ln 
实现HAProxy高可用

原理:由keepalived去监测haproxy的状态,如果主keepalived上haproxy主机出现了问题,主keepalived就将自己的优先级降低,优先级一降低,vip就会跑到我们备keepalived上去,备keepalived上的haproxy也可以正常调度,也可以正常访问real server。

主要是检测haproxy的状态,haproxy作为调度器,如果他出现了问题,就算你有vip也无法访问我们的real server

实现其它应用的高可用性 VRRP Script
keepalived利用 VRRP Script 技术,可以调用外部的辅助脚本进行资源监控,并根据监控的结果实现优先级动态调整,从而实现其它应用的高可用性功能 参考配置文件:/usr/share/doc/keepalived/keepalived.conf.vrrp.localcheck
VRRP Script 配置 
分两步实现:
1.定义脚本      vrrp_script:自定义资源监控脚本,vrrp实例根据脚本返回值,公共定义,可被多个实例调用,定义在vrrp实例之外的独立配置块,一般放在global_defs设置块之后。      通常此脚本用于监控指定应用的状态。一旦发现应用的状态异常,则触发对MASTER节点的权重减至低于SLAVE节点,从而实现 VIP 切换到 SLAVE 节点
vrrp_script <SCRIPT_NAME> { script <STRING>|<QUOTED-STRING> #此脚本返回值为非0时,会触发下面OPTIONS执行 OPTIONS }

 2.调用脚本

   track_script:调用vrrp_script定义的脚本去监控资源,定义在VRRP实例之内,调用事先定义的vrrp_script
track_script { SCRIPT_NAME_1 SCRIPT_NAME_2 }
定义 VRRP script
vrrp_script <SCRIPT_NAME> {     #定义一个检测脚本,在global_defs 之外配置 script <STRING>|<QUOTED-STRING> #shell命令或脚本路径 interval <INTEGER>              #间隔时间,单位为秒,默认1秒 timeout <INTEGER>               #超时时间 weight <INTEGER:-254..254>      #默认为0,如果设置此值为负数,                                 #当上面脚本返回值为非0时                                 #会将此值与本节点权重相加可以降低本节点权重,                                 #即表示fall.                                 #如果是正数,当脚本返回值为0,                                 #会将此值与本节点权重相加可以提高本节点权重                                 #即表示 rise.通常使用负值 fall <INTEGER>                  #执行脚本连续几次都失败,则转换为失败,建议设为2以上 rise <INTEGER>                  #执行脚本连续几次都成功,把服务器从失败标记为成功 user USERNAME [GROUPNAME]       #执行监测脚本的用户或组 init_fail                       #设置默认标记为失败状态,监测成功之后再转换为成功状态 }
调用 VRRP script
vrrp_instance test { ... ... track_script { check_down } }
利用脚本实现主从角色切换
[root@ka1 ~]# vim /etc/keepalived/check_blue.sh  #!/bin/bash  [ ! -f  /blue ]  # 检测 /blue这个文件存不存在
[root@ka1 ~]# bash /etc/keepalived/check_blue.sh [root@ka1 ~]# echo $? 0   [root@ka1 ~]# chmod +x /etc/keepalived/check_blue.sh  # 给脚本一个可执行权限

执行脚本后,通过其返回值来确定这个文件存不存在,若是0表示执行成功,文件不存在,若是其他值,表示执行失败,文件存在。

! Configuration File for keepalived  global_defs {    notification_email {      2948250195@qq.com       # 发送邮件通知给谁    }    notification_email_from keep@li.org    #发送的邮件从哪来    smtp_server 127.0.0.1                # 邮件服务器ip    smtp_connect_timeout 30              # 连接邮件服务器的超时时间    router_id ka1                        # 虚拟路由的id    vrrp_skip_check_adv_addr             # 同一来源的只检测一次 #   vrrp_strict                         # 强制使用vrrp协议    vrrp_garp_interval 0    vrrp_gna_interval 0    vrrp_mcast_group4 224.0.0.18        # 接收通告数据的IP地址(组播地址) #   vrrp_iptables } vrrp_script check_file {     script "/etc/keepalived/check_blue.sh"     interval 1                  # 检测时间间隔为1秒     weight -30                  # 如果返回值不为0,优先级减30     fall 2                      # 脚本执行两次,再者视为失败     rise 2                      # 脚本连续两次执行成功,把服务器从失败转换为成功状态     timeout 2                   # 脚本执行的超时时间 }  # 检测脚本的配置文件放在 vrrp_instance VI_1  配置文件的上面
 vrrp_instance VI_1 {     state MASTER     interface ens33              # vip使用的真实设备是谁     virtual_router_id 100        # 虚拟路由id(唯一的)     priority 100     advert_int 1     authentication {         auth_type PASS           # 发通告带的信息         auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口         192.168.10.240/24 dev ens33 label ens33:0     }     unicast_src_ip 192.168.10.170     unicast_peer {         192.168.10.180    }         track_script {                    check_file   # 脚本名称 和上面定义脚本的名称一致         } } #调用脚本放在虚拟路由配置文件的里面

测试:

当我们脚本中的文件不存在时,返回值为0,配置文件中的weight值就不生效。优先级就仍然为100,vip不会漂移

[root@ka1 ~]# ll /blue ls: 无法访问/blue: 没有那个文件或目录 [root@ka1 ~]# ifconfig ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.170  netmask 255.255.255.0  broadcast 192.168.10.255         inet6 fe80::20c:29ff:feea:fe5a  prefixlen 64  scopeid 0x20<link>         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet)         RX packets 297425  bytes 27436999 (26.1 MiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 234268  bytes 17810980 (16.9 MiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.240  netmask 255.255.255.0  broadcast 0.0.0.0         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet)  lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536         inet 127.0.0.1  netmask 255.0.0.0         inet6 ::1  prefixlen 128  scopeid 0x10<host>         loop  txqueuelen 1000  (Local Loopback)         RX packets 2459  bytes 182483 (178.2 KiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 2459  bytes 182483 (178.2 KiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0 

当我们创建这个文件时,他存在,执行脚本后返回值不为0,我们的配置文件的weight值生效,我们的优先级就会减30,变为70,此时主keepalived的优先级低于备,使用vip就会漂移到ka2上

[root@ka1 ~]# touch /blue [root@ka1 ~]# ll /blue -rw-r--r--. 1 root root 0 8月  14 17:25 /blue [root@ka1 ~]# systemctl restart keepalived.service [root@ka1 ~]# ifconfig ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.170  netmask 255.255.255.0  broadcast 192.168.10.255         inet6 fe80::20c:29ff:feea:fe5a  prefixlen 64  scopeid 0x20<link>         ether 00:0c:29:ea:fe:5a  txqueuelen 1000  (Ethernet)         RX packets 298043  bytes 27493779 (26.2 MiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 234948  bytes 17862710 (17.0 MiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  
[root@ka2 ~]# ifconfig ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.180  netmask 255.255.255.0  broadcast 192.168.10.255         inet6 fe80::20c:29ff:fe2c:7bd  prefixlen 64  scopeid 0x20<link>         ether 00:0c:29:2c:07:bd  txqueuelen 1000  (Ethernet)         RX packets 2709  bytes 262428 (256.2 KiB)         RX errors 0  dropped 0  overruns 0  frame 0         TX packets 3609  bytes 274342 (267.9 KiB)         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.240  netmask 255.255.255.0  broadcast 0.0.0.0         ether 00:0c:29:2c:07:bd  txqueuelen 1000  (Ethernet)  ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500         inet 192.168.10.245  netmask 255.255.255.0  broadcast 0.0.0.0         ether 00:0c:29:2c:07:bd  txqueuelen 1000  (Ethernet)  

根据上面的实验,我们现在只需要把脚本的内容换成检测haproxy好坏,就可以实现我们的高可用。

实战案例
haproxy+keepalived实现高可用

在keepalived主机上装haproxy

[root@ka1 ~]# yum install haproxy -y 
[root@ka2 ~]# yum install haproxy -y 
[root@ka1 ~]# vim /etc/haproxy/haproxy.cfg  .。。。。。。。省略。。。。。。。。。。。 #--------------------------------------------------------------------- # round robin balancing between the various backends #--------------------------------------------------------------------- backend app     balance     roundrobin     server  app1 127.0.0.1:5001 check     server  app2 127.0.0.1:5002 check     server  app3 127.0.0.1:5003 check     server  app4 127.0.0.1:5004 check listen webcluser     bind 192.168.10.240:80     mode http     balance roundrobin     server webserver1 192.168.10.220:80 check inter 3 fall 2 rise 5     server webserver2 192.168.10.230:80 check inter 3 fall 2 rise 5  

重启服务

 [root@ka1 ~]# systemctl restart haproxy.service 

因为我们在ka1上配置了bind 192.168.10.240 而ka2没有该ip使用无法监听,所以我们需要打开我们两个主机的内裤参数

 [root@ka1 ~]# vim /etc/sysctl.conf  # sysctl settings are defined through files in # /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/. # # Vendors settings live in /usr/lib/sysctl.d/. # To override a whole file, create a new file with the same in # /etc/sysctl.d/ and put new settings there. To override # only specific settings, add a file with a lexically later # name in /etc/sysctl.d/ and put new settings there. # # For more information, see sysctl.conf(5) and sysctl.d(5). net.ipv4.ip_nonlocal_bind = 1 ~ 
[root@ka1 ~]# sysctl -p net.ipv4.ip_nonlocal_bind = 1  # 即使本地没有这个ip也可以正常访问 # 刷新配置

ka1和ka2配置相同。

[root@ka1 ~]# netstat -antlupe | grep haproxy tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN      0          217544     10669/haproxy tcp        0      0 192.168.10.240:80       0.0.0.0:*               LISTEN      0          217546     10669/haproxy udp        0      0 0.0.0.0:43413           0.0.0.0:*                           0          217545     10668/haproxy  # 查看端口是否开启

去掉在webserver1和webserver2上的vip,换原arp响应

[root@webserver1 ~]# vim /etc/sysctl.d/arp.conf  net.ipv4.conf.all.arp_announce=0 net.ipv4.conf.all.arp_ignore=0 net.ipv4.conf.lo.arp_announce=0 net.ipv4.conf.lo.arp_ignore=0  [root@webserver1 ~]# sysctl -p

webserver1和webserver2配置相同

#virtual_server 192.168.10.240 80 { #    delay_loop 6 #    lb_algo wrr #    lb_kind DR ##    persistence_timeout 50 #    protocol TCP #################################################### #    real_server 192.168.10.220 80 { #        weight 1 #        HTTP_GET { #            url { #              path / #              digest_code 200 #            } #            connect_timeout 3 #            nb_get_retry 2 #            delay_before_retry 2 #        } #    } #################################################### #    real_server 192.168.10.230 80 { #        weight 1 #        HTTP_GET { #            url { #              path / #              digest_code 200 #            } #            connect_timeout 3 #            nb_get_retry 2 #            delay_before_retry 2 #        } #    }  

注:将之前实验修改的real server全部注释掉,和hapoxy有冲突,ka1和ka2配置相同

测试:

检测haproxy的命令

 在ka1和ka2上安装killall软件包,ka1,ka2配置相同

[root@ka1 ~]# yum install psmisc -y 
[root@ka1 ~]# killall -0 haproxy [root@ka1 ~]# echo $? 0 [root@ka1 ~]# systemctl stop haproxy.service [root@ka1 ~]# killall -0 haproxy haproxy: no process found [root@ka1 ~]# echo $? 1 

当haproxy调度器正常工作时我们使用killall -0 haproxy  他返回的值为0,当haoroxy停止工作时,他返回的值为非0,我们可以根据这一点来修改之前的脚本,来判断haproxy是否正常运行,从而达到keepalived检测haproxy状态,使用keepalived优先级根据harprixy的变化而变化,实现vip的漂移。

[root@ka1 ~]# vim /etc/keepalived/check_blue.sh #!/bin/bash  killall -0 haproxy 

ka2也相同操作,我就用scp直接复制了

[root@ka1 ~]# vim /etc/keepalived/keepalived.conf  vrrp_script check_haproxy {     script "/etc/keepalived/check_blue.sh"     interval 1                  # 检测时间间隔为1秒     weight -30                  # 如果检测不为0,优先级减30     fall 2                      # 脚本执行两次,再者视为失败     rise 2                      # 脚本连续两次执行成功,把服务器从失败转换为成功状态     timeout 2                   # 脚本执行的超时时间  }   vrrp_instance VI_1 {     state MASTER     interface ens33              # vip使用的真实设备是谁     virtual_router_id 100        # 虚拟路由id(唯一的)     priority 100     advert_int 1     authentication {         auth_type PASS           # 发通告带的信息         auth_pass 1111     }     virtual_ipaddress {            # vip id     # 设定网卡子接口         192.168.10.240/24 dev ens33 label ens33:0     }     unicast_src_ip 192.168.10.170     unicast_peer {         192.168.10.180    }    track_script {        check_haproxy     } 

重启keepalived和haproxy,

此时因为ka1的优先级高于ka2,且ka1上的haproxy正常运行,使用vip仍然在ka1上

我们现在模拟故障,将ka1上的harproxy停掉,vip就会跑到ka2上

因为ka1上的haproxydown掉,脚本成功检测,返回值为非0,所以ka1上的优先级就会减30,变为70,此时的ka2上的优先级为80,所以vip就跑到了ka2上,在此期间,客户仍然可以正常访问,当我们ka1上的haproxy正常工作时,vip有会回到ka1上,因为我们设置的是2次脚本返回值为0,就把当前的harproxy标记为正常状态,优先级又回到了100

 

    广告一刻

    为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!