Keepalived部署与配置详解

Keepalive详解


工做原理

Keepalived本质就是为ipvs服务的,它也不须要共享存储。IPVS其实就是一些规则,Keepalived主要的任务就是去调用ipvsadm命令,来生成规则,并自动实现将用户须要访问的地址转移到可用LVS节点实现。因此keepalive的高可用是属于具备很强针对性的高可用,它和corosync这种通用性HA方案不一样。html

Keepalived的主要目的就是它自身启动为一个服务,它工做在多个LVS主机节点上,当前活动的节点叫作Master备用节点叫作Backup,Master会不停的向Backup节点通告本身的心跳,这种通告是基于VRRP协议的。Backup节点一旦接收不到Master的通告信息,它就会把LVS的VIP拿过来,而且把ipvs的规则也拿过来,在本身身上生效,从而替代Master节点linux

Keepalived除了能够监控和转移LVS资源以外,它还能够直接配置LVS而不须要直接使用ipvsadm命令,由于它能够调用,也就是说在LVS+KEEPALIVED模型中,你全部的工做在Keepalived中配置就能够了,并且它还有对后端应用服务器健康检查的功能。算法

直接一句话Keepalived就是VRRP协议的实现,该协议是虚拟冗余路由协议。后端

VRRP工做原理简述

那么这个VRRP协议是干吗用呢?传统上来讲咱们经过一个路由器上网,若是故障那就不能用了,若是使用2个路由器,有一个故障你就须要手动的设置客户端切换到另外的路由器上,或者使用ARP客户端也能够实现,但总之部署比较麻烦不利于管理,就像下图:缓存

有没有一种办法能够自动转移而省去手动配置呢?咱们就能够经过VRRP协议来实现路由器的故障转移。以下图:bash

这里有个问题,VRRP提供一个VIP,它能够来设定那个路由器是活动节点,而后出现故障进行切换,VIP也随之对应到新的路由器上,可是内网是用过MAC地址来寻址的,虽然VIP对应到了新的路由器上,但是MAC变了,客户端的ARP表也没有更新,因此仍是用不了,为了解决这个问题VRRP不但提供VIP还提供VMAC地址,这个VMAC地址是VRRP单独申请的,你们均可以正常使用。服务器

故障切换的时候虽然改变了后端路由器,可是因为客户端使用的是VIP和VMAC地址,这样就不会有任何影响了。curl

因此Keepalived就是在Linux系统上提供了VRRP功能,固然还提供了服务监控功能,好比监控后端服务器的健康检查、LVS服务可用性检查。jsp

VRRP的工做过程是这样的:tcp

  1. 虚拟路由器中的路由器根据优先级选举出Master,Master路由器经过发送免费ARP报文,将本身的虚拟MAC地址通告给与它链接的设备。
  2. Master路由器周期性发送VRRP报文,以公布本身的配置信息(优先级等)和工做状态
  3. 若是Master故障,虚拟路由器中的Backup路由器将根据优先级从新选举新的Master
  4. 虚拟路由器状态切换时,Master路由器由一台设备切换会另一台设备,新的Master路由器只是简单的发送一个携带虚拟MAC地址和虚拟IP的免费ARP报文,这样就能够更新其余设备中缓存的ARP信息
  5. Backup路由器的优先级高于Master时,由Backup的工做方式(抢占式或者非抢占式)决定是否从新选举Master。

VRRP还支持认证,就是为了防止随意一个VRRP设备加入到当前的虚拟路由组离来,它提供无认证、简单8位字符串认证和MD5认证(该认证方式Keepalive不支持)。

Keepalive软件结构

Keepalived启动后之后会有一个主进程Master,它会生成还有2个子进程,一个是VRRP Stack负责VRRP(也就是VRRP协议的实现)、一个是Checkers负责IPVS的后端的应用服务器的健康检查,当检测失败就会调用IPVS规则删除后端服务器的IP地址,检测成功了再加回来。当检测后端有失败的状况可使用SMTP通知管理员。另外VRRP若是检测到另一个Keepalive失败也能够经过SMTP通知管理员。

Control Plane:这个就是主进程,主进程的功能是分析配置文件,读取、配置和生效配置文件,指挥那2个子进程工做。

WatchDog:看门狗,这个是Linux系统内核的一个模块,它的做用是帮助主进程盯着那2个子进程,由于主进程并不负责具体工做,具体工做都是子进程完成的。若是子进程挂了,那Keepalived就不完整了,因此那2个子进程会按期的向主进程打开的一个内部Unix Socket文件写心跳信息。若是有某个子进程不写信息了,它就会重启子进程,主进程就是让WatchDog来监控子进程的。下面咱们就使用Keepalive来作LVS的高可用讲解。关于后端服务器上的设置我这里就不说了请看另一篇博文。

Keepalive安装和配置

服务器 IP地址 角色
Srv01 172.16.42.100
VIP: 172.16.42.111
LVS+Keepalive
Srv02 172.16.42.101
VIP: 192.168.100.1
LVS+Keepalive
Srv03 172.16.42.102
VIP: 172.16.42.111
Nginx
Srv04 172.16.42.103
VIP: 172.16.42.111
Nginx

先决条件

  1. 禁用SElinux、清除iptables规则、关闭防火墙。就算因某种缘由不能清除iptables规则,那么你须要增长一条规则放行多播

  2. 各个节点时间同步,启用时间同步服务systemctl start chronyd

  3. 确保Keepalive使用的网卡开启了多播,以下图:

若是没有开启,可使用该命令打开ip link set multicast on dev ens33,ens33是网卡名称。

安装keepalive

之间经过yum安装便可yum install -y keepalived。我这里使用的是阿里云的源,它默认就在里面,以下图:

在2个节点都安装。

文件 说明
/usr/sbin/keepalived 二进制程序
/etc/keepalived/keepalived.conf 配置文件
/usr/lib/systemd/system/keepalived.service 服务文件

Keepalive配置文件说明

# 全局配置
global_defs {
   # 邮件通知信息
   notification_email {
     # 定义收件人
     acassen@firewall.loc
   }
   # 定义发件人
   notification_email_from Alexandre.Cassen@firewall.loc
   # SMTP服务器地址
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   # 路由器标识,通常不用改,也能够写成每一个主机本身的主机名
   router_id LVS_DEVEL
   # VRRP的ipv4和ipv6的广播地址,配置了VIP的网卡向这个地址广播来宣告本身的配置信息,下面是默认值
   vrrp_mcast_group4 224.0.0.18
   vrrp_mcast_group6 ff02::12
}

# 定义用于实例执行的脚本内容,好比能够在线下降优先级,用于强制切换
vrrp_script SCRIPT_NAME {

}

# 一个vrrp_instance就是定义一个虚拟路由器的,实例名称
vrrp_instance VI_1 {
    # 定义初始状态,能够是MASTER或者BACKUP
    state MASTER
    # 工做接口,通告选举使用哪一个接口进行
    interface ens33
    # 虚拟路由ID,若是是一组虚拟路由就定义一个ID,若是是多组就要定义多个,并且这个虚拟
    # ID仍是虚拟MAC最后一段地址的信息,取值范围0-255
    virtual_router_id 51
    # 使用哪一个虚拟MAC地址
    use_vmac XX:XX:XX:XX:XX
    # 监控本机上的哪一个网卡,网卡一旦故障则须要把VIP转移出去
    track_interface {
        eth0
        ens33
    }
    # 若是你上面定义了MASTER,这里的优先级就须要定义的比其余的高
    priority 100
    # 通告频率,单位为秒
    advert_int 1
    # 通讯认证机制,这里是明文认证还有一种是加密认证
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    # 设置虚拟VIP地址,通常就设置一个,在LVS中这个就是为LVS主机设置VIP的,这样你就不用本身手动设置了
    virtual_ipaddress {
        # IP/掩码 dev 配置在哪一个网卡
        192.168.200.16/24 dev eth1
        # IP/掩码 dev 配置在哪一个网卡的哪一个别名上
        192.168.200.17/24 dev label eth1:1
    }
    # 虚拟路由,在须要的状况下能够设置lvs主机 数据包在哪一个网卡进来从哪一个网卡出去
    virtual_routes {
        192.168.110.0/24 dev eth2
    }
    # 工做模式,nopreempt表示工做在非抢占模式,默认是抢占模式 preempt
    nopreempt|preempt
    # 若是是抢占默认则能够设置等多久再抢占,默认5分钟
    preempt delay 300
    # 追踪脚本,一般用于去执行上面的vrrp_script定义的脚本内容
    track_script {

    }
    # 三个指令,若是主机状态变成Master|Backup|Fault以后会去执行的通知脚本,脚本要本身写
    notify_master ""
    notify_backup ""
    notify_fault ""
}

# 定义LVS集群服务,能够是IP+PORT;也能够是fwmark 数字,也就是防火墙规则
# 因此经过这里就能够看出来keepalive天生就是为ipvs而设计的
virtual_server 10.10.10.2 1358 {
    delay_loop 6
    # 算法
    lb_algo rr|wrr|lc|wlc|lblc|sh|dh 
    # LVS的模式
    lb_kind NAT|DR|TUN
    # 子网掩码,这个掩码是VIP的掩码
    nat_mask 255.255.255.0
    # 持久链接超时时间
    persistence_timeout 50
    # 定义协议
    protocol TCP
    # 若是后端应用服务器都不可用,就会定向到那个服务器上
    sorry_server 192.168.200.200 1358

    # 后端应用服务器 IP PORT
    real_server 192.168.200.2 1358 {
        # 权重
        weight 1
        # MSIC_CHECK|SMTP_CHEKC|TCP_CHECK|SSL_GET|HTTP_GET这些都是
        # 针对应用服务器作健康检查的方法
        MISC_CHECK {}
        # 用于检查SMTP服务器的
        SMTP_CHEKC {}

        # 若是应用服务器不是WEB服务器,就用TCP_CHECK检查
        TCP_CHECK {
          # 向哪个端口检查,若是不指定默认使用上面定义的端口
          connect_port <PORT>
          # 向哪个IP检测,若是不指定默认使用上面定义的IP地址
          bindto <IP>
          # 链接超时时间
          connect_timeout 3
        }

        # 若是对方是HTTPS服务器就用SSL_GET方法去检查,里面配置的内容和HTTP_GET同样
        SSL_GET {}

        # 应用服务器UP或者DOWN,就执行那个脚本
        notify_up "这里写的是路径,若是脚本后有参数,总体路径+参数引发来"
        notify_down "/PATH/SCRIPTS.sh 参数"

        # 使用HTTP_GET方法去检查
        HTTP_GET {
            # 检测URL
            url { 
              # 具体检测哪个URL
              path /testurl/test.jsp
              # 检测内容的哈希值
              digest 640205b7b0fc66c1ea91c463fac6334d
              # 除了检测哈希值还能够检测状态码,好比HTTP的200 表示正常,两种方法二选一便可
              status_code 200
            }
            url { 
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url { 
              path /testurl3/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            # 向哪个端口检查,若是不指定默认使用上面定义的端口
            connect_port <PORT>
            # 向哪个IP检测,若是不指定默认使用上面定义的IP地址
            bindto <IP>
            # 链接超时时间
            connect_timeout 3
            # 尝试次数
            nb_get_retry 3
            # 每次尝试之间间隔几秒
            delay_before_retry 3
        }
    }

    real_server 192.168.200.3 1358 {
        weight 1
        HTTP_GET {
            url { 
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334c
            }
            url { 
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334c
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

配置Srv01和Srv02

配置VRRP部分

Srv01上的keepalived.conf

global_defs {
   notification_email {
     acassen@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id srv01
}


vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }

    virtual_ipaddress {
        172.16.42.111/24 brd 172.16.42.111 dev ens33 label ens33:0
    }
    preempt delay 60
}

Srv02上的keepalived.conf,惟一不一样的就是state、priority以及router_id。

global_defs {
   notification_email {
     acassen@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id srv02
}


vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }

    virtual_ipaddress {
        172.16.42.111/24 brd 172.16.42.111 dev ens33 label ens33:0
    }
    preempt delay 60
}

启动2个节点,启动后会自动配置ens33:0这个子接口的虚拟IP

在主节点上你经过systemctl status keepalived看不到它究竟是什么角色,不过在BACKUP节点上你能够看到,可是你在主节点日志中cat /var/log/message里能够看到Srv01进入到MASTER状态,以下图:

查看Srv02的状态

那么你经过中止Srv01上的keepalived服务就看到MASTER会被转移到Srv02上。

使用该命令查看VRRP通告tcpdum -i ens33 -nn host 224.0.0.18,你在2台主机都会看到相同的信息。

Srv01使用真实物理IP对该地址进行发送通告,那么Srv02也会收到,若是Srv01宕机,那么Srv02就会使用本身的物理IP向该地址发送通告,因为Srv01已经宕机那么此时Srv02的优先级就是最高的,因此Srv02就变成了MASTER。

配置LVS部分

这里只是用了LVS来讲明如何配置Keepalived,若是要看完整内容请移步使用Keepalived构建LVS高可用集群

在keepalived.conf文件中增长下面的内容,2台服务器增长的内容一致,因此这里就写一份。

virtual_server 172.16.42.111 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    persistence_timeout 0
    protocol TCP

    sorry_server 192.168.200.200 1358

    # 后端应用服务器 IP PORT
    real_server 172.16.42.102 80 {
        weight 1
        # 应用服务器UP或者DOWN,就执行那个脚本
        notify_up "/usr/local/notify.sh up"
        notify_down "/usr/local/notify.sh down"
        HTTP_GET {
            # 检测URL
            url { 
              path /index.html
              # 除了检测哈希值还能够检测状态码,好比HTTP的200 表示正常,两种方法二选一便可
              status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 172.16.42.103 80 {
        weight 1
        # 应用服务器UP或者DOWN,就执行那个脚本
        notify_up "/usr/local/notify.sh up"
        notify_down "/usr/local/notify.sh down"
        HTTP_GET {
            # 检测URL
            url { 
              path /index.html
              # 除了检测哈希值还能够检测状态码,好比HTTP的200 表示正常,两种方法二选一便可
              status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

这里的notify_up|down脚本我写的很简单就是为了使用一下这个功能,内容以下:

#!/bin/bash

# 不一样的是2个主机上的echo部分不同,由于主机名不一样。
if [ $1 == "up" ]; then
  echo "Srv02 is UP" > /tmp/notify.txt
elif [ $1 == "down" ]; then
  echo "Srv02 is DOWN" > /tmp/notify.txt
fi

重启Keepalived服务以后你就能够经过ipvsadm -Ln查看ipvs规则了,这些规则在2台服务器上都会有,以下图:

测试访问

使用下面的命令快速访问for i in {1..20}; do curl http://172.16.42.111/ | grep "Srv0" --color ; done

能够看到2台服务器交替,由于咱们使用的rr调度算法。

故障转移测试

连续访问VIP,而后中止Srv01上面的keepalived服务,这就意味着Srv01也就是失去了VIP,而后观察请求状况以及是否触发以前设定的脚本。

在Srv01上查看脚本执行状况

查看Srv02上面的日志

相关文章
相关标签/搜索