深度剖析Keepalived:一个不可或缺的网络健康检查与故障转移神器

keepalived简介

keepalived是一个基于VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)协议来实现其高可用性(High Availbility,HA)的轻量级软件,其主要应用于Linux操作系统,特别是一些需要高可用服务的场景,如负载均衡器、Web服务器集群、数据库服务器等。

keepalived的功能

  • 基于VRRP协议完成地址流动
  • 为VIP地址所在的节点生成ipvs规则(在配置文件中预先定义)
  • 为ipvs集群的各RS做健康状态监测
  • 基于脚本调用接口完成脚本中定义的功能,进而影响集群事务,以此支持nginx、haproxy等服务

VRRP

虚拟路由冗余协议,用于确保在局域网环境中网络的可靠性。当多台路由器(或具有路由功能的设备)连接到同一网络时,VRRP允许这些路由器之间共享一个或多个虚拟IP地址,即VIP,以便在网络中呈现为一个单一的虚拟路由器。

VRRP的主要作用是提高网络的可靠性和容错。它通过选举一个路由器作为主路由器(master),负责转发数据包,而其它的路由器则作为备份路由器(backup)。如果主路由器出现故障,VRRP会迅速选举一个新的主路由器来接替工作,从而实现网络的无缝转换,避免单点故障导致的服务中断。

VRRP的专业术语

  • 虚拟路由器:Virtual Router
  • 虚拟路由器标识:VRID(0-255),唯一标识虚拟路由器
  • VIP:Virtual IP
  • VMAC:Virtual MAC
  • 物理路由器:
    • master:主设备
    • backup:备用设备
    • priority:优先级

VRRP的相关技术

通告:心跳、优先级、周期性等

工作方式:抢占模式、非抢占模式

安全认证方式:

  • 无认证
  • 简单的字符认证:共享密钥
  • MD5

工作模式:

  • 主/备:单虚拟路由器
  • 主/主:一台虚拟路由器为主/备,另一台虚拟路由器为备/主

高可用

高可用是一个系统属性,指的是在系统或组件在面对故障、维护操作或其它意外事件时,能够持续提供服务的能力。高可用性的目标是最小化系统停机时间,来确保服务的连续性和可靠性。

高可用的关键要素

  • 冗余:
    • 硬件冗余:使用额外的硬件组件(如冗余电源、RAID磁盘阵列、双网卡等)来防止单点故障
    • 软件冗余:通过部署多个实例(如主备模式、集群模式)的软件服务来确保在一个实例失败时,其他实例能够接管服务。
    • 数据冗余:通过数据复制、备份和恢复策略来确保数据的安全性和可用性。
  • 故障转移:
    • 当系统检测到某个组件或服务出现故障时,能够自动或手动地将服务从故障组件转移到正常组件上,来确保服务的不间断性。
  • 负载均衡:
    • 在多个服务器或者服务实例之间分配工作负载,以提高资源利用率和响应速度,同时增强系统的容错能力。
  • 监控和告警:
    • 实时监控系统运行状态,及时发现潜在问题,并通过告警机制通知管理员,以便快速响应和处理。
  • 自动化恢复:
    • 通过自动化脚本或者工具来简化故障处理流程,减少人为错误和停机时间。

keepalived的部署

keepalived的架构

  • 用户空间核心组件:
    • vrrp stack:VIP消息通告
    • checkers:检测realserver
    • system call:实现VRRP协议状态转换时调用脚本的功能
    • SMTP:邮件组件
    • IPVS wrapper:生成IPVS规则
    • Netlink Reflector:网络接口
    • WatchDog:监控进程
  • 控件组件:提供keepalived.conf的解析器,完成keepalived配置
  • IO复用器:针对网络目的而优化的自己的线程抽象
  • 内存管理组件:为某些通用的内存管理功能(例如分配、重新分配、发布等)提供访问权限

keepalived实验环境

KA1        172.25.254.10

KA2        172.25.254.20

realserver1        172.25.254.110

realserver2        172.25.254.120

实验前的基础准备

  • 各节点的时间必须同步
  • 关闭防火墙以及SELinux
  • 配置解析文件,使得各节点之间可以用过主机名进行相互通信
  • 各节点之间可以通过ssh服务进行免密钥认证

keepalived的软件安装及相关文件

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

#keepalived的相关文件
/etc/keepalived/keepalived.conf    #主配置文件
/etc/sysconfig/keepalived    #Unit File的环境配置文件
/usr/lib/systemd/system/keepalived.service    #Unit File
/usr/sbin/keepalived    #主程序文件
/usr/share/doc/keepalived-1.3.5/    #配置文件示例

#keepalived的服务启动
[root@ka1 ~]# systemctl start keepalived.service

keepalived的配置

配置文件的组成部分

配置文件:/etc/keepalived/keepalived.conf

配置文件的组成:

  • global_defs
    • 定义邮件配置、route_id,vrrp配置,多播地址等
  • vrrp_instance VI_0
    • 定义每个vrrp虚拟路由器
  • virtual_server
    • LVS集群的VS和RS

配置文件说明

全局配置
global_defs {
   notification_email {
        XXXXXXXX@qq.com    #keepalived发生故障切换时邮件发送的目标邮箱,可以按行区分写多个邮箱
   }
   notification_email_from keepalived@ka1.super.org    #发邮件的地址
   smtp_server 127.0.0.1                  #邮件服务器地址
   smtp_connect_timeout 30                #邮件服务器的连接timeout
   router_id ka1.super.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_0 {
    state MASTER
    interface ens33    #绑定为当前虚拟路由器使用的物理接口,可以不和VIP在同一张网卡上
    virtual_router_id 100    #每个虚拟路由器的唯一标识,范围为0-255,每个虚拟路由器此值必须唯一,否则服务无法正常启动。同属一个虚拟路由器的多个keepalived节点必须相同,务必要确认在同一网络中此值必须唯一
    priority 100    #当前物理节点在此虚拟路由器的优先级,范围:1-254,值越大优先级越高,每个keepalived主机节点此值不同
    advert_int 1    #vrrp通告时间间隔,默认为1s
    authentication {        #认证机制
        auth_type PASS      #AH为IPSEC认证(不推荐),PASS为简单密码(建议使用)
        auth_pass 1111      #用于认证的密码,仅前8位有效,同一个虚拟路由器的多个keepalived节点必须一样
    }
    virtual_ipaddress {    #虚拟IP,生产环境可能指定上百个IP地址
        172.25.254.100/24 dev ens33 label ens33:1    #指定VIP、网卡及网卡标签,不指定网卡,默认为eth0
    }
}
启用keepalived日志功能
[root@ka1 ~]# vim /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -S 6"

[root@ka1 ~]# vim /etc/rsyslog.conf
local6.*                        /var/log/keepalived.log

#重启rsyslog日志服务和keepalived服务
[root@ka1 ~]# systemctl restart rsyslog.service
[root@ka1 ~]# systemctl restart keepalived.service

[root@ka1 ~]# tail /var/log/keepalived.log
Aug 16 21:49:45 ka1 Keepalived_healthcheckers[17500]: Removing service [192.168.200.5]:1358 from VS [10.10.10.3]:1358
Aug 16 21:49:45 ka1 Keepalived_healthcheckers[17500]: Lost quorum 1-0=1 > 0 for VS [10.10.10.3]:1358
Aug 16 21:49:45 ka1 Keepalived_healthcheckers[17500]: Remote SMTP server [127.0.0.1]:25 connected.
Aug 16 21:49:45 ka1 Keepalived_healthcheckers[17500]: SMTP alert successfully sent.
Aug 16 21:49:47 ka1 Keepalived_healthcheckers[17500]: Timeout connecting server [192.168.201.100]:443.
Aug 16 21:49:47 ka1 Keepalived_healthcheckers[17500]: Check on service [192.168.201.100]:443 failed after 3 retry.
Aug 16 21:49:47 ka1 Keepalived_healthcheckers[17500]: Removing service [192.168.201.100]:443 from VS [192.168.200.100]:443
Aug 16 21:49:47 ka1 Keepalived_healthcheckers[17500]: Lost quorum 1-0=1 > 0 for VS [192.168.200.100]:443
Aug 16 21:49:47 ka1 Keepalived_healthcheckers[17500]: Remote SMTP server [127.0.0.1]:25 connected.
Aug 16 21:49:47 ka1 Keepalived_healthcheckers[17500]: SMTP alert successfully sent.

实现独立子配置文件

当生产环境较为复杂时,keepalived的主配置文件/etc/keepalived/keepalived.conf中的内容会很多,不方便进行管理。我们可以将不同集群的配置放在独立的子配置文件中,使用include指令即可实现包含子配置文件。

#创建子配置文件目录
[root@ka1 ~]# mkdir /etc/keepalived/conf.d

#在主配置文件中包含子配置文件
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
include "/etc/keepalived/conf.d/*.conf"

#编辑子配置文件
[root@ka1 ~]# vim /etc/keepalived/conf.d/child.conf
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 20
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.25.254.100/24 dev eth0 label eth0:0
    }
}

#重启生效
[root@ka1 ~]# systemctl restart keepalived.service

keepalived企业应用示例

实现master/slave的keepalived单主架构

master主机的配置

[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
   notification_email {
    xxxxxxxx@qq.com
   }
   notification_email_from keepalived@ka1.super.org
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id ka1.super.org
   vrrp_skip_check_adv_addr
   #vrrp_strict            #添加此选项可能无法访问VIP,可以使用nft list ruleset查看
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   vrrp_mcast_group4 224.0.0.18
}

vrrp_instance VI_0 {
    state MASTER
    interface ens33
    virtual_router_id 100
    priority 100
    #preempt_delay 10s
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    172.25.254.100/24 dev ens33 label ens33:1
    }
}

backup主机的配置

[root@ka2 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
   notification_email {
    xxxxxxxx@qq.com
   }
   notification_email_from keepalived@ka1.super.org
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id ka1.super.org
   vrrp_skip_check_adv_addr
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   vrrp_mcast_group4 224.0.0.18
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33    
    virtual_router_id 100    #相同的id管理同一个虚拟路由
    priority 80    #有优先级比master低
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    172.25.254.100/24 dev ens33 label ens33:2
    }
}
抓包验证

抢占模式与非抢占模式

抢占模式(Preempt Mode)

定义与特点:
  • 在抢占模式下,当master节点发生故障时,VIP会漂移到backup备用节点。
  • 当主节点恢复上线时,它会尝试重新抢占VIP,将其从backup节点收回。
  • keepalived默认工作在抢占模式下。
配置要点
  • 主节点的state配置为MASTER,备用节点的state配置为BACKUP。
  • master节点的优先级要比backup节点的优先级高。
使用场景
  • 适用于机器性能一致,且允许VIP多次漂移的业务场景。
  • 在需要快速恢复服务的场景下,抢占模式可以确保VIP尽快地回到主节点上。

非抢占模式(Non-Preempt Mode)

定义与特点
  • 在非抢占模式下,当主节点发生故障后,VIP会漂移到备用节点上。
  • 当master节点恢复上线时,它不会尝试抢占VIP,VIP将保持在backup节点上。
  • 要实现非抢占模式,需要在高优先级的节点配置中添加nopreempt参数,并将所有节点的state都配置为BACKUP。
配置要点
  • 所有节点的state都配置为BACKUP。
  • 高优先级节点的配置中添加nopreempt参数。
  • 确保高优先级节点的优先级仍然高于低优先级节点。
使用场景
  • 适用于不允许VIP随意切换的场景,如某些业务对IP地址的稳定性有较高要求。
  • 在非抢占模式下,即使master节点恢复在线,也不会造成VIP的频繁迁移,从而避免了可能的网络抖动。
master节点的配置
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 200
    priority 100
    nopreempt        #开启非抢占模式
    #preempt_delay 10s
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }

    virtual_ipaddress {
        172.25.254.100/24 dev ens33 label ens33:1
    }

}
backup节点的配置
[root@ka2 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 100
    priority 80      #优先级比ka1低
    nopreempt        #开启非抢占模式
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    172.25.254.100/24 dev ens33 label ens33:2
    }
}
验证
[root@ka1 ~]# systemctl restart keepalived.service

#我们可以发现,重启ka1的keepalived服务后,VIP并没有回到ka1上
[root@ka1 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.25.254.10  netmask 255.255.255.0  broadcast 172.25.254.255
        inet6 fe80::20c:29ff:fe45:4b37  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:45:4b:37  txqueuelen 1000  (Ethernet)
        RX packets 11828  bytes 791923 (773.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 17254  bytes 1166757 (1.1 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 172.25.254.20  netmask 255.255.255.0  broadcast 172.25.254.255
        inet6 fe80::20c:29ff:fef1:622d  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:f1:62:2d  txqueuelen 1000  (Ethernet)
        RX packets 14351  bytes 925533 (903.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 12239  bytes 838465 (818.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.25.254.100  netmask 255.255.255.0  broadcast 0.0.0.0
        ether 00:0c:29:f1:62:2d  txqueuelen 1000  (Ethernet)

延迟抢占模式(preempt_delay)

定义与特点
  • 当master节点恢复上线后,不会立即抢回VIP,而是会等待一段预设的时间(抢占延迟时间)后,再进行抢占。
  • 可以减少VIP在主备节点之间的频繁切换,从而提高网络整体的稳定性。
  • 在网络环境不稳定或主节点恢复初期可能存在的不稳定因素下,延迟抢占模式有助于减少这些不稳定因素对网络的影响。
配置要点
  • 通过preempt_delay参数来指定抢占延迟时间,以s为单位。
  • 在启用延迟抢占模式时,建议将所有节点的state都配置为BACKUP,并通过优先级来确定哪个节点先成为master。
使用场景
  • 在网络环境不稳定或存在潜在的网络抖动风险时,延迟抢占模式可以减少VIP的频繁切换,从而提高网络的稳定性。
  • 对于业务稳定性有较高要求的场景,延迟抢占模式可以确保在主节点恢复后不会立即引起服务的波动。
  • 当预计主节点恢复时间较长时,延迟抢占模式可以给主节点足够的恢复时间,避免在主节点尚未完全恢复时就被迫接管服务。
master节点配置
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_0 {
    state BACKUP
    interface ens33
    virtual_router_id 100
    priority 100
    preempt_delay 10s    #设定延迟抢占时间为10s
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    172.25.254.100/24 dev ens33 label ens33:1
    }
}
backup节点配置
[root@ka2 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 100
    priority 80
    preempt_delay 10s    #设定延迟抢占时间为10s
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.25.254.100/24 dev ens33 label ens33:2
    }
}
验证
[root@ka1 ~]# systemctl stop keepalived.service
[root@ka1 ~]# systemctl start keepalived.service
#重启keepalived服务后,我们可以发现,ka1并没有马上抢占VIP
[root@ka1 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.25.254.10  netmask 255.255.255.0  broadcast 172.25.254.255
        inet6 fe80::20c:29ff:fe45:4b37  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:45:4b:37  txqueuelen 1000  (Ethernet)
        RX packets 16735  bytes 1102284 (1.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 21870  bytes 1475811 (1.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
#等待10s后,我们再次查看,ka1抢占了VIP
[root@ka1 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.25.254.10  netmask 255.255.255.0  broadcast 172.25.254.255
        inet6 fe80::20c:29ff:fe45:4b37  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:45:4b:37  txqueuelen 1000  (Ethernet)
        RX packets 16792  bytes 1106380 (1.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 21938  bytes 1480865 (1.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.25.254.100  netmask 255.255.255.0  broadcast 0.0.0.0
        ether 00:0c:29:45:4b:37  txqueuelen 1000  (Ethernet)

VIP单播

定义与特点
  • 通过VIP单播模式, master节点可以直接将VRRP通告消息发送给指定的backup节点,而无需通过组播地址广播给所有监听改地址的设备。
  • 由于单播消息只发送给指定的backup节点,因此不会在网络中产生大量的无用信息,从而减少网络拥塞。
  • 通过单播模式发送VRRP通告消息,可以防止未经授权的节点接收到这些消息,从而提高了网络的安全性。
配置要点
  • 要确保关闭了vrrp_strict选项,因为vrrp_strict会强制执行vrrp协议的一些限制,包括禁止单播对等点等。
  • 在vrrp实例配置中,需要指定单播的源IP和目标IP,这些IP地址应该是用于心跳通信的专用网络地址。
使用场景
  • 在大型或者复杂的网络环境中,组播方式可能会产生大量的无用信息,导致网络堵塞。此时,采用VIP单播方式可以减少网络堵塞,提高网络的可靠性和稳定性。
  • 对于要求高安全性的网络环境,采用VIP单播方式可以防止未经授权的节点接到VRRP通告消息,从而提高网络的安全性。
  • 在某些特定的业务场景中,可能需要将VRRP通告消息限制在特定的节点之间传输。此时,VIP单播方式可以满足这些特定需求。
master节点配置
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
   notification_email {
    xxxxxxxx@qq.com
   }
   notification_email_from keepalived@ka1.super.org
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id ka1.super.org
   vrrp_skip_check_adv_addr
   #vrrp_strict            #注意,此参数一定要注释,与VIP单播模式会产生冲突
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   vrrp_mcast_group4 224.0.0.18
}

vrrp_instance VI_0 {
    state MASTER
    interface ens33
    virtual_router_id 100
    priority 100
    #nopreempt
    preempt_delay 10s
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.25.254.100/24 dev ens33 label ens33:1
    }

    unicast_src_ip 172.25.254.10    #本机IP
    unicast_peer {
        172.25.254.20                   #指向对方主机IP,可添加多个节点IP
    }
}
backup节点配置
[root@ka2 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
   notification_email {
    3152471662@qq.com
   }
   notification_email_from keepalived@ka1.super.org
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id ka1.super.org
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   vrrp_mcast_group4 224.0.0.18
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 100
    priority 80
    preempt_delay 10s
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.25.254.100/24 dev ens33 label ens33:2
    }
    unicast_src_ip 172.25.254.20    #本机IP
    unicast_peer {
        172.25.254.10                   #对端主机IP
    }
}
抓包验证

keepalived通知脚本配置

keepalived支持多种通知机制,包括通过脚本在状态变化时执行自定义操作。

默认以用户keepalived_script身份执行脚本。

通知脚本类型

当前节点成为主节点时触发脚本

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>

脚本的调用方法

[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_0 {
    state MASTER
    interface ens33
    virtual_router_id 100
    priority 100
    #nopreempt
    preempt_delay 10s
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    172.25.254.100/24 dev ens33 label ens33:1
    }

    unicast_src_ip 172.25.254.10
    unicast_peer {
        172.25.254.20
    }
    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/notify.sh
#!/bin/bash
mail_dest='xxxxxxxx@sina.cn'

mail_send(){
    mail_subj="$HOSTNAME to be $1 vip move"
    mail_msg="`date +%F\ %T`: vrrp move, $HOSTNAME change $1"
    echo "$mail_msg" | mail -s "$mail_subj" $mail_dest
}

case $1 in
    master)
        mail_send master
    ;;
    backup)
        mail_send backup
    ;;
    fault)
        mail_send fault
    ;;
    *)
        exit 1
    ;;
esac

邮件服务配置

#下载mailx软件包
[root@ka1 ~]# yum install mailx -y

#邮箱服务配置
[root@ka1 ~]# vim /etc/mail.rc
set bsdcompat
set from=xxxxxxxx@sina.cn
set smtp=smtp.sina.cn
set smtp-auth-user=xxxxxxxx@sina.cn
set smtp-auth-password=xxxxxxxx
set smtp-auth=login
set ssl-verify=ignore

#发送邮件测试
[root@ka1 ~]# echo test massage | mail -s test xxxxxxxx@sina.cn

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

[root@ka1 ~]# cat /etc/keepalived/notify.sh
#!/bin/bash
mail_dest='xxxxxxxx@sina.cn'

mail_send(){
    mail_subj="$HOSTNAME to be $1 vip move"
    mail_msg="`date +%F\ %T`: vrrp move, $HOSTNAME change $1"
    echo "$mail_msg" | mail -s "$mail_subj" $mail_dest
}

case $1 in
    master)
        mail_send master
    ;;
    backup)
        mail_send backup
    ;;
    fault)
        mail_send fault
    ;;
    *)
        exit 1
    ;;
esac

#给脚本添加执行权限
[root@ka1 ~]# chmod +x /etc/keepalived/notify.sh

#keepalived主配置文件
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_0 {
    state MASTER
    interface ens33
    virtual_router_id 100
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    172.25.254.100/24 dev ens33 label ens33:1
    }

    unicast_src_ip 172.25.254.10
    unicast_peer {
        172.25.254.20
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

keepalived故障模拟

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

查看邮件

实现master/master的keepalived双主架构

在master/master的keepalived双主架构中,两台或多台keepalived服务器分别配置不同的虚拟IP(VIP)地址,这些VIP地址分别绑定到不同的业务上。每台服务器都可以作为某个业务的主服务器,同时作为其他业务的备用服务器。当主服务器出现故障时,备用服务器可以立即接管其业务,确保服务的连续性。

ka1主机的配置

[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_0 {
    state MASTER    #主
    interface ens33
    virtual_router_id 100
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.25.254.100/24 dev ens33 label ens33:1
    }
}

vrrp_instance VI_1 {
    state BACKUP    #备
    interface ens33
    virtual_router_id 200
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
       172.25.254.200/24 dev ens33 label ens33:2
    }
}

ka2主机配置

[root@ka2 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
    state BACKUP    #备
    interface ens33
    virtual_router_id 100
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.25.254.100/24 dev ens33 label ens33:2
    }
}

vrrp_instance VI_2 {
    state MASTER    #主
    interface ens33
    virtual_router_id 200
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.25.254.200/24 dev ens33 label ens33:1
    }

}

验证

#ka1
[root@ka1 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.25.254.10  netmask 255.255.255.0  broadcast 172.25.254.255
        inet6 fe80::20c:29ff:fe45:4b37  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:45:4b:37  txqueuelen 1000  (Ethernet)
        RX packets 50858  bytes 3292159 (3.1 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 73123  bytes 4849343 (4.6 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.25.254.100  netmask 255.255.255.0  broadcast 0.0.0.0
        ether 00:0c:29:45:4b:37  txqueuelen 1000  (Ethernet)

#ka2
[root@ka2 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.25.254.20  netmask 255.255.255.0  broadcast 172.25.254.255
        inet6 fe80::20c:29ff:fef1:622d  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:f1:62:2d  txqueuelen 1000  (Ethernet)
        RX packets 59299  bytes 3734765 (3.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 54298  bytes 3601184 (3.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.25.254.200  netmask 255.255.255.0  broadcast 0.0.0.0
        ether 00:0c:29:f1:62:2d  txqueuelen 1000  (Ethernet)

实现IPVS的高可用性

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

virtual_server IP port    #定义虚拟主机IP地址及其端口
virtual_server fwmark int    #ipvs的防火墙标签,实现基于防火墙的负载均衡集群
virtual_server group string    #使用虚拟服务器组

Virtual server的配置

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 {
    url {
        path <URL_PATH>             #定义要监控的URL
        status_code <INT>           #判断上述检测机制为健康状态的响应码,一般为200s
    } 

    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
}

实战案例

实现单主的LVS-DR模式

realserver配置
[root@realserver1 ~]# yum install httpd -y
[root@realserver1 ~]# echo RS1 - 172.25.254.110 > /var/www/html/index.html
[root@realserver1 ~]# ip a a 172.25.254.100/32 dev lo
[root@realserver1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@realserver1 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@realserver1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@realserver1 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce

[root@realserver2 ~]# yum install httpd -y
[root@realserver2 ~]# echo RS1 - 172.25.254.110 > /var/www/html/index.html
[root@realserver2 ~]# ip a a 172.25.254.100/32 dev lo
[root@realserver2 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@realserver2 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@realserver2 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@realserver2 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
keepalived配置
#ka1
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
virtual_server 172.25.254.100 80 {
    delay_loop 6
    lb_algo wrr
    lb_kind DR
    protocol TCP

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

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

#ka2
[root@ka2 ~]# vim /etc/keepalived/keepalived.conf
virtual_server 172.25.254.100 80 {
    delay_loop 6
    lb_algo wrr
    lb_kind DR
    protocol TCP

    real_server 172.25.254.110 80 {
        weight 1
        HTTP_GET {
            url {
                path /
                status_code 200
            }
            connect_timeout 3
            nb_get_retry 2
            delay_before_retry 2
        }
    }
    real_server 172.25.254.120 80 {
        weight 1
        HTTP_GET {
            url {
                path /
                status_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  172.25.254.100:80 wrr
  -> 172.25.254.110:80            Route   1      0          0
  -> 172.25.254.120:80            Route   1      0          0
测试访问

故障模拟
#停止realserver1的httpd服务,会自动跳转到realserver2
[root@realserver1 ~]# systemctl stop httpd

[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  172.25.254.100:80 wrr
  -> 172.25.254.120:80            Route   1      0          10

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

在keepalived中,VRRP Script是一个重要的功能,它允许你定义一系列的检查脚本(scripts),这些脚本用于监控特定服务的健康状态。如果服务故障(即脚本返回非零值),keepalived可以基于这些脚本的输出来调整VRRP的状态,比如降级或转移主备角色。

VRRP Script的配置

[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
#定义脚本
vrrp_script check_haproxy {
    script "/etc/keepalived/test.sh"    #脚本的路径
    interval 1                          #间隔时间,单位为s
    weight -30                          #默认为0,如果设置为负数,当上面脚本返回值为0时,会将此值与本节点权重相加可以降低本节点的权重
    fall 2                              #执行脚本连续几次都失败,则转换为失败,建议设为2以上
    rise 2                              #执行脚本连续几次都成功,则转换为成功
    timeout 2                           #超时时间
}
vrrp_instance VI_0 {
    state MASTER
    interface ens33
    virtual_router_id 100
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    172.25.254.100/24 dev ens33 label ens33:1
    }
    #调用脚本
    track_script {
       check_haproxy
    }
}

#脚本
[root@ka1 ~]# cat /etc/keepalived/test.sh
#!/bin/bash
[ ! -f "/mnt/niu" ]    #如果文件存在,则返回1,如果文件不存在,则返回0

[root@ka1 ~]# chmod +x /etc/keepalived/test.sh
测试
[root@ka1 ~]# touch /mnt/niu
[root@ka1 ~]# tail /var/log/messages
Aug 17 17:34:53 ka1 Keepalived_vrrp[59704]: /etc/keepalived/test.sh exited with status 1
Aug 17 17:34:53 ka1 Keepalived_vrrp[59704]: VRRP_Script(check_haproxy) failed
Aug 17 17:34:54 ka1 Keepalived_vrrp[59704]: VRRP_Instance(VI_1) Changing effective priority                        from 80 to 50
Aug 17 17:34:54 ka1 Keepalived_vrrp[59704]: /etc/keepalived/test.sh exited with status 1
Aug 17 17:34:55 ka1 Keepalived_vrrp[59704]: /etc/keepalived/test.sh exited with status 1
Aug 17 17:34:56 ka1 Keepalived_vrrp[59704]: /etc/keepalived/test.sh exited with status 1
Aug 17 17:34:57 ka1 Keepalived_vrrp[59704]: /etc/keepalived/test.sh exited with status 1
Aug 17 17:34:58 ka1 Keepalived_vrrp[59704]: /etc/keepalived/test.sh exited with status 1
Aug 17 17:34:59 ka1 Keepalived_vrrp[59704]: /etc/keepalived/test.sh exited with status 1
Aug 17 17:35:00 ka1 Keepalived_vrrp[59704]: /etc/keepalived/test.sh exited with status 1
[root@ka1 ~]# > /var/log/messages

[root@ka1 ~]# > /var/log/messages
[root@ka1 ~]# rm -rf /mnt/niu
[root@ka1 ~]# tail /var/log/messages
Aug 17 17:36:01 ka2 Keepalived_healthcheckers[60086]: Error connecting server [172.25.254.110]:80.
Aug 17 17:36:03 ka2 Keepalived_healthcheckers[60086]: Error connecting server [172.25.254.110]:80.
Aug 17 17:36:03 ka2 Keepalived_healthcheckers[60086]: Check on service [172.25.254.110]:80 failed after 2 retry.
Aug 17 17:36:03 ka2 Keepalived_healthcheckers[60086]: Removing service [172.25.254.110]:80 from VS [172.25.254.100]:80
Aug 17 17:36:03 ka1 Keepalived_healthcheckers[60086]: Remote SMTP server [127.0.0.1]:25 connected.
Aug 17 17:36:03 ka1 Keepalived_healthcheckers[60086]: SMTP alert successfully sent.

实现HAProxy高可用

#在两个ka1和ka2先实现haproxy的配置
[root@ka1 ~]# vim /etc/haproxy/haproxy.cfg

listen webcluster
    bind 172.25.254.100:80
    mode http
    balance roundrobin
    server web1 172.25.254.110:80 check inter 3 fall 2 rise 5
    server web2 172.25.254.120:80 check inter 3 fall 2 rise 5

#在两个ka1和ka2两个节点启用内核参数
[root@ka1 ~]# vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1
[root@ka1 ~]# sysctl -p
net.ipv4.ip_nonlocal_bind = 1

[root@ka2 ~]# vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1
[root@ka2 ~]# sysctl -p
net.ipv4.ip_nonlocal_bind = 1

#在ka1中编写检测脚本
[root@ka1 ~]# vim /etc/keepalived/test.sh
#!/bin/bash
killall -0 haproxy

#给脚本添加执行权限
[root@ka1 ~]# chmod +x /etc/keepalived/test.sh

#在ka1中配置keepalived
[root@ka1 ~]#vim /etc/keepalived/keepalived.conf
vrrp_script check_haproxy {
    script "/etc/keepalived/test.sh"
    interval 1
    weight -30
    fall 2
    rise 2
    timeout 2
}


vrrp_instance VI_0 {
    state MASTER
    interface ens33
    virtual_router_id 100
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.25.254.100/24 dev ens33 label ens33:1
    }


    track_script {
        check_haproxy
    }
}
测试
[root@ka1 ~]# systemctl restart keepalived.service haproxy.service
                           

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

  • 29
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SUPER COW

云原生探索,您的支持,动力无限

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值