4-1-Keepalived

熊 0 阅读 Linux集群服务

1. keepalived简介

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

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

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

1.1 Keepalived是什么?

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

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

1.2 VRRP协议与工作原理

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

熟悉网络的学员对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 , 这种选举角色切换非常之快 , 因而保证了服务的持续可用性。

1.3 Keepalived工作原理

keepalived-struct-1

上面我们介绍了Keepalived通过VRRP实现高可用性的工作原理 , 而Keepalived作为一个高性能集群软件 , 它还能实现对集群中服务器运行状态的监控以及故障隔离 , 下面我们介绍一下Keepalived对服务器运行状态和故障隔离的工作原理。

Keepalived工作在TCP/IP 参考模型的 三层、四层、五层,也就是分别为 : 网络层 、传输层和应用层 , 根据TCP、IP参数模型隔层所能实现的功能 , Keepalived运行机制如下 :

在网络层 , 我们知道运行这4个重要的协议 : 互联网络IP协议 , 互联网络可控制报文协议ICMP、地址转换协议ARP、反向地址转换协议RARP 。在网络层Keepalived在网络层采用最常见的工作方式是通过ICMP协议向服务器集群中的每一个节点发送一个ICMP数据包(有点类似与Ping的功能) , 如果某个节点没有返回响应数据包 , 那么认为该节点发生了故障 , Keepalived将报告这个节点失效 , 并从服务器集群中剔除故障节点。

在传输层 , 提供了两个主要的协议 : 传输控制协议TCP和用户数据协议UDP , 传输控制协议TCP可以提供可靠的数据输出服务、IP地址和端口 , 代表TCP的一个连接端 , 要获得TCP服务,需要在发送机的一个端口和接收机的一个端口上建立连接 , 而Keepalived在传输层里利用了TCP

协议的端口连接和扫描技术来判断集群节点的端口是否正常 , 比如对于常见的WEB服务器80端口。或者SSH服务22端口 , Keepalived 一旦在传输层探测到这些端口号没有数据响应和数据返回 , 就认为这些端口发生异常 , 然后强制将这些端口所对应的节点从服务器集群中剔除掉。

在应用层 : 可以运行FTP , TELNET , SMTP , DNS等各种不同类型的高层协议 ,Keepalived的运行方式也更加全面化和复杂化, 用户可以通过自定义Keepalived工作方式 , 例如 : 可以通过编写程序或者脚本来运行Keepalived , 而Keepalived将根据用户的设定参数检测各种程序或者服务是否允许正常,如果Keepalived的检测结果和用户设定的不一致时 , Keepalived将把对应的服务器从服务器集群中剔除

1.4 Keepalived 体系结构

keepalive-struct-1

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

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

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

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

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

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

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

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

    • Core componets 这部分主要保护呢了5个部分

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

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

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

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

      • Netlink Reflector :用来实现高可用集群Failover时虚拟IP(VIP)的设置和切换 ,Netlink Reflector的所有请求最后都发送到内核空间层的NETLINK模块来完成。

2. keepalived安装

2.1 包安装

  • CentOS7安装

    [root@centos ~]#yum install keepalived 
  • CentOS8安装

    [root@centos8 ~]#dnf -y install keepalived
  • Ubuntu安装

    root@ubuntu2110:~# apt-get install keepalived

2.2 编译安装

  • CentOS7

    [root@centos7 ~]# yum install  ipvsadm libnfnetlink-devel gcc curl openssl-devel libnl3-devel net-snmp-devel libnl libnl-devel
    [root@centos7 ~]# wget https://keepalived.org/software/keepalived-2.2.7.tar.gz
    [root@centos7 ~]# mkdir /opt/app/keepalived -pv
    ​
    [root@centos7 ~]# tar -xf keepalived-2.2.7.tar.gz 
    [root@centos7 ~]# cd keepalived-2.2.7
    [root@centos7 keepalived-2.2.7]# ./configure --with-init=systemd --with-systemdsystemunitdir=/usr/lib/systemd/system --prefix=/opt/app/keepalived/ --runstatedir=/opt/app/keepalived/run
    # --with-init : 指定系统初始的启动类型
    # --with-systemdsystemunitdir : 指定系统服务运行文件目录
    # --prefix : 将架构文件放置在指定的目录中[/usr/local]
    # --runstatedir : 可修改的每进程数据[LOCALSTATEDIR/run]
    # --mandir: 帮助手册指定目录[DATAROOTDIR/man]
    ​
    [root@centos7 keepalived-2.2.7]# make && make install
    ​
  • ubuntu2204

    root@ubuntu2204:~# tar -xf keepalived-2.2.7.tar.gz
    root@ubuntu2204:~# mkdir /opt/app/keepalived -pv
    root@ubuntu2204:~/keepalived-2.2.7# apt-get install gcc libssl-dev ipvsadm build-essential libpopt-dev libnl-3-dev libnl-genl-3-dev libnfnetlink-dev libsnmp-dev
    root@ubuntu2204:~/keepalived-2.2.7# ./configure --with-init=systemd --with-systemdsystemunitdir=/usr/lib/systemd/system --prefix=/opt/app/keepalived/ --runstatedir=/opt/app/keepalived/run 
    
    root@ubuntu2204:~/keepalived-2.2.7# make && make install
  • ubuntu2110

    root@ubuntu2110:~# tar -xf keepalived-2.0.20.tar.g
    root@ubuntu2110:~# mkdir /opt/app/keepalived -pv
    ​
    root@ubuntu2110:~/keepalived-2.0.20# apt-get install gcc libssl-dev ipvsadm build-essential libpopt-dev libnl-3-dev libnl-genl-3-dev libnfnetlink-dev
    ​
    root@ubuntu2110:~/keepalived-2.0.20# ./configure --with-init=systemd --with-systemdsystemunitdir=/usr/lib/systemd/system --prefix=/opt/app/keepalived/ --runstatedir=/opt/app/keepalived/run 
    ​
    root@ubuntu2110:~/keepalived-2.0.20# make && make install
    ​
    root@ubuntu2110:~# cat /etc/profile.d/keepalived.sh 
    export PATH=/opt/app/keepalived/bin/:/opt/app/keepalived/sbin/:$PATH
    ​
    root@ubuntu2110:~# cat /etc/manpath.config 
    MANPATH_MAP /opt/app/keepalived/sbin/          /opt/app/keepalived/share/man/
    MANPATH_MAP     /opt/app/keepalived/bin/               /opt/app/keepalived/share/man/
    root@ubuntu2110:~# mandb
    ​
    修改keepalive 的system配置文件中pid的位置
    root@ubuntu2201:~/keepalived-2.2.7# vim /usr/lib/systemd/system/keepalived.service 
    [Unit]
    Description=LVS and VRRP High Availability Monitor
    After=network-online.target syslog.target 
    Wants=network-online.target 
    Documentation=man:keepalived(8)
    Documentation=man:keepalived.conf(5)
    Documentation=man:genhash(1)
    Documentation=https://keepalived.org
    ​
    [Service]
    Type=forking
    PIDFile=/opt/app/keepalived/run/keepalived.pid
    KillMode=process
    EnvironmentFile=-/opt/app/keepalived/etc/sysconfig/keepalived
    ExecStart=/opt/app/keepalived/sbin/keepalived  $KEEPALIVED_OPTIONS
    ExecReload=/bin/kill -HUP $MAINPID
    ​
    [Install]
    WantedBy=multi-user.target
    ​
  • CentOS8

    [root@centos8 ~]# tar -xf keepalived-2.2.7.tar.gz 
    [root@centos8 ~]# mkdir /opt/app/keepalived -pv
    
    [root@centos8 keepalived-2.2.7]# dnf install gcc gcc-c++ make automake openssl-devel ipvsadm net-snmp-devel libnl3-devel 
    [root@centos8 keepalived-2.2.7]# ./configure --with-init=systemd --with-systemdsystemunitdir=/usr/lib/systemd/system --prefix=/opt/app/keepalived/ --runstatedir=/opt/app/keepalived/run 
    
    [root@centos8 keepalived-2.2.7]# make && make install

注: build-essential是Debian系的meta package的名字 , RH系里可以运行

yum install make automake gcc gcc-c++ kernel-devel

或者大而全的话

yum groupinstall "Development Tools" "Development Libraries"

--disable-fwmark : 编译过程中可以使用该参数禁用fwmark

3. keepalive配置

3.1 配置文件

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

  • 主程序文件 : /usr/sbin/keepalived

  • 提供校验码 : /usr/bin/genhash

  • Unit File的环境配置文件

    • /etc/sysconfig/keepalived (CentOS)

    • /etc/default/keepalived(Ubuntu)

  • Unit File : /usr/lib/systemd/system/keepalived.service

可以通过在主配置文件中添加include /etc/keepalived/conf.d/*.conf将配置分配到其他文件中。

3.1.1 守护进程

keepalived命令行参数如下:

  • -f, –use-file=FILE : 使用指定的配置文件 , 默认配置文件是"/etc/keepalived/keepalived.conf"。

  • -P, –vrrp : 只运行VRRP子系统。这对于不使用IPVS负载均衡的配置很有用。

  • -C, –check : 只运行健康检查子系统。这对于将IPVS负载均衡与单个导向器一起使用而没有故障切换的配置很有用。

  • -l, –log-console : 将消息记录到本地控制台。默认行为是将消息记录到syslog。

  • -D, –log-detail : 详细的日志信息。

  • -S, –log-facility=[0-7] : 设置syslog设施为LOG_LOCAL [0-7]。默认的syslog设施是LOG_DAEMON。

  • -V,–dont-release-vrrp : 在守护进程停止时不要删除VRRP VIP和VROUTE。默认行为是在keepalived退出时删除所有VIP和VROUTE。

  • -I,–dont-release-ipvs : 在守护进程停止时不要删除IPVS拓扑。默认行为是在keepalived退出时 , 它将从IPVS虚拟服务器表中删除所有条目。

  • -R, –dont-respawn : 不要重新派生子进程。默认行为是如果任一进程退出 , 就重新启动VRRP和checker子进程。

  • -n, –dont-fork : 不要派生守护进程。此选项将导致keepalived在前台运行。

  • -d , –dump-conf : 转储配置数据。

  • -p, –pid=FILE : 将指定的pidfile文件用于父级keepalived进程。Keepalived的默认pid文件是 "/var/run/keepalived.pid" 。

  • -r, –vrrp_pid=FILE : 将指定的pidfile文件用于VRRP子进程。VRRP子进程的默认pid文件是" /var/run/keepalived_vrrp.pid " 。

  • -c, –checkers_pid=FILE : 将指定的pidfile文件用于checker子进程。checker子进程的默认pid文件是 " /var/run/keepalived_checkers.pid "。

  • -x, –snmp : 启用SNMP子系统。

  • -v, –version : 显示版本并退出。

  • -h, –help : 显示此帮助信息并退出。

3.1.2 genhash 实用程序

genhash二进制文件用于生成只要字符串。genhash的命令行参数如下 :

  • –use-ssl, -S : 使用SSL连接到服务器。

  • –server <host>, -s : 指定要连接的IP地址。

  • –port <port>, -p : 指定要连接的端口。

  • –url <url>,-u : 指定要生成哈希值的文件路径。

  • –use-virtualhost <host>, -V : 指定要与HTTP请求头(host字段)一起发送的虚拟主机

  • –hash <alg>, -H : 指定哈希算法以生成目标页面的摘要。请参阅帮助信息,查看带有默认标记的可用列表。

  • –verbose, -v : 输出详细信息。

  • –help, -h : 显示此帮助信息并退出。

  • –release, -r : 显示版本号并退出。

3.1.3 Unit File配置文件

[root@centos7 ~]# cat /usr/lib/systemd/system/keepalived.service
[Unit]
Description=LVS and VRRP High Availability Monitor
After=syslog.target network-online.target
​
[Service]
Type=forking
PIDFile=/var/run/keepalived.pid
KillMode=process
EnvironmentFile=-/etc/sysconfig/keepalived
ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
​
[Install]
WantedBy=multi-user.target
​

3.2 配置说明

Keepalived的所有配置都在一个配置文件里面 , 主要分为三类 :

  • 全局配置

  • VRRPD配置

  • LVS配置

配置文件是以配置块的形式存在 , 每个配置块都在一个闭合的{}范围内 , 所以编辑的时候需要注意大括号的闭合问题。#和!开头都是注释。

配置段

说明

global_defs

全局配置段: 定义邮件配置 、route_id、vrrp配置、多播地址等

vrrp_instance

实例配置段: 定义每个vrrp虚拟路由器

vrrp_script

健康检查脚本段

vrrp_sync_group

绑定多个instance实例为一个组,同生共死

virtual_server

用来搭配lvs(一种基于内核的四层负载均衡)

3.2.1 全局配置

全局配置是对整个Keepalived生效的配置 , 一个典型的配置如下 :

global_defs {
   notification_email {         #设置 keepalived 在发生事件(比如切换)的时候,需要发送到的email地址,可以设置多个,每行一个。
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc    #设置通知邮件发送来自于哪里,如果本地开启了sendmail的话,可以使用上面的默认值。
   smtp_server 192.168.200.1     #指定发送邮件的smtp服务器。
   smtp_connect_timeout 30       #设置smtp连接超时时间,单位为秒。
   router_id LVS_DEVEL           #是运行keepalived的一个表示,多个集群设置不同。
   vrrp_strict                   #严格执行VRRP协议规范,不允许状况:1,没有VIP地址;2.配置了单播邻居;3.在VRRP版本2中有IPv6地址.
   vrrp_skip_check_adv_addr      #所有报文都检查比较消耗性能,此配置为如果收到的报文和上一个报文是同一个路由器则跳过检查报文中的源地址    
   vrrp_garp_interval 0          #ARP报文发送延迟
   vrrp_gna_interval  0          #消息发送延迟
   vrrp_mcast_group4  224.0.0.18 #默认组播IP地址,224.0.0.0到239.255.255.255
   vrrp_iptables                 #此项和vrrp_strict同时开启时,则不会添加防火墙规则,如果无配置vrrp_strict项,则无需启用此项配置
   script_user keepalived_script #指定运行脚本的用户名和组。默认使用用户的默认组。如未指定,默认为keepalived_script 用户,如无此用户,则使用root
   enable_script_security        #如果路径为非root可写,不要配置脚本为root用户执行。
}

参数说明

  • smtp_server 127.0.0.1 [<PORT>] : 指定发送邮件的smtp服务器。

  • smtp_connect_timeout 30 : 设置smtp连接超时时间,单位为秒。

  • router_id <STRING> : 运行Keepalived服务器的一个标识。发邮件时显示在邮件标题中的信息。默认为本地的主机名

  • vrrp_mcast_group4 224.0.0.18 : 默认组播IP地址 , 224.0.0.0到239.255.255.255

  • default_interface eth0 : 设置静态地址默认绑定的端口。默认是eth0。

  • lvs_sync_daemon <INTERFACE> <VRRP_INSTANCE> [id <SYNC_ID>] [maxlen <LEN>] [port <PORT>] [ttl <TTL>] [group <IP ADDR>] :

    设置LVS同步服务的相关内容。可以同步LVS的状态信息。

    • INTERFACE : 指定同步服务绑定的接口。

    • VRRP_INSTANCE : 指定同步服务绑定的VRRP实例。

    • id <SYNC_ID> : 指定同步服务所使用的SYNCID , 只有相同的SYNCID才会同步。范围是0-255。

    • maxlen : 指定数据包的最大长度。范围是1-65507

    • port : 指定同步所使用的UDP端口。

    • group : 指定组播IP地址。

  • lvs_flush : 在keepalived启动时 , 刷新所有已经存在的LVS配置。

  • lvs_flush_on_stop [VS] : 关闭时刷新剩余的LVS配置(对于大型配置,这比单独删除每个RS和每个VS的默认方法要快得多)。 如果指定了VS , 请删除每个 keepalive 托管virtual server,而不显式删除后端的real server(内核将删除它们)。

  • vrrp_garp_master_delay 10 : 当转换为MASTER状态时 , 延迟多少秒发送第二组的免费ARP。默认为5s , 0表示不发送第二组免的免费ARP。

  • vrrp_garp_master_repeat 1 : 当转换为MASTER状态时 , 在一组中一次发送的免费ARP数量。默认是5.

  • vrrp_garp_lower_prio_delay 10 : 当MASTER收到更低优先级的通告时 , 延迟多少秒发送第二组的免费ARP。

  • vrrp_garp_lower_prio_repeat 1 : 当MASTER收到更低优先级的通告时 , 在一组信息中一次发送的免费ARP数量。

  • vrrp_garp_master_refresh 60 : 当keepalived成为MASTER以后 , 刷新免费ARP的最小时间间隔(会再次发送免费ARP)。默认是0 , 表示不会刷新。

  • vrrp_garp_master_refresh_repeat 2 : 当keepalived成为MASTER以后 , 每次刷新会发送多少个免费ARP。默认是1.

  • vrrp_garp_interval 0.001 : 在一个接口发送的两个免费ARP之间的延迟。可以精确到毫秒级。默认是0.

  • vrrp_gna_interval 0 : 消息发送延迟

  • vrrp_lower_prio_no_advert true|false : 默认是false。如果收到低优先级的通告,不发送任何通告。

  • vrrp_higher_prio_send_advert [<BOOL>] : 如果我们是主服务器并且收到优先级更高的通告信息 , 在过渡为BACKUP之前发送一个通过信息(其优先级将低于其他主服务器)。这意味着如果另一个主节点设置了garp_lower_priority_repeat , 它将重新发送garp消息。 这是为了解决他们同时是两个master的问题 , 最后看到的 GARP消息来自我们。

  • vrrp_version 2|3 : 设置默认的VRRP版本。默认是2.

  • vrrp_check_unicast_src : 在单播模式中,开启对VRRP数据包的源地址做检查,源地址必须是单播邻居之一。

  • vrrp_mcast_group4 : 设置默认的组播地址

  • vrrp_skip_check_adv_addr : 默认是不跳过检查。检查收到的VRRP通告中的所有地址可能会比较耗时,设置此命令的意思是,如果通告与接收的上一个通告来自相同的master路由器,则不执行检查(跳过检查)。

  • vrrp_strict:严格遵守VRRP协议。下列情况将会阻止启动Keepalived:1. 没有VIP地址。2. 单播邻居。3. 在VRRP版本2中有IPv6地址。

  • vrrp_iptables : 不添加任何iptables规则。默认是添加iptables规则的。

如果vrrp进程或check进程超时 , 可以用下面的4个选项。可以使处于BACKUP状态的VRRP实例变成MASTER状态 , 即使MASTER实例依然在运行。因为MASTER或BACKUP系统比较慢 , 不能及时处理VRRP 数据包。

  • vrrp_priority <-20 -- 19>:设置VRRP进程的优先级。

  • checker_priority <-20 -- 19>:设置checker进程的优先级。

  • vrrp_no_swap:vrrp进程不能够被交换。

  • checker_no_swap:checker进程不能够被交换。

  • script_user <username> [groupname]:设置运行脚本默认用户和组。如果没有指定, 则默认用户为keepalived_script(需要该用户存在), 否则为root用户。默认groupname同username。

  • enable_script_security:如果脚本路径的任一部分对于非root用户来说 , 都具有可写权限,则不会以root身份运行脚本。

  • nopreempt : 默认是抢占模式 要是用非抢占式的就加上nopreempt

static_ipaddress、static_routes和static_rule区域配置的是是本节点的IP和路由信息。如果你的机器上已经配置了IP和路由,那么这两个区域可以不用配置。其实,一般情况下你的机器都会有IP地址和路由信息的,因此没必要再在这两个区域配置。 rules 与routes的使用语法与ip rule add和ip route add 一样

注:

static_ipaddress {
    10.210.214.163/24 brd 10.210.214.255 dev eth0
    ...
}
static_routes {
    10.0.0.0/8 via 10.210.214.1 dev eth0
    ...
}

static_rules {
	from 192.168.2.0/24 table 1 track_group GROUP1

	to 192.168.2.0/24 table 1

	from 192.168.28.0/24 to 192.168.29.0/26 table small iif p33p1
						 oif wlan0 tos 22 fwmark 24/12
		 				 preference 39 realms 30/20 goto 40

	to 1:2:3:4:5:6:7:0/112 from 7:6:5:4:3:2::/96 table 6908
						 uidrange 10000-19999

	to 1:2:3:4:6:6:7:0/112 from 8:6:5:4:3:2::/96 l3mdev protocol 12
					     ip_proto UDP sport 10-20 dport 20-30
    ...
}

注意:上述为global_defs中的指令

3.2.2 VRRPD配置

VRRPD的配置是Keepalived比较重要的配置 , 主要分为两个部分VRRP同步组和VRRP实例 , 也就是想要使用VRRP进行高可用选举 , 那么就一定需要配置一个VRRP实例 , 在实例中来定义VIP、服务器角色等。

3.2.2.1 VRRP Sync Groups

post-1660-607c390a53781

不使用Sync Group的话 , 如果机器(或者说router) 有两个网段 , 一个内网一个外网 , 每个网段开启一个VRRP实例 , 假设VRRP配置为检查内网 , 那么当外网出现问题时 , VRRPD认为自己仍然健康 , 那么不会发生Master和Backup的切换 , 从而导致了问题。Sync group就是为了解决这个问题 , 可以把两个实例都放进一个Sync Group , 这样的话 , group里面任何一个实例出现问题都会发生切换。

当vip正常时候在LVS调度器1上,出现故障进行切换后在LVS调度器2上,如果此时dip还是在LVS调度器1上那么就会出现无法访问的情况,所以需要将vip与dip进行捆绑 , 一个切换另一个也跟着切换,这样可以保证报文的正常转发

作用 : 将所有相关的VRRP实例定义在一起,作为一个VRRP Group,如果组内的任意一个实例出现问题,都可以实现Failover

vrrp_sync_group VG_1{ #监控多个网段的实例
group {
    VI_1 #实例名
    VI_2
    ......
}
​
vrrp_instance VI_1 {
    eth0
    vip
}
​
vrrp_instance VI_2 {
    eth1
    dip
}
notify_master /path/xx.sh     #指定当切换到master时,执行的脚本
netify_backup /path/xx.sh     #指定当切换到backup时,执行的脚本
notify_fault "path/xx.sh VG_1"   #故障时执行的脚本
notify /path/xx.sh 
smtp_alert   #使用global_defs中提供的邮件地址和smtp服务器发送邮件通知
}

  • 说明 : 如果username和groupname没有指定 , 则以默认的script_user所指定的用户和组。

    1. notify_master /path/to_master.sh [username [groupname]]

      作用 : 当成为MASTER时 , 以指定的用户和组执行脚本。

    2. notify_backup /path/to_backup.sh [username [groupname]]

      作用 : 当成为BACKUP时 , 以指定的用户和组执行脚本。

    3. notify_fault "/path/fault.sh VG_1" [username [groupname]]

      作用 : 当该同步组Fault时 , 以指定的用户和组执行脚本。

    4. notify /path/notify.sh [username [groupname]]

      作用 : 在任何状态都会以指定的用户和组执行脚本。

      说明 : 该脚本会在notify_*脚本后执行。

      notify可以使用3个参数 , 如下 :

      • $1:可以是GROUP或INTANCE , 表明后面是组还是实例。

      • $2 : 组名或实例名。

      • $3 : 转换后的目标状态。有 : MASTER、BACKUP、FAULT。

    5. smtp_alert : 当状态发生改变时 , 发送邮件。

    6. global_tracking : 所有的VRRP实例共享相同的tracking配置。

    注意 : 脚本文件要加上x权限 , 同时指令最好写绝对路径。

3.2.2.2 vrrp_instance

post-1660-607c39026f0aa

上图中蓝色皆为可选配置项,黄色为应使用配置项

补充:

  • vrrp_notify

    vrrp_notify是在触发了keepalived状态切换之后 ,才会执行的操作。可以编写一些邮件通知之类的,当keepalived状态变化之后 , 自动通知相关人员 ,并根据脚本自动启停一些服务等。

    • notify的具体用法:

      notify_master : 当前节点成为master时 , 执行脚本(一般用于启动某服务 , 比如nginx等)

      notify_backup : 当前节点成为backup时 , 执行脚本(一般用于关闭某服务 , 比如nginx等)

      notify_fault : 当前节点出现故障 , 执行的任务;

      notify_stop <STRING>|<QUOTED-STRING> [username [groupname]] : 当停止VRRP时执行的脚本。

  • track_script{} : 用于启用已定义的检测动作(脚本) , 详见下文。

  • 虚拟mac: 每个虚拟路由器都有一个虚拟mac地址 , 默认为00-00-5e-00-01-virtual_router_id , 这里的virutal_router_id显示16进制。

VRRP实例(instance)配置

VRRP实例就表示在上面开启了VRRP协议 , 这个实例说明了VRRP的一些特征 , 比如主从 VRID等 , 可以在每个interface上开启一个实例。

vrrp_instance VI_1 {    
    interface eth0       #指定实例绑定的网卡
    virtual_router_id 51 #设置VRID标记,多个集群不能重复(0..255)
    priority 100         #设置优先级,优先级高的会被竞选为Master,Master要高于BACKUP至少50
    advert_int 1         #检查的时间间隔,默认1s
    nopreempt            #设置为不抢占,说明:这个配置只能在BACKUP主机上面设置
    preempt_delay        #抢占延迟,默认5分钟
    debug                #debug级别
    authentication {     #设置认证
        auth_type PASS    #认证方式,支持PASS和AH,官方建议使用PASS
        auth_pass 1111    #认证的密码
    }
    virtual_ipaddress {     #设置VIP,可以设置多个,用于切换时的地址绑定。格式:#<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPT> label <LABE
        192.168.200.16/24 dev eth0 label eth0:1
        192.168.200.17/24 dev eth1 label eth1:1  #ip关联至网口,定义名称
        192.168.200.18     #简单模式
    }
}

  • 选项说明

    • state MASTER|BACKUP : 指定该keepalived节点的初始状态。

    • interface eth0 : vrrp实例绑定的接口 , 用于发送VRRP包。

    • use_vmac [<VMAC_INTERFACE>] : 在指定的接口产生一个子接口 , 如vrrp.51 , 该接口的MAC地址为组播地址 , 通过该接口向外发送和接收VRRP包。

    • vmac_xmit_base : 通过基本接口向外发送和接收VRRP数据包 , 而不是通过VMAC接口。如果配置了use_mac参数, 必须配置该参数vmac_xmit_base。

    • native_ipv6 : 强制VRRP实例使用IPV6.(当同时配置了IPV4和IPV6的时候)

    • garp master delay : 在切换到master状态后 , 延迟进行免费的ARP(gratuitous ARP)请求

    • dont_track_primary : 忽略VRRP接口的错误 , 默认是没有配置的。

    track_interface {  
    	eth0  
    	eth1 weight <-254-254>  
    	... 
    }

    如果track的接口有任何一个出现故障 ,都会进入FAULT状态。

    track_script {
    	<SCRIPT_NAME>
    	<SCRIPT_NAME> weight <-254-254>
    }

    添加一个track脚本(vrrp_script配置的脚本。)

    • mcast_src_ip <IPADDR> : 指定发送组播数据包的源IP地址。默认是绑定VRRP实例的接口的主IP地址。

    • unicast_src_ip <IPADDR> : 指定发送单播数据包的源IP地址。默认是绑定VRRP实例的接口的主IP地址。

    • version 2|3 : 指定该实例所使用的VRRP版本。

    unicast_peer {
       <IPADDR>
       ...
    }

    采用单播的方式发送VRRP通告 , 指定单播邻居的IP地址。

    • 接口特定设置,与全局参数相同。默认为全局参数

      garp_master_delay 10
      garp_master_repeat 1
      garp_lower_prio_delay 10
      garp_lower_prio_repeat 1
      garp_master_refresh 60
      garp_master_refresh_repeat 2
    • virtual_router_id 51 : 指定VRRP实例ID , 范围是0-255。设置VRID标记

    • priority 100 : 指定优先级 , 优先级高的将成为MASTER。 Master要高于BACKUP至少50

    • advert_int 1 : 指定发送VRRP通告的间隔。单位是秒。

    authentication {
      auth_type PASS|AH:指定认证方式。PASS简单密码认证(推荐),AH:IPSEC认证(不推荐)。
      auth_pass 1234:指定认证所使用的密码。最多8位。
    }
    virtual_ipaddress {
       <IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>
       192.168.200.17/24 dev eth1
       192.168.200.18/24 dev eth2 label eth2:1
    }

    指定VIP地址。

    • virtual routes : 原理和virtual ipaddress一样,只不过这里是增加和删除路由

    • lvs_sync_daemon interface : lvs syncd绑定的网卡

    • nopreempt : 设置为不抢占。默认是抢占的,当高优先级的机器恢复后 , 会抢占低优先级的机器成为MASTER , 而不抢占 , 则允许低优先级的机器继续成为MASTER , 即使高优先级的机器已经上线。如果要使用这个功能,则初始化状态必须为BACKUP。

    • preempt_delay:设置抢占延迟。单位是秒 , 范围是0---1000 , 默认是0.发现低优先级的MASTER后多少秒开始抢占。

    • debug : debug级别

    • skip_check_adv_addr : 参考全局vrrp_skip_check_adv_addr描述 , 其中设置了默认值。默认值为 vrrp_skip_check_adv_addr

    • strict_mode [on|off|true|false|yes|no] : 参考全局vrrp_strict的说明 , 如果未指定 strict_mode , 则取值vrrp_strict。如果指定了不带参数的strict_mode , 则默认为on。

      strict_mode [on|off|true|false|yes|no]

3.2.3 LVS配置

虚拟服务器virtual_server定义块 , 虚拟服务器定义是keepalived框架最重要的项目了 , 是keepalived.conf必不可少的部分。 该部分是用来管理LVS的 , 是实现keepalive和LVS相结合的模块。ipvsadm命令可以实现的管理在这里都可以通过参数配置实现 , 注意:real_server是被包含在virtual_server模块中的 , 是子模块。

virtual_server{
	… ...
	real_server{
		… ...
	}
}

3.2.3.1 virtual_server

virtual_server IP Port | virtual_server fwmark int | virtual_server group string {

  lb_algo rr|wrr|lc|wlc|lblc|sh|dh:LVS调度算法。
  lb_kind NAT|DR|TUN:LVS模式。
  persistence_timeout 360:持久化超时时间,单位是秒。默认是6分钟。
  persistence_granularity:持久化连接的颗粒度。
  protocol TCP|UDP|SCTP:4层协议。
  ha_suspend:如果virtual server的IP地址没有设置,则不进行后端服务器的健康检查。
  virtualhost <STRING>:为HTTP_GET和SSL_GET执行要检查的虚拟主机。如virtualhost www.felix.com
  sorry_server <IPADDR> <PORT>:添加一个备用服务器。当所有的RS都故障时。
  sorry_server_inhibit:将inhibit_on_failure指令应用于sorry_server指令。

  alpha:在keepalived启动时,假设所有的RS都是down,以及健康检查是失败的。有助于防止启动时的误报。默认是禁用的。
  omega:开启omega模式,清除rs时会执行quorum_down指令所定义的相应的脚本(rs的notify_up,quorum_up),默认为禁用模式 

  quorum <INT>:默认值1. 所有的存活的服务器的总的最小权重。
  quorum_up <STRING>:当quorum增长到满足quorum所定义的值时,执行该脚本。
  quorum_down <STRING>:当quorum减少到不满足quorum所定义的值时,执行该脚本。
}
  • delay_loop <INT> : 健康检查的时间间隔。

  • lb_algo rr|wrr|lc|wlc|lblc|sh|dh : LVS后端调度算法

    等同于, 建议使用lvs_sched v2.0.0之后版本已经弃用lb_algo

    lvs_sched rr|wrr|lc|wlc|lblc|sh|mh|dh|fo|ovf|lblcr|sed|nq|twos

  • lb_kind NAT/DR/TUN : LVS集群模式

    等同于lvs_method ,v2.0.0之后已经弃用lb_kind建议使用lvs_method

    lvs_method NAT|DR
    lvs_method TUN [type {ipip|gue port NUM|gre} [nocsum|csum|remcsum]]
  • persistence_timeout <INT> :持久化超时时间,单位是秒。默认是6分钟。

  • persistence_granularity <NETMASK> : LVS会话保持粒度 , ipvsadm中的-M参数。默认为255.255.255.255。

  • protocol TCP|UDP|SCTP : 指定四层协议类型

  • ha_suspend : 如果未设置VS IP 地址 , 则暂停healthchecker的活动

  • virtualhost <string> : HTTP_GET做健康检查时 , 检查的web服务器的虚拟主机(即host:头)

  • sorry_server <IPADDR> <PORT> : 备用机 , 就是当所有后端realserver节点都不可用时 , 就用这里设置的,也就是临时把所有的请求都发送到这里来

  • sorry_server_inhibit : 将inhibit_on_failure指令应用于sorry_server指令。

  • inhibit_on_failure :

  • sorry_server_lvs_method NAT| DR

  • sorry_server_lvs_method TUN [type {ipip|gue port NUM|gre} [nocsum|csum|remcsum]]

  • quorum <INTEGER> : 保证整个集群正常运行的情况,后端Virtual server运行的最小数量。默认为1

  • quorum_up <STRING>|<QUOTED-STRING> [username [groupname]] : 当默认的运行的Virtual Server高于quorum指定的法定人数时,运行脚本

  • quorum_down <STRING>|<QUOTED-STRING> [username [groupname]] : 当默认的运行的Virtual Server低于quorum指定的法定人数时,运行脚本

  • alpha : 在keepalived启动时 , 假设所有的RS都是down,以及健康检查是失败的。有助于防止启动时的误报。默认是禁用的。

  • omega : 开启omega模式 , 清除rs时会执行quorum_down指令所定义的相应的脚本(rs的notify_up , quorum_up) , 默认为禁用模式

  • ip_family inet|inet6 :fwmark 服务的IP协议类型

v2版本后新增参数如下

  • sorry_server_lvs_method NAT| DR : 指定sorry_server的lvs类型

  • sorry_server_lvs_method TUN [type {ipip|gue port NUM|gre} [nocsum|csum|remcsum]]

  • connect_timeout <TIMER> : 可选连接超时(以秒为单位)。默认值为 5 秒

  • retry <INTEGER> : 在检查活着的服务器失败时进行额外检查次数

  • delay_before_retry <TIMER> : 失败后重试前延迟。对于DNS_CHECK默认为delay_loop。HTTP_GET和SSL_GET为3秒 , 否则为1秒。

  • warmup <TIMER> : 可选的随机延迟,用于开始初始检查,最长 N 秒。用于将多个同时检查分散到同一RS。默认情况下启用 , 最大值为 delay_loop。指定 0 以禁用

  • delay_loop <TIMER> : 检查器轮询的延迟计时器(如果未指定,则为 60 秒)

  • inhibit_on_failure : healthchecker检测到失败时 , 设置weight为0 。表示在节点失败后把他权重设置成0 而不是在IPVS中删除该条目。

3.2.3.2 real_server

real_server IP Port {
  weight <INT>:给服务器指定权重。默认是1.
  inhibit_on_failure:当服务器健康检查失败时,将其weight设置为0,而不是从Virtual Server中移除。
  notify_up <STRING>:当服务器健康检查成功时,执行的脚本。
  notify_down <STRING>:当服务器健康检查失败时,执行的脚本。
  uthreshold <INT>:到这台服务器的最大连接数。
  lthreshold <INT>:到这台服务器的最小连接数。
}
  • weight <INTEGER> : 指定服务器的权重。默认为1

  • inhibit_on_failure : 当服务器健康检查失败时,将其weight设置为0 , 而不是从Virtual Server中移除。

  • notify_up <STRING>|<QUOTED-STRING> [username [groupname]] : 当服务器健康检查成功时,执行的脚本。

  • notify_down <STRING>|<QUOTED-STRING> [username [groupname]] : 当服务器健康检查失败时,执行的脚本。

  • uthreshold <INTEGER> : 到这台服务器的最大连接数。

  • lthreshold <INTEGER> : 到这台服务器的最小连接数。

以下均是v2.0.0以后版本出现选项

  • lvs转发方式

    lvs_method NAT|DR
    lvs_method TUN [type {ipip|gue port NUM|gre} [nocsum|csum|remcsum]]
  • virtualhost <STRING> : HTTP_GET或SSL_GET的默认虚拟主机字符串

  • alpha <BOOL> : 在keepalived启动时 , 假设所有的RS都是down,以及健康检查是失败的。有助于防止启动时的误报。默认是禁用的。

  • connect_timeout <TIMER> :可选连接超时(以秒为单位)。默认值为 5 秒

  • retry <INTEGER> : 在检查活着的服务器失败时进行额外检查次数

  • delay_before_retry <TIMER> : 失败后重试前延迟。对于DNS_CHECK默认为delay_loop。HTTP_GET和SSL_GET为3秒 , 否则为1秒。

  • delay_loop <TIMER> : 检查器轮询的延迟计时器(如果未指定,则为 60 秒)

3.2.3.3 real_server监控检查

  • 所有检查器都有以下选项。MISC_CHECK只有alpha以上的选项 , BFD_CHECK和FILE_CHECK没有标准选项。该检查选项只有v2.0.0版本之后才有。v2之前的版本中该检查选项中的所有参数,主要存在于其他选项中。V2兼容v1版本的配置

    CHECKER_TYPE {
     	# 通用连接选项
     	# 设置可选择连接的IP地址。默认是realserver的IP
     	connect_ip <IPADDR>
     
     	# 可选择连接的端口, 默认为realserver端口
     	connect_port <PORT>
     
     	# 用于发起连接的可选地址
     	bindto <IPADDR>
     
     	# 选择使用的接口;如果bindto地址是IPv6链接本地,则需要
     	bind_if <IFNAME>
     
     	# 用于发起连接的可选源端口
     	bind_port <PORT>
     
     	# 用于在所有发出的检查器数据包上标记
     	fwmark <INTEGER>
     
     	alpha <BOOL>                    # see above
     	connect_timeout <TIMER>         # see above
     	retry <INTEGER>                 # see above
     	delay_before_retry <TIMER>      # see above
     	warmup <TIMER>                  # see above
     	delay_loop <TIMER>              # see above
     	log_all_failures <BOOL>         # log all failures when checker up
     }
  • HTTP和SSL健康检查器

    HTTP_GET | SSL_GET {
    		url {
    			path <STRING>:指定要检查的URL的路径。如path / or path /mrtg2
    			digest <STRING>:摘要。计算方式:genhash -s 172.17.100.1 -p 80 -u /index.html
    			status_code <INT>:状态码。
    		}
    		nb_get_retry <INT>:get尝试次数。
    		delay_before_retry <INT>:在尝试之前延迟多长时间。
    
    		connect_ip <IP ADDRESS>:连接的IP地址。默认是real server的ip地址。
    		connect_port <PORT>:连接的端口。默认是real server的端口。
    		bindto <IP ADDRESS>:发起连接的接口的地址。
    		bind_port <PORT>:发起连接的源端口。
    		connect_timeout <INT>:连接超时时间。默认是5s。
    		fwmark <INTEGER>:使用fwmark对所有出去的检查数据包进行标记。
    		warmup <INT>:指定一个随机延迟,最大为N秒。可防止网络阻塞。如果为0,则关闭该功能。
    } 
    
    v2.0.0以后参数
    HTTP_GET|SSL_GET {
    		#HTTP协议版本,1.0、1.0C、1.1中的一个 协议版本1.0C指的是1.0版本,增加了 "Connection: close "一行,1.1版本默认包括这一行。
    		http_protocol <PROTOCOL>
    		# 设置 alpha 模式或从故障中恢复时,将检查每个 URL,每次检查之间有 <delay_loop> 延迟。 如果有 20 个 URL,并且 <delay_loop> 为 3 秒,则 RS 在启动或从故障中恢复后需要 1 分钟才能出现。 设置 fast_recovery 消除了启动时和从故障中恢复后的延迟,这意味着一旦检查了所有 URL,RS 就会出现,在检查每个 URL 之间没有延迟。
    		fast_recovery [<BOOL>]
    		# 要测试的 URL 可以在此处包含多个条目
    		url {
    		  #指定要检查的URL的路径。如path / or path /mrtg2
    		  path <STRING>
    		  # 摘要。计算方式:genhash -s 172.17.100.1 -p 80 -u /index.html
    		  digest <STRING>
    		  # HTTP 标头中返回的状态代码,例如 status_code 200 或 status_code 200-299 400-499 503 505
    		  # 默认值为 200-299
    		  status_code <INTEGER|RANGE> [<INTEGER|RANGE>] ...
    		  # 虚拟主机字符串。例如虚拟主机www.firewall.loc,如果未设置,则使用真实或虚拟服务器中的虚拟主机
    		  virtualhost <STRING>
    		  
    		  #用于搜索返回数据的正则表达式。匹配失败会导致检查失败。
    		  regex <STRING>
    		  
    		  #返回文本的匹配会导致检查失败。
    		  regex_no_match
    
    		  # 返回数据中开始检查正则表达式模式匹配的最小偏移量。 如果返回的数据很大,这可以节省处理时间。
    		  regex_min_offset <OFFSET>
    		  # 主题匹配开始时返回数据的最大偏移量。
    		  regex_max_offset <OFFSET>
    		}
    }
    
    SSL_GET {
    		# when provided, send Server Name Indicator during SSL handshake
    		#提供后,在 SSL 握手期间发送服务器名称指示符
    		enable_sni
    }
  • TCP检查器

    TCP_CHECK {
    		connect_ip <IP ADDRESS>:连接的IP地址。默认是real server的ip地址。
    		connect_port <PORT>:连接的端口。默认是real server的端口。
    		bindto <IP ADDRESS>:发起连接的接口的地址。
    		bind_port <PORT>:发起连接的源端口。
    		connect_timeout <INT>:连接超时时间。默认是5s。
    		fwmark <INTEGER>:使用fwmark对所有出去的检查数据包进行标记。
    		warmup <INT>:指定一个随机延迟,最大为N秒。可防止网络阻塞。如果为0,则关闭该功能。
    		retry <INIT>:重试次数。默认是1次。
    		delay_before_retry <INT>:默认是1秒。在重试之前延迟多少秒。
    }
    
    
    v2.0.0以后配置
    TCP_CHECK {
    		# 无其他选项
    }
  • SMTP检查器

    
    SMTP_CHECK {
    		connect_ip <IP ADDRESS>:连接的IP地址。默认是real server的ip地址。
    		connect_port <PORT>:连接的端口。默认是real server的端口。 默认是25端口
    		bindto <IP ADDRESS>:发起连接的接口的地址。
    		bind_port <PORT>:发起连接的源端口。
    		connect_timeout <INT>:连接超时时间。默认是5s。
    		fwmark <INTEGER>:使用fwmark对所有出去的检查数据包进行标记。
    		warmup <INT>:指定一个随机延迟,最大为N秒。可防止网络阻塞。如果为0,则关闭该功能。
    
    		retry <INT>:重试次数。
    		delay_before_retry <INT>:在重试之前延迟多少秒。
    		helo_name <STRING>:用于SMTP HELO请求的字符串。
    }
    
    
    v2.0.0以后选项
    SMTP_CHECK {
    		# 用于SMTP HELO请求的字符串。
    		helo_name <STRING>|<QUOTED-STRING>
    }
  • DNS健康检查器

    DNS_CHECK {
    		connect_ip <IP ADDRESS>:连接的IP地址。默认是real server的ip地址。
    		connect_port <PORT>:连接的端口。默认是real server的端口。 默认是25端口
    		bindto <IP ADDRESS>:发起连接的接口的地址。
    		bind_port <PORT>:发起连接的源端口。
    		connect_timeout <INT>:连接超时时间。默认是5s。
    		fwmark <INTEGER>:使用fwmark对所有出去的检查数据包进行标记。
    		warmup <INT>:指定一个随机延迟,最大为N秒。可防止网络阻塞。如果为0,则关闭该功能。
    
    		retry <INT>:重试次数。默认是3次。
    		type <STRING>:DNS query type。A/NS/CNAME/SOA/MX/TXT/AAAA
    		name <STRING>:DNS查询的域名。默认是(.)
    }
    
    
    v2.0.0以后参数
    DNS_CHECK {
    		# The retry default is 3.
    
    		# DNS query type :A|NS|CNAME|SOA|MX|TXT|AAAA
    		# 默认为SOA
    		type <STRING>
    
    		# DNS查询的域名。默认是. (dot)
    		# The default is . (dot)
    		name <STRING>
    }
  • MISC健康检查器

    MISC_CHECK {
    		misc_path <STRING>:外部的脚本或程序路径。
    		misc_timeout <INT>:脚本执行超时时间。
    		user USERNAME [GROUPNAME]:指定运行该脚本的用户和组。如果没有指定GROUPNAME,则GROUPNAME同USERNAME。
     		misc_dynamic:根据退出状态码动态调整权重。
              0,健康检查成功,权重不变。
              1,健康检查失败。
              2-255,健康检查成功。权重设置为退出状态码减去2.如退出状态码是250,则权重调整为248
    		warmup <INT>:指定一个随机延迟,最大为N秒。可防止网络阻塞。如果为0,则关闭该功能。
    }
    
    MISC_CHECK {
    		# The retry default is 0.
    
    		# 外部的脚本或程序路径。
    		misc_path <STRING>|<QUOTED-STRING>
    		# 脚本执行超时时间。
    		misc_timeout <INTEGER>
    
    		# 根据退出状态码动态调整权重。
              0,健康检查成功,权重不变。
              1,健康检查失败。
              2-255,健康检查成功。权重设置为退出状态码减去2.如退出状态码是250,则权重调整为248
    		misc_dynamic
    
    		# 指定运行该脚本的用户和组。如果没有指定GROUPNAME,则GROUPNAME同USERNAME。
    		user USERNAME [GROUPNAME]
    }

示例一

virtual_server 192.168.202.200 23 {        //VIP地址,要和vrrp_instance模块中的virtual_ipaddress地址一致
		delay_loop 6   #健康检查时间间隔 
		lb_algo rr   #lvs调度算法rr|wrr|lc|wlc|lblc|sh|dh 
		lb_kind DR    #负载均衡转发规则NAT|DR|RUN 
		persistence_timeout 5 #会话保持时间 
		protocol TCP    #使用的协议 
		persistence_granularity <NETMASK> #lvs会话保持粒度 
		virtualhost <string>    #检查的web服务器的虚拟主机(host:头) 
		sorry_server<IPADDR> <port> #备用机,所有realserver失效后启用


		real_server 192.168.200.5 23 {             //RS的真实IP地址
			weight 1 #默认为1,0为失效
			inhibit_on_failure #在服务器健康检查失效时,将其设为0,而不是直接从ipvs中删除 
            notify_up <string> | <quoted-string> #在检测到server up后执行脚本
            notify_down <string> | <quoted-string> #在检测到server down后执行脚本
            
			TCP_CHECK {                    //常用
            	connect_timeout 3 #连接超时时间
            	nb_get_retry 3 #重连次数
            	delay_before_retry 3 #重连间隔时间
            	connect_port 23  #健康检查的端口的端口
            	bindto <ip>   
          	}

			HTTP_GET | SSL_GET{          //不常用
    			url{ #检查url,可以指定多个
         		path /
         		digest <string> #检查后的摘要信息
         		status_code 200 #检查的返回状态码
        			}
    		connect_port <port> 
    		bindto <IPADD>
    		connect_timeout 5
    		nb_get_retry 3
    		delay_before_retry 2
		}

		SMTP_CHECK{                 //不常用
			host{
				connect_ip <IP ADDRESS>
				connect_port <port> #默认检查25端口
				bindto <IP ADDRESS>
				}
			connect_timeout 5
			retry 3
			delay_before_retry 2
			helo_name <string> | <quoted-string> #smtp helo请求命令参数,可选
		}

		MISC_CHECK{                 //不常用
    		misc_path <string> | <quoted-string> #外部脚本路径
    		misc_timeout #脚本执行超时时间
    		misc_dynamic #如设置该项,则退出状态码会用来动态调整服务器的权重,返回0 正常,不修改;返回1,
						 #检查失败,权重改为0;返回2-255,正常,权重设置为:返回状态码-2
    	}
}

示例二

! Configuration File for keepalived
global_defs {                                     #全局定义部分
    notification_email {                          #设置报警邮件地址,可设置多个
        acassen@firewall.loc                      #接收通知的邮件地址
    }                        
    notification_email_from test0@163.com         #设置 发送邮件通知的地址
    smtp_server smtp.163.com                      #设置 smtp server 地址,可是ip或域名.可选端口号 (默认25)
    smtp_connect_timeout 30                       #设置 连接 smtp server的超时时间
    router_id LVS_DEVEL                           #主机标识,用于邮件通知
    vrrp_skip_check_adv_addr                   
    vrrp_strict                                   #严格执行VRRP协议规范,此模式不支持节点单播
    vrrp_garp_interval 0                       
    vrrp_gna_interval 0     
    script_user keepalived_script                 #指定运行脚本的用户名和组。默认使用用户的默认组。如未指定,默认为keepalived_script 用户,如无此用户,则使用root
    enable_script_security                        #如过路径为非root可写,不要配置脚本为root用户执行。
}       

vrrp_script chk_nginx_service {                   #VRRP 脚本声明
    script "/etc/keepalived/chk_nginx.sh"         #周期性执行的脚本
    interval 3                                    #运行脚本的间隔时间,秒
    weight -20                                    #权重,priority值减去此值要小于备服务的priority值
    fall 3                                        #检测几次失败才为失败,整数
    rise 2                                        #检测几次状态为正常的,才确认正常,整数
    user keepalived_script                        #执行脚本的用户或组
}                                             

vrrp_instance VI_1 {                              #vrrp 实例部分定义,VI_1自定义名称
    state MASTER                                  #指定 keepalived 的角色,必须大写 可选值:MASTER|BACKUP
    interface ens33                               #网卡设置,lvs需要绑定在网卡上,realserver绑定在回环口。区别:lvs对访问为外,realserver为内不易暴露本机信息
    virtual_router_id 51                          #虚拟路由标识,是一个数字,同一个vrrp 实例使用唯一的标识,MASTER和BACKUP 的 同一个 vrrp_instance 下 这个标识必须保持一致
    priority 100                                  #定义优先级,数字越大,优先级越高。
    advert_int 1                                  #设定 MASTER 与 BACKUP 负载均衡之间同步检查的时间间隔,单位为秒,两个节点设置必须一样
    authentication {                              #设置验证类型和密码,两个节点必须一致
        auth_type PASS                        
        auth_pass 1111                        
    }                                         
    virtual_ipaddress {                           #设置虚拟IP地址,可以设置多个虚拟IP地址,每行一个
        192.168.119.130                       
    }
    track_script {                                #脚本监控状态
        chk_nginx_service                         #可加权重,但会覆盖声明的脚本权重值。chk_nginx_service weight -20
    }
        notify_master "/etc/keepalived/start_haproxy.sh start"  #当前节点成为master时,通知脚本执行任务
        notify_backup "/etc/keepalived/start_haproxy.sh stop"   #当前节点成为backup时,通知脚本执行任务
        notify_fault  "/etc/keepalived/start_haproxy.sh stop"   #当当前节点出现故障,执行的任务; 
}                                             

virtual_server 192.168.119.130 80  {          #定义RealServer对应的VIP及服务端口,IP和端口之间用空格隔开
    delay_loop 6                              #每隔6秒查询realserver状态
    lb_algo rr                                #后端调试算法(load balancing algorithm)
    lb_kind DR                                #LVS调度类型NAT/DR/TUN
    #persistence_timeout 60                   同一IP的连接60秒内被分配到同一台realserver
    protocol TCP                              #用TCP协议检查realserver状态
    real_server 192.168.119.120 80 {          
        weight 1                              #权重,最大越高,lvs就越优先访问
        TCP_CHECK {                           #keepalived的健康检查方式HTTP_GET | SSL_GET | TCP_CHECK | SMTP_CHECK | MISC
            connect_timeout 10                #10秒无响应超时
            retry 3                           #重连次数3次
            delay_before_retry 3              #重连间隔时间
            connect_port 80                   #健康检查realserver的端口
        }                                     
    }                                         
    real_server 192.168.119.121 80 {          
        weight 1                              #权重,最大越高,lvs就越优先访问
        TCP_CHECK {                           #keepalived的健康检查方式HTTP_GET | SSL_GET | TCP_CHECK | SMTP_CHECK | MISC
            connect_timeout 10                #10秒无响应超时
            retry 3                           #重连次数3次
            delay_before_retry 3              #重连间隔时间
            connect_port 80                   #健康检查realserver的端口
        }                                     
    }                                         
}                                             

vrrp_instance VI_2 {                          #vrrp 实例部分定义,VI_1自定义名称
    state   BACKUP                            #指定 keepalived 的角色,必须大写 可选值:MASTER|BACKUP 分别表示(主|备)
    interface ens33                           #网卡设置,绑定vip的子接口,lvs需要绑定在网卡上,realserver绑定在回环口。区别:lvs对访问为外,realserver为内不易暴露本机信息
    virtual_router_id 52                      #虚拟路由标识,是一个数字,同一个vrrp 实例使用唯一的标识,MASTER和BACKUP 的 同一个 vrrp_instance 下 这个标识必须保持一致
    priority 90                               #定义优先级,数字越大,优先级越高。
    advert_int 1                              #设定 MASTER 与 BACKUP 负载均衡之间同步检查的时间间隔,单位为秒,两个节点设置必须一样
    authentication {                          #设置验证类型和密码,两个节点必须一致
        auth_type PASS                        
        auth_pass 1111                        
    }                                         
    virtual_ipaddress {                       #设置虚拟IP地址,可以设置多个虚拟IP地址,每行一个
        192.168.119.131                       
    }                                         
}                                             

virtual_server 192.168.119.131 80 {           #定义RealServer对应的VIP及服务端口,IP和端口之间用空格隔开
    delay_loop 6                              #每隔6秒查询realserver状态
    lb_algo rr                                #后端调试算法(load balancing algorithm)
    lb_kind DR                                #LVS调度类型NAT/DR/TUN
    #persistence_timeout 60                   #同一IP的连接60秒内被分配到同一台realserver
    protocol TCP                              #用TCP协议检查realserver状态
    real_server 192.168.119.120 80 {          
        weight 1                              #权重,最大越高,lvs就越优先访问
        TCP_CHECK {                           #keepalived的健康检查方式HTTP_GET | SSL_GET | TCP_CHECK | SMTP_CHECK | MISC
            connect_timeout 10                #10秒无响应超时
            retry 3                           #重连次数3次
            delay_before_retry 3              #重连间隔时间
            connect_port 80                   #健康检查realserver的端口
        }                                     
    }                                         
    real_server 192.168.119.121 80 {          
        weight 1                              #权重,最大越高,lvs就越优先访问
        TCP_CHECK {                           #keepalived的健康检查方式HTTP_GET | SSL_GET | TCP_CHECK | SMTP_CHECK | MISC
            connect_timeout 10                #10秒无响应超时
            retry 3                           #重连次数3次
            delay_before_retry 3              #重连间隔时间
            connect_port 80                   #健康检查realserver的端口
        }
    }
}

3.2.3.4 配置示例

DR Real_server初始化脚本

#!/bin/sh
#LVS DR模式初始化脚本
LVS_VIP=192.168.194.17
source /etc/rc.d/init.d/functions
case "$1" in 
start)
		/sbin/ifconfig lo:0 $LVS_VIP netmask 255.255.255.255 broadcast
		/sbin/route add -host $LVS_VIP dev lo:0
		echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
		echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce
		echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
		echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
		sysctl -p > /dev/null 2>&1
		echo "RealServer Start OK"
		;;
stop)
		/sbin/ifconfig lo:0 down
		/sbin/route del $LVS_VIP >/dev/null 2>&1
		echo "0" > /proc/sys/net/ipv4/conf/lo/arp_ignore
		echo "0" > /proc/sys/net/ipv4/conf/lo/arp_announce
		echo "0" > /proc/sys/net/ipv4/conf/all/arp_ignore
		echo "0" > /proc/sys/net/ipv4/conf/all/arp_announce
		echo "RealServer Stoped"
        ;;
*)
		echo "Usage: $0 {start|stop}"
		exit 1
esac
exit 0

master角色配置

[root@centos72 ~]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   #vrrp_iptables
}
include /etc/keepalived/conf.d/*.conf


[root@centos72 ~]# cat /etc/keepalived/conf.d/VI_1.conf 
vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 100
    priority 100
    use_vmac vrrp.12
    vmac_xmit_base
    unicast_peer {
        192.168.194.130
        192.168.194.145
    }
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456789
    }
    virtual_ipaddress {
        192.168.194.16/24  dev ens33  label ens33:0
        192.168.194.17/24  dev ens33  label ens33:1 
        192.168.194.18/24  dev ens33  label ens33:2
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}
virtual_server 192.168.194.17 80 {
    delay_loop 3
    lb_algo wrr
    lb_kind DR
    #persistence_timeout 20
    protocol TCP

    real_server 192.168.194.141 80 {
         weight 1
         #TCP_CHECK {
         #    connect_timeout 5
         #    nb_get_retry 3
         #    delay_defore_retry 3
         #    connect_port 80
         #}
         HTTP_GET {
              url {
                  path /monitor/monitor.html
                  status_code 200
              }
              connect_timeout 5
              nb_get_retry 3
              delay_defore_retry 3
              connect_port 80
         }
    }

    real_server 192.168.194.131 80 {
         weight 1
         #TCP_CHECK {
         #    connect_timeout 5
         #    nb_get_retry 3
         #    delay_defore_retry 3
         #    connect_port 80
         #}
         HTTP_GET {
              url {
                  path /monitor/monitor.html
                  status_code 200
              }
              connect_timeout 5
              nb_get_retry 3
              delay_defore_retry 3
              connect_port 80
         }

    }

}

backup角色配置

[root@centos71 ~]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   #vrrp_iptables
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 100
    priority 80
    use_vmac vrrp.12
    vmac_xmit_base
    unicast_peer {
        192.168.194.145
        192.168.194.146  
    }
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456789
    }
    virtual_ipaddress {
        192.168.194.16/24 dev ens33 label ens33:0 
        192.168.194.17/24 dev ens33 label ens33:1
        192.168.194.18/24 dev ens33 label ens33:2
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}
virtual_server 192.168.194.17 80 {
    delay_loop 3
    lb_algo wrr
    lb_kind DR
    #persistence_timeout 20
    protocol TCP
    
    real_server 192.168.194.141 80 {
         weight 1
         #TCP_CHECK {
         #    connect_timeout 5
         #    nb_get_retry 3
         #    delay_defore_retry 3
         #    connect_port 80
         #}
         HTTP_GET {
              url {
                  path /monitor/monitor.html
                  status_code 200
              }
              connect_timeout 5
              nb_get_retry 3
              delay_defore_retry 3
              connect_port 80
         }
    }

    real_server 192.168.194.131 80 {
         weight 1
         #TCP_CHECK {
         #    connect_timeout 5
         #    nb_get_retry 3
         #    delay_defore_retry 3
         #    connect_port 80
         #}
         HTTP_GET {
              url {
                  path /monitor/monitor.html
                  status_code 200
              }
              connect_timeout 5
              nb_get_retry 3
              delay_defore_retry 3
              connect_port 80
         }

    }

}

3.2.4 启用keepalived日志功能

[root@keepalived ~]#cat /etc/sysconfig/keepalived | grep -Ev '^#|^$'
KEEPALIVED_OPTIONS="-D -S 6"

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

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

3.2.5 实现独立子配置文件

当生产环境复杂时 , /etc/keepalived/keepalived.conf 文件中内容过多 , 不易管理 , 可以将不同集群的配置 , 比如: 不同集群的VIP配置放在独立的子配置文件中

利用include指令可以实现包含子配置文件

  • 格式 : include /path/file

[root@keepalive ~]#mkdir /etc/keepalived/conf.d/
[root@keepalive ~]#cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
[root@keepalive ~]#ls /etc/keepalived/
conf.d  keepalived.conf  keepalived.conf.bak

[root@keepalive ~]#vim /etc/keepalived/keepalived.conf
[root@keepalive ~]#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

include /etc/keepalived/conf.d/*.conf       #将VRRP相关配置放在子配置文件中

4. Keepalive模式说明

4.1 组播配置

默认情况下 , Keepalived模式使用的是组播。

#MASTER 
[root@centos72 ~]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   vrrp_iptables
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 100
    priority 100
    use_vmac 
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456789
    }
    virtual_ipaddress {
        192.168.194.16/24  dev ens33  label ens33:0
        192.168.194.17/24  dev ens33  label ens33:1 
        192.168.194.18/24  dev ens33  label ens33:2
    }
}

#BACKUP  
[root@centos71 ~]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   vrrp_iptables
}

vrrp_instance VI_2 {
    state BACKUP
    interface ens33
    virtual_router_id 100
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456789
    }
    virtual_ipaddress {
        192.168.194.16/24 dev ens33 label ens33:0 
        192.168.194.17/24 dev ens33 label ens33:1
        192.168.194.18/24 dev ens33 label ens33:2
    }
}

4.2 单播配置

单播的主要实现方式,是通过unicast_src_ip <IPADDR> 、unicast_peer {}实现。单播模式需要注意需要注释vrrp_strict、vrrp_iptables这两行。可选: unicast_src_ip指定单播源IP。使用过程中建议使用use_vmac单独创建一个网口发单播包

#MASTER
[root@centos72 ~]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   #vrrp_iptables
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 100
    priority 100
    use_vmac vrrp.12
    unicast_peer {
        192.168.194.130
        192.168.194.145
    }
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456789
    }
    virtual_ipaddress {
        192.168.194.16/24  dev ens33  label ens33:0
        192.168.194.17/24  dev ens33  label ens33:1 
        192.168.194.18/24  dev ens33  label ens33:2
    }
}

#BACKUP
[root@centos71 ~]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   #vrrp_iptables
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 100
    priority 80
    use_vmac vrrp.12
    unicast_peer {
        192.168.194.145
        192.168.194.146  
    }
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456789
    }
    virtual_ipaddress {
        192.168.194.16/24 dev ens33 label ens33:0 
        192.168.194.17/24 dev ens33 label ens33:1
        192.168.194.18/24 dev ens33 label ens33:2
    }
}

4.3 抢占/非抢占模式配置

keepalived默认为抢占模式。这一章节中主要讲解非抢占模式与抢占延时模式

  • 非抢占模式中,非抢占式不再有主从之分 , 全部都为BACKUP,并且配置文件中添加nopreempt,用来标识为非抢占式;nopreempt主要配置与高优先级的keepalived主机中

    #high priority BACKUP
    [root@centos71 ~]# cat /etc/keepalived/keepalived.conf 
    ! Configuration File for keepalived
    
    global_defs {
       notification_email {
         acassen@firewall.loc
         failover@firewall.loc
         sysadmin@firewall.loc
       }
       notification_email_from Alexandre.Cassen@firewall.loc
       smtp_server 192.168.200.1
       smtp_connect_timeout 30
       router_id LVS_DEVEL
       vrrp_skip_check_adv_addr
       #vrrp_strict
       vrrp_garp_interval 0
       vrrp_gna_interval 0
       #vrrp_iptables
    }
    
    vrrp_instance VI_1 {
        state BACKUP
        interface ens33
        virtual_router_id 100
        priority 80
        #nopreempt
        unicast_peer {
            192.168.194.145 
        }
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 123456789
        }
        virtual_ipaddress {
            192.168.194.16/24 dev ens33 label ens33:0 
            192.168.194.17/24 dev ens33 label ens33:1
            192.168.194.18/24 dev ens33 label ens33:2
        }
    }
    
    #lower priority  BACKUP
    [root@centos73 ~]# cat /etc/keepalived/keepalived.conf 
    ! Configuration File for keepalived
    
    global_defs {
       notification_email {
         acassen@firewall.loc
         failover@firewall.loc
         sysadmin@firewall.loc
       }
       notification_email_from Alexandre.Cassen@firewall.loc
       smtp_server 192.168.200.1
       smtp_connect_timeout 30
       router_id LVS_DEVEL
       vrrp_skip_check_adv_addr
       #vrrp_strict
       vrrp_garp_interval 0
       vrrp_gna_interval 0
       #vrrp_iptables
    }
    
    vrrp_instance VI_1 {
        state BACKUP
        interface ens33
        virtual_router_id 100
        priority 60
        advert_int 1
        nopreempt
        unicast_peer {
            192.168.194.130
        }
        authentication {
            auth_type PASS
            auth_pass 123456789
        }
        virtual_ipaddress {
            192.168.194.16/24 dev ens33 label ens33:0 
            192.168.194.17/24 dev ens33 label ens33:1
            192.168.194.18/24 dev ens33 label ens33:2
        }
    }
  • 抢占延时模式。即优先级高的主机恢复后 , 不会立即抢回VIP , 而是延迟一段时间(默认300s)再抢回VIP

    抢占延时模式中主要通过preempt_delay决定延迟的时间。需要各keepalived服务器state为BACKUP,并且不要启用vrrp_strict

    #high priority BACKUP
    [root@centos71 ~]# cat /etc/keepalived/keepalived.conf 
    ! Configuration File for keepalived
    
    global_defs {
       notification_email {
         acassen@firewall.loc
         failover@firewall.loc
         sysadmin@firewall.loc
       }
       notification_email_from Alexandre.Cassen@firewall.loc
       smtp_server 192.168.200.1
       smtp_connect_timeout 30
       router_id LVS_DEVEL
       vrrp_skip_check_adv_addr
       #vrrp_strict
       vrrp_garp_interval 0
       vrrp_gna_interval 0
       #vrrp_iptables
    }
    
    vrrp_instance VI_1 {
        state BACKUP
        interface ens33
        virtual_router_id 100
        priority 80
        #nopreempt
        preempt_delay 60
        unicast_peer {
            192.168.194.145
            #192.168.194.146  
        }
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 123456789
        }
        virtual_ipaddress {
            192.168.194.16/24 dev ens33 label ens33:0 
            192.168.194.17/24 dev ens33 label ens33:1
            192.168.194.18/24 dev ens33 label ens33:2
        }
    }
    
    #lower priority BACKUP 
    [root@centos73 ~]# cat /etc/keepalived/keepalived.conf 
    ! Configuration File for keepalived
    
    global_defs {
       notification_email {
         acassen@firewall.loc
         failover@firewall.loc
         sysadmin@firewall.loc
       }
       notification_email_from Alexandre.Cassen@firewall.loc
       smtp_server 192.168.200.1
       smtp_connect_timeout 30
       router_id LVS_DEVEL
       vrrp_skip_check_adv_addr
       #vrrp_strict
       vrrp_garp_interval 0
       vrrp_gna_interval 0
       #vrrp_iptables
    }
    
    vrrp_instance VI_1 {
        state BACKUP
        interface ens33
        virtual_router_id 100
        priority 60
        advert_int 1
        #nopreempt
        preempt_delay 60
        unicast_peer {
            192.168.194.130
            #192.168.194.146
        }
        authentication {
            auth_type PASS
            auth_pass 123456789
        }
        virtual_ipaddress {
            192.168.194.16/24 dev ens33 label ens33:0 
            192.168.194.17/24 dev ens33 label ens33:1
            192.168.194.18/24 dev ens33 label ens33:2
        }
    }

5. Keepalived 通知配置

5.1 发件人配置

mailx命令是Linux中专门用来发送和接收邮件的命令。

[root@centos72 ~]# yum install mailx

5.1.1 mailx选项说明

选项说明如下:

  • -a : 给定的文件附加到邮件中。

  • -b : 将密件抄送至列表。 列表应为逗号分隔的名称列表。

  • -c : 将抄送副本发送到用户列表。

  • -e : 只需检查系统邮箱中是否存在邮件即可。 如果是 , 则返回退出状态为零 , 否则返回非零值。

  • -E : 如果传出消息的第一个或唯一一个消息部分不包含任何文本 , 则不要发送它 , 而是静默丢弃它 , 在进程启动时有效地设置 skipemptybody变量。这对于从cron启动的脚本发送消息很有用。

  • -r address : 指定发件人

  • -f [file] : 读取用户mbox(或指定文档)的内容进行处理;当 mailx退出时 ,它会将未删除的邮件写回此文档。 字符串文档按以下文档夹命令所述进行处理。

  • -s subject : 在命令行上指定主题(仅将-s标志后的第一个参数用作主题 , 请注意引用包含空格的主题)。

  • -u : 读取给定用户名的邮箱。

  • -V : 显示版本信息并退出。

  • -? : 启用波浪逃逸 ,即使不是在交互模式。

5.1.2 配置文件说明

mailx命令的系统级配置文件是/etc/mail.rc , 用户级别的默认配置文件是~/.mailrc , 也可以通过MAILRC环境变量设置配置文件路径。

#设置发件人邮箱和昵称
set from=2973707860@qq.com  

#smtp地址
set smtp=smtp.qq.com

#这里输入邮箱账号
set smtp-auth-user=2973707860@qq.com

#这里填入密码
set smtp-auth-password=mfcjxxjezawgdgee

#认证方式
set smtp-auth=login

#忽略证书
set ssl-verify=ignore

配置说明

  • from : 对方收到邮件时显示的发件人

  • smtp : 第三方发邮件的smtp服务器地址

  • smtp-auth-user : 第三方发邮件的用户名

  • smtp-auth-password : smtp服务的认证密码

  • smtp-auth : smtp服务的认证密码;

需要注意,这里smtp-auth-password对应的是qq邮箱中下图所示的授权码。

image-20221023194309377

5.1.3 邮件发送

该命令可以有三种发邮件方式

  • 通过文件anaconda-ks.cfg中内容当做邮件正文, 并将anaconda-ks.txt当做邮件附件

    [root@centos72 ~]# mailx  -s test -a anaconda-ks.txt  xiong_wangyi@163.com < anaconda-ks.cfg 
  • 通过echo命令将123当做正文发送

    [root@centos72 ~]# echo "123" | mailx -s test2 -a anaconda-ks.cfg  xiong_wangyi@163.com
  • 直接使用以下命令, 会进入交互模式。输入正文,在输入.之后退出,并发送邮件

    [root@centos72 ~]# mail -s "none" xiong_wangyi@163.com
    fdfasdf
    dfadf
    dfadf
    dsfadf
    dfadsfadsfsdfasdfffsdfa
    sdfadfadfadf
    .
    EOT

5.2 Keepalived 配置

5.2.1 Keepalived 参数说明

notify的具体用法:

notify_master : 当前节点成为master时 , 执行脚本(一般用于启动某服务 , 比如nginx等)

notify_backup : 当前节点成为backup时 , 执行脚本(一般用于关闭某服务 , 比如nginx等)

notify_fault : 当前节点出现故障 , 执行的任务;

notify_stop <STRING>|<QUOTED-STRING> [username [groupname]] : 当停止VRRP时执行的脚本。

5.2.2 Keepalived 通知脚本

[root@centos72 ~]# cat /etc/keepalived/notify.sh 
#!/bin/bash
contact='xiong_wangyi@163.com'
notify() {
	mailsubject="$(hostname) to be $1, vip 转移"
	mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
	echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
master)
	notify master
	;;
backup)
	notify backup
	;;
fault)
	notify fault
	;;
*)
	echo "Usage: $(basename $0) {master|backup|fault}"
	exit 1
	;;
esac

5.2.3 Keepalived 配置文件

在配置文件中, 直接将以下内容添加到实例配置中

notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"

配置文件如下

[root@centos71 ~]# ll /etc/keepalived/notify.sh
-r-xr-xr-x 1 root root 421 Oct 25  2022 /etc/keepalived/notify.sh
[root@centos71 ~]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   #vrrp_iptables
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 100
    priority 80
    #nopreempt
    preempt_delay 60
    unicast_peer {
        192.168.194.145
        #192.168.194.146  
    }
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456789
    }
    virtual_ipaddress {
        192.168.194.16/24 dev ens33 label ens33:0 
        192.168.194.17/24 dev ens33 label ens33:1
        192.168.194.18/24 dev ens33 label ens33:2
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}
[root@centos71 ~]# 

6. Vrrp Script

keepalived只能做到对网络故障和keepalived本身的监控 , 即当出现网络故障或者keepalived本身出现问题时 , 进行切换。但是这些还不够 , 我们还需要监控keepalived所在服务器上的其他业务进程 , 比如说nginx 、keepalived+nginx实现nginx的负载均衡高可用 , 如果nginx异常 , 仅仅keepalived保持正常 , 是无法完成系统的正常工作的 , 因此需要根据业务进程的运行状态决定是否需要进行主备切换。这个时候 , 我们可以通过编写脚本对业务进程进行检测监控。

作用 : 添加一个周期性执行的脚本。脚本的退出状态码会被调用它的所有的VRRP Instance记录。

注意 : 至少有一个VRRP实例调用它并且优先级不能为0 , 优先级范围是1-254。

keepalived只能做到对网络故障和keepalived本身的监控 ,这些在实际中是远远不够的。 我们还需要监控keepalived所在服务器上的其他业务进程 , 根据业务进程的运行状态决定是否需要进行主备切换。 所以这个时候 , 一般都可以提前写好相关脚本 , 然后将脚本路径加入vrrp_script的配置中。这样的话 , 基本可以实现以下的功能:

# 服务器某种状态 –> 触发脚本 –> 触发keepalived主备切换
# 定义动作 “chk_mysql_port”
vrrp_script chk_mysql_port {     #检测mysql服务是否在运行。有很多方式,比如进程,用脚本检测等等
    script "/opt/chk_mysql.sh"   #这里通过脚本监测
    interval 2                   #脚本执行间隔,每2s检测一次
    weight -20                    #脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -20
    fall 2                    #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间)
    rise 1                    #检测1次成功就算成功。但不修改优先级
}

# 定义后需要在vrrp_instance配置段中启用,例如
    track_script {
     chk_mysql_port
    }
  • script "/path/to/somewhere" : 指定要执行的脚本的路径。

  • interval <INTEGER> : 指定脚本执行的间隔。单位是秒。默认为1s。

  • timeout <INTEGER> : 指定在多少秒后,脚本被认为执行失败。

  • weight <-254 --- 254> : 调整优先级。默认为2.

  • rise <INTEGER> : 执行成功多少次才认为是成功。

  • fall <INTEGER> : 执行失败多少次才认为失败。

  • user <USERNAME> [GROUPNAME] : 运行脚本的用户和组。

  • init_fail : 假设脚本初始状态是失败状态。

6.1 优先级更新策略

keepalived会定时执行脚本并对脚本执行的结果进行分析 , 动态调整vrrp_instance的优先级。

如果脚本执行结果为0 , 并且weight配置的值大于0 , 则优先级相应的增加。

如果脚本执行结果非0 , 并且weight配置的值小于0 , 则优先级相应的减少。

其他情况 , 维持原本配置的优先级 , 即配置文件中priority对应的值。

这里需要注意的是:

  1. 优先级不会不断的提高或者降低

  2. 可以编写多个检测脚本并为每个检测脚本设置不同的weight。

  3. 不管提高优先级还是降低优先级 , 最终优先级的范围是在[1,254] , 不会出现优先级小于等于0或者优先级大于等于255的情况。

这样可以做到利用脚本检测业务进程的状态 , 并动态调整优先级从而实现主备切换。

6.2 vrrp_script中节点权重改变算法

在Keepalived集群中 ,其实并没有严格意义上的主、备节点 ,虽然可以在Keepalived配置文件中设置"state"选项为"MASTER"状态 , 但是这并不意味着此节点一直就是Master角色。控制节点角色的是Keepalived配置文件中的"priority" 值 , 但并它并不控制所有节点的角色 , 另一个能改变节点角色的是在vrrp_script模块中设置的"weight"值 , 这两个选项对应的都是一个整数值 , 其中“weight”值可以是个负整数,一个节点在集群中的角色就是通过这两个值的大小决定的。

6.2.1 不设置weight

在vrrp_script模块中 , 如果不设置"weight" 选项值 , 那么集群优先级的选择将由Keepalived配置文件中的"priority"值决定 , 而在需要对集群中优先级进行灵活控制时 , 可以通过在vrrp_script模块中设置"weight"值来实现。

6.2.2 设置weight

vrrp_script里的script返回值为0时认为检测成功 , 其它值都会当成检测失败;

  1. weight为正时 , 脚本检测成功时此weight会加到priority上 ,检测失败时不加 ;

    1. 主失败:

      1. 主priority < 从priority + weight 时, 会切换。

    2. 主成功:

      1. 主priority + weight > 从priority + weight时 , 主依然为主

  2. weight为负时 , 脚本检测成功时此weight不影响priority , 检测失败时priority – abs(weight)

    1. 主失败:

      1. 主priority – abs(weight) < 从priority , 时会切换主从

    2. 主成功:

      1. 主priority> 从priority , 主依然为主

6.2.3 权重示例

keepalived配置如下:

# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
   notification_email {
         root@localhost
   }
   notification_email_from admin@lnmmp.com
   smtp_connect_timeout 3
   smtp_server 127.0.0.1
   router_id LVS_DEVEL
}
vrrp_script chk_maintaince_down {
   script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"
   interval 1
   weight 2
}
vrrp_script chk_haproxy {
    script "killall -0 haproxy"
    interval 1
    weight 2
}
vrrp_instance VI_1 {
    interface eth0
    state MASTER
    priority 100
    virtual_router_id 125
    garp_master_delay 1
    authentication {
        auth_type PASS
        auth_pass 1e3459f77aba4ded
    }
    track_interface {
       eth0
    }
    virtual_ipaddress {
        172.16.25.10/16 dev eth0 label eth0:0
    }
    track_script {
        chk_haproxy
        chk_maintaince_down
    }
    notify_master "/etc/keepalived/notify.sh master 172.16.25.10"
    notify_backup "/etc/keepalived/notify.sh backup 172.16.25.10"
    notify_fault "/etc/keepalived/notify.sh fault 172.16.25.10"
}
vrrp_instance VI_2 {
    interface eth0
    state BACKUP
    priority 99
    virtual_router_id 126
    garp_master_delay 1
    authentication {
        auth_type PASS
        auth_pass 7615c4b7f518cede
    }
    track_interface {
       eth0
    }
    virtual_ipaddress {
        172.16.25.11/16 dev eth0 label eth0:1
    }
    track_script {
        chk_haproxy
        chk_maintaince_down
    }
    notify_master "/etc/keepalived/notify.sh master 172.16.25.11"
    notify_backup "/etc/keepalived/notify.sh backup 172.16.25.11"
    notify_fault "/etc/keepalived/notify.sh fault 172.16.25.11"
}
# vi /etc/keepalived/notify.sh
#!/bin/bash
# Author: Jason.Yu <admin@lnmmp.com>
# description: An example of notify script
#
contact='root@localhost'
notify() {
    mailsubject="`hostname` to be $1: $2 floating"
    mailbody="`date '+%F %H:%M:%S'`: vrrp transition, `hostname` changed to be $1"
    echo $mailbody | mail -s "$mailsubject" $contact
}
case "$1" in
    master)
        notify master $2
        /etc/rc.d/init.d/haproxy start
        exit 0
    ;;
    backup)
        notify backup $2
        /etc/rc.d/init.d/haproxy stop
        exit 0
    ;;
    fault)
        notify fault $2
        /etc/rc.d/init.d/haproxy stop
        exit 0
    ;;
    *)
        echo 'Usage: `basename $0` {master|backup|fault}'
        exit 1
    ;;
esac

故障1: keepalived宕机恢复后VIP集体漂移故障

ah8xw-hvcgm

故障2: haproxy服务停止后重启VIP集体漂移故障

avpwo-yxu4r

问题原因

每次主备状态切换时 , 会引发notify_backup , 而在notify.sh脚本中backup部分会执行/etc/rc.d/init.d/haproxy stop ,导致权重在2个节点上都改变一次 , 从而单一节点上对于所有instance的权重都处于最大或者最小 , 故VIP集体漂移也就不奇怪了 ;

a5rhi-kt7gg
aowaz-o1y4v

处理方式 : 修改notify.sh脚本 , 在处理backup部分 , 只发送通知邮件 , 而无需刻意停止haproxy服务 ;

调整后的正常权重改变流程

as11x-yvsrd

6.3 监控机制

6.3.1 killall命令探测服务运行状态

vrrp_script check_nginx {       # check_nginx 为自定义的一个监控名称
  script "killall -0 nginx"     # 采用 killall 信号 0 来对进程运行状态进行监控,0 为正常,1 为异常
  interval 2                    # 检测间隔时间,即两秒检测一次
  weight 30                     # 一个正整数或负整数。权重值,关系到整个集群角色选举,尤为重要( 单独出帖 )
}

track_script {
  check_nginx                   # 引用上面定义的监控模块
}

6.3.2 检测端口运行状态

检测端口的运行状态也是最常见的服务监控方式 , 在keepalived的vrrp_script模块中可以通过如下方式对本机的端口进行检测:

vrrp_script check_nginx {
  script "< /dev/tcp/127.0.0.1:80"  # 通过 < /dev/tcp/127.0.0.1:80 这样的方式定义一个对本机端口状态的检测
  interval 2
  fall 2                            # 检测失败的最大次数,超过两次认为节点资源发生故障
  rise 1                            # 请求一次成功认为节点恢复正常
  weight 30
}

track_script {
  check_nginx
}

通过 "< /dev/tcp/127.0.0.1/80"这样的方式定义了一个对本机80端口的状态检测 , 其中 , “fail”选项表示检测到失败的最大次数 , 也就是说 , 如果请求失败两次 , 就认为此节点资源发生故障 , 将进行切换操作 ;"rise"表示如果请求一次成功 , 就认为此节点资源恢复正常。

6.3.3 通过shell语句进行状态监控

vrrp_script check_nginx {
  script " if [ -f /usr/local/nginx/logs/nginx.pid ]; then exit 0 ; else exit 1; fi"
  interval 2
  fall 1
  rise 1
  weight 30
}

track_script {
  check_nginx
}

通过一个shell判断语句 , 检测httpd.pid文件是否存在 , 如果存在 , 就认为状态正常 , 否则认为状态异常 , 这种监测方式对于一些简单的应用监控或者流程监控非常有用。从这里也可以得知 , vrrp_script模块支持的监控方式十分灵活。

6.3.4 通过脚本进行服务状态监控

vrrp_script chk_mysqld {
 script "/etc/keepalived/check_mysqld.sh"
 interval 2
 }

 track_script {
   chk_mysqld
  }

check_mysqld.sh的内容为:

 #!/bin/bash
/usr/bin/mysql -e "show status;" > /dev/null 2>&1
if [ $? -eq 0 ];then
   MYSQL_STATUS=0
 else
    MYSQL_STATUS=1
 fi
exit $MYSQL_STATUS

6.3.5 仲裁设备检测

所有节点上同时挂载仲裁盘, 当节点中服务出现问题时,直接在仲裁盘中写入文件。keepalived通过识别该仲裁文件实现对节点服务的监控。当存在此仲裁设备时发生故障迁移 。

适用场景:在backup服务器探测文件是否存在 , 当master运行正常的时候没有此文件 , 当master异常的时候生成此文件 ,然后将backup服务器的优先级设置高于master , 从而将VIP接管到backup服务器。

vrrp_script chk_down {
script “/bin/bash -c ‘[[ -f /etc/keepalived/device/down ]]’ && exit 0 || exit 7“ #成功退出为0
interval 1
weight +80
fall 3
rise 5
timeout 2
}


参考链接

Keepalived详细介绍简介 - losbyday - 博客园 (cnblogs.com)

Keepalived配置详解 - 别来无恙- - 博客园 (cnblogs.com)

keepalived配置文件详解 原 - 腾讯云开发者社区-腾讯云 (tencent.com)

keepalived配置说明 - 草结笔记 (caojie.blog)

Keepalived程序简介 — keepalived 1.4.3 文档 (keepalived-doc.readthedocs.io)

keepalived原理及配置文件详解_ITPUB博客

初识keepalived-孙翔个人成长记

双剑合璧(Keepalived+LVS)-孙翔个人成长记)

keepalived高可用-赛博树洞

小丑的个人博客 (5212345.cn)

KeepAlived 详解 - 西木 | Blog (icefrozen.github.io)

KeepAlived 详解 - 西木 | Blog (icefrozen.github.io)

Keepalived其它高可用性 – 孙翔个人成长记 (sunxiang.net)

keepalived中vrrp_script,track_script,notify的使用方法51CTO博客keepalived track_script

keepalived中vrrp_script,track_script,notify的使用方法 - 代搬服务器 - 博客园 (cnblogs.com)

keepalived之vrrp_script详解 - 木子木泗 - 博客园 (cnblogs.com)

Keepalived双主模型中vrrp_script中权重改变故障排查51CTO博客keepalived vrrp_script

keepalived 的 vrrp_script - 博客萨斯州 - 博客园 (cnblogs.com)