目录

一、keepalived简单介绍

二、VRRP协议与工作原理

三、keepalived详细介绍

四、单、多实例及LVS-nat/dr模型实现

五、总结


一、keepalived简单介绍

keepalived是由c语言编写的一个路径选择软件,是IPVS的一个扩展性项目,为IPVS提供高可用性(故障转移)特性,它的高可用性是通过VRRP协议实现的,并实现了对负载均衡服务器池中的real server进行健康状态检测,当real server不可用时,自身实现了故障的隔离,这弥补了IPVS不能对real server服务器进行健康检测的不足,这也是keepalived运用最广泛的场景,当然keepalived不只限于实现IPVS的高可用。

keepalived软件架构

cf20f3a389e82d76d7de6a65a36a8575.jpg

下部分是内核空间,有IPVS和NETLINK两个部分组成,IPVS提供IP虚拟网络,而NETLINK提供高级的路由功能和其他相关的网络功能。上部分是用户空间,由这些组件来完成具体的功能,在核心组件中:

1)WatchDog:实现对healthchecking和VRRP进程的监控,如果子进程非法停止,父进程会重启子进程。

2)Checkers 负责real server的 healthchecking,是 keepalived 最主要的功能,它实时对real server进行测试,判断其是否存活后实现对lvs规则的添加或删除。可利用OSI模型中的第四、五、七层来进行测试。healthchecking进程由父进程监控一个独立的进程运行。

3)VRRP Stack 负责负载均衡器之间的失败切换( FailOver),由父进程监控一个独立的进程运行。

4)IPVS wrapper 用来发送设定的规则到内核 ipvs 代码。

5)Netlink Reflector 用来设定 vrrp 的 vip 地址等。

二、 VRRP协议与工作原理

keepalived:

vrrp协议:Virtual Redundant Router/RoutingProtocol,虚拟冗余路由(器)协议;

2.1 技术术语:

虚拟路由器:虚拟路由器接口;

VRID:虚拟路由器标识符,描述路由器的分组;确定该分组的虚拟Mac地址;范围0-255;

MASTER:虚拟IP地址的拥有者,能够完成数据转发功能的路由器;

BACKUP:不参与数据转发,检测MASTER的健康状态;

VIP:虚拟IP地址,虚拟路由器的IP地址;用于VIP的就是MASTER;

VMAC:00-00-5E-00-01-{VRID}

优先级:选举称为MASTER的主要参考标准,取值范围是0-255;

0:放弃MASTER选举;

255:虚拟IP地址拥有者的优先级;

1-254:越大越有可能称为MASTER;

抢占式:如果MASTER状态为down,则BACKUP中会重新选举新的MASTER;此时如果原来MASTER恢复,就立即发起新的选举,称为MASTER;

非抢占式:如果MASTER状态为down,则BACKUP中会重新选举新的MASTER;此时如果原来MASTER恢复,就自动称为BACKUP,直到MASTER状态为down,重新选举时才会成为新的MASTER;

2.2 VRRP的工作模式:

单实例:MASTER/BACKUP

多实例:MASTER/BACKUP、MASTER/MASTER

2.3工作原理

在现实的网络环境中,主机之间的通信都是通过配置静态路由(默认网关)完成的,而主机之间的路由器一旦出现故障,通信就会失败,因此,在这种通信模式中,路由器就成了一个单点瓶颈,为了解决这个问题,就引入了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出现故障,接着多台BACKUP就会进行选举,优先级最高的BACKUP将成为新的MASTER,这种选举并进行角色切换的过程非常快,因而也就保证了服务的持续可用性。

三、keepalived详细介绍

3.1 工作原理

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

在网络层,运行着四个重要的协议:互连网协议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将把对应的服务从服务器中网络推广移除。

3.2 keepalived的安装

CentOS 6.4+以上的发行版本中,keepalived的rpm包被收录在官方光盘镜像中所以配置好本地光盘的yum仓库使用yum install keepalived,之前的版本可能要编译安装。

启动软件:

[root@zj01 ~]# systenctlstart keepalived

[root@zj01 ~]# ps aux |grep keepalived

root 3385 0.9 0.3120156 1460 ? Ss 19:15 0:00 /usr/sbin/keepalived -D

root 3387 0.0 0.6122356 3000 ? S 19:15 0:00 /usr/sbin/keepalived -D

root 5745 0.0 0.0 0 0 ? D 19:15 0:00 [keepalived]

root 5749 0.0 0.1112660 968 pts/0 S+ 19:15 0:00 grep --color=autokeepalived

可以看到三个守护进程,为了keepalived的健状性和稳定性,keepalived启动后运行了三个守护进程,一个父进程,两个child进程,父进程用于监控两个child进程,两个child进程中一个是vrrp child,一个是healthchecking child。

3.3 程序环境:

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

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

Unit File:keepalived.service

3.4 keepalived.conf配置段详解

在keepalived.conf的配置文件一般分为三个配置块,一是全局定义块,二是vrrp实例定义块,三是虚拟服务器定义块。而各配置段中还可以嵌套另外的配置段,而有些配置段又不是必须的。虚拟服务配置是专门针对LVS设计的,如果你所在的环境不是让LVS具有高可用性,那虚拟服务配置段就可以不要,如果你想让keepalived每一次状态的改变(MASTER-BACKUP间的转变)都以邮件的方式通知管理员,那可增加关于邮件报警相关的配置段,总之,keepalived.conf的配置十分灵活,下边对常用的配置进行说明。

VRRPD CONFIGURATION

VRRP synchronization group(s)

VRRP instance(s)

vrrp_instance inside_network { //定义vrrp示例及示例名称;

state MASTER //指定当前设备的vrrp状态;

interface eno16777736 //被vrrp协议绑定的网络接口,即通过哪个接口发送vrrp通告;

virtual_router_id 51 //虚拟路由器ID,用于确定vrrp组;

priority 100 //指定当前节点的优先级,1-254之间整数,数字越大越有可能称为MASTER;

advert_int 1 //发送vrrp通告的时间间隔;

authentication {

  auth_type PASS  //设置验证方式为简单密码验证;

  auth_pass Hudlnej7  //设置验证密码,不超过8个字符长度;

}

virtual_ipaddress {

172.16.72.101/32 brd 172.16.72.101 dev eno16777736 label eno16777736:0

//指定虚拟IP地址及其配置的位置;

}

nopreempt //设定当前节点为非抢占模式;

preempt_delay 300 //抢占开始前的延迟时间;

notify_master <STRING>|<QUOTED-STRING>

notify_backup <STRING>|<QUOTED-STRING>

notify_fault <STRING>|<QUOTED-STRING>

//设置发生状态改变时,所触发的脚本文件路径及相关参数;

}

从这个配置文件中也可看出keepalived不仅可以为LVS提供高可用,也可以给nginx做高可用,只是keepalived和LVS结合时自身带了健康检测的机制,这也是healthcheck子进程所在的意义,而对非LVS做高可用时则需要借助vrrp_script这个配置段和相应的脚本来实现。

四、单、多实例及LVS-nat/dr模型实现

4.1单实例

下载安装keepalived后,备份keepalived.conf,方便恢复初始配置

drct1配置

! Configuration File for keepalived

global_defs {

notification_email {

 root@localhost   ///收件人

}

notification_email_from keepalived@localhost ///发件人

smtp_server 127.0.0.1

smtp_connect_timeout 30 ///连接超时时间

router_id drct1

vrrp_mcast_group4 224.200.100.18 ///阻播地址,要是正确的D类地址

}

vrrp_instance VI_1 { ///实例1

state MASTER     ///主

interface eno16777736    ///网卡

virtual_router_id 81     ///id号码,0-255之间的都行

priority 100                  ///优先级

advert_int 1

authentication {

    auth_type PASS     ///验证方式

    auth_pass zrs66zrs     ///验证密码

}

virtual_ipaddress {

    172.16.1.99/32 brd  172.16.1.99 dev eno16777736 label eno16777736:0    ///虚拟ip地址

}

drct2配置

! Configuration File for keepalived

global_defs {

notification_email {

 root@localhost

}

notification_email_from keepalived@localhost

smtp_server 127.0.0.1

smtp_connect_timeout 30

router_id drct2

vrrp_mcast_group4 224.200.100.18

}

vrrp_instance VI_1 {

state BACKUP

interface eno16777736

virtual_router_id 81

priority 90

advert_int 1

authentication {

    auth_type PASS

    auth_pass zrs66zrs

}

virtual_ipaddress {

    172.16.1.99/32 brd  172.16.1.99 dev eno16777736 label eno16777736:0

}

}

配置完成后,保存退出,启动keepalived,查看状态,可看到drct1进入MASTER状态

当stopdrct1的时候,drct2会立即变成MASTER,当再次start drct1的时候,drct1又会变成MASTER状态,drct2变成BACKUP状态。

4.2多实例

为了更高效的利用资源,单实例显然是不合适的,所以下面我们配置多实例,就是在一个实例上面再配置一个vrrp_instance VI_2添加一个虚拟地址,实现负载分担,配置如下:

drct1

! Configuration File for keepalived

global_defs {

notification_email {

 root@localhost

}

notification_email_from keepalived@localhost

smtp_server 127.0.0.1

smtp_connect_timeout 30

router_id drct1

vrrp_mcast_group4 224.200.100.18

}

vrrp_instance VI_1 {

state MASTER

interface eno16777736

virtual_router_id 81

priority 100

advert_int 1

authentication {

    auth_type PASS

    auth_pass zrs66zrs

}

virtual_ipaddress {

    172.16.1.99/32 brd 172.16.1.99  dev eno16777736 label eno16777736:0

}

}

vrrp_instance VI_2 {

state BACKUP                   ///实例1为MASTER,所以这个修改为BACKUP,作为备用

interface eno16777736

virtual_router_id 80       ///组号最好更改为跟实例1不同的组号

priority 90         ///优先级修改为实例1较低的优先级

advert_int 1

authentication {

    auth_type PASS

    auth_pass zrs88zrs     ///这里的也需要换一个密码

}

virtual_ipaddress {

    172.16.1.88/32 brd  172.16.1.88 dev eno16777736 label eno16777736:1    ///修改ip地址,即虚拟一个新的ip地址,端口改为1

}

}

drct2

将该配置文件复制到另一台主机中,修改个别内容

~]# scp keepaliver.conf172.16.1.200:/etc/keepalived

!Configuration File for keepalived

global_defs {

notification_email {

 root@localhost

}

notification_email_from keepalived@localhost

smtp_server 127.0.0.1

smtp_connect_timeout 30

router_id drct1

vrrp_mcast_group4 224.200.100.18

}

vrrp_instance VI_1 {

state BACKUP

interface eno16777736

virtual_router_id 81

priority 90

advert_int 1

authentication {

    auth_type PASS

    auth_pass zrs66zrs

}

virtual_ipaddress {

    172.16.1.99/32 brd 172.16.1.99 dev  eno16777736 label eno16777736:0

}

}

vrrp_instance VI_2 {

state MASTER

interface eno16777736

virtual_router_id 80

priority 100

advert_int 1

authentication {

    auth_type PASS

    auth_pass zrs88zrs

}

virtual_ipaddress {

    172.16.1.88/32 brd 172.16.1.88 dev  eno16777736 label eno16777736:1

}

}

保存退出,启动keepalived并查看状态,可以看到drct的状态正常

dbbbeb472d8777ff82dbc43fdc2ce8eb.png

12ff104f069ff2a372521ae96c22d2c7.png

正常添加了ip地址

431c0aeb94d778b4865b1c71664e862e.png

24b8a8039bb75e3dc560a727e52b700f.png

当把其中一台的keepalived停止时,另一台将会加入两个ip地址

02c89e3648502d4620e59ace0d2cf3e5.png

4.3 利用keepalived实现lvs-dr

这里需要在两个drct的配置文件中添加后端RS相关配置,添加的内容如下

virtual_server 172.16.1.254 80 {

delay_loop 3

lb_algo rr

lb_kind DR

nat_mask 255.255.0.0

presistence_timeout 5

protocol TCP

sorry_server 127.0.0.1 80

real_server 172.16.1.3 80 {

    weight 1

    HTTP_GET {

        url {

          path /index.html

          status_code 200

        }

        connect_timeout 3

        nb_get_retry 3

        delay_before_retry 1

    }

}

real_server 172.16.1.4 80 {

    weight 2

    HTTP_GET {

        url {

          path /index.html

          status_code 200

        }

        connect_timeout 3

        nb_get_retry 3

        delay_before_retry 1

    }

}

}

保存并重启,后端两个RS配置详见上篇博客,RS的配置脚本中的VIP地址需要改变,如我的VIP

地址需要改成172.16.1.254

重启服务查看已经有了集群了

[root@zj02 keepalived]# killall keepalived

[root@zj02 keepalived]# systemctl restarthttpd

[root@zj02 keepalived]# systemctl startkeepalived

[root@zj02 keepalived]# ipvsadm -ln

IP Virtual Server version 1.2.1(size=4096)

Prot LocalAddress:Port Scheduler Flags

-> RemoteAddress:Port Forward Weight ActiveConn InActConn

TCP 172.16.1.254:80 rr

-> 172.16.1.3:80 Route 1 0 0

-> 172.16.1.4:80 Route 2 0 0

客户端查看

edfacfa80350b73519da0eb4749c90cd.png

5a94af781f35a476d837c61dc5d6ef28.png

此时利用keepalived高可用lvs调度器实现DR模型的负载均衡一个php应用,可以在后端RS上添加共享目录,存放如wordpress应用,也可以再打开一台虚拟机做nfs共享存储服务器,然后分别挂载到rs1和rs2上面,挂载方式详见上篇博客。

4.4 利用keepalived实现lvs-nat

构建规划

drct1

外网:172.16.1.9

内网:192.168.1.100

drct2

外网:172.16.1.2

内网:192.16.1.200

rs1

内网:192.168.1.3

rs2

内网:192.168.1.4

虚拟地址

172.16.1.188

drct1的配置

! Configuration File for keepalived

global_defs {

notification_email {

    root@localhost

}

notification_email_from keepalived@locahost

smtp_server 127.0.0.1

smtp_connect_timeout 30

router_id dir1

vrrp_mcast_group4 224.220.100.18

}

vrrp_instance VI_1 {

state MASTER

interface eno16777736

virtual_router_id 51

priority 100

advert_int 1

authentication {

    auth_type PASS

    auth_pass zrszrs11

}   

virtual_ipaddress {

172.16.1.188/16 dev eno16777736 label eno16777736:0

}

}

vrrp_instance VI_2 {

state MASTER

interface eno50332200

virtual_router_id 52

priority 100

advert_int 1

authentication {

    auth_type PASS

    auth_pass zrszrs11

}   

virtual_ipaddress {

192.168.1.188/16 dev eno50332200 label eno50332200:0

}

}

virtual_server 172.16.1.188 80 {

delay_loop 2

lb_algo rr

lb_kind NAT

nat_mask 255.255.0.0

presistence_timeout 5

protocol TCP

sorry_server 127.0.0.1 80

real_server 192.168.1.3 80 {

    weight 1

    HTTP_GET {

        url {

          path /index.html

          status_code 200

        }

        connect_timeout 3

        nb_get_retry 3

        delay_before_retry 1

    }

}

real_server 192.168.1.4 80 {

    weight 2

    HTTP_GET {

        url {

          path /index.html

          status_code 200

        }

        connect_timeout 3

        nb_get_retry 3

        delay_before_retry 1

    }

}

}

drct2的配置

! Configuration File for keepalived

global_defs {

notification_email {

    root@localhost

}

notification_email_from keepalived@locahost

smtp_server 127.0.0.1

smtp_connect_timeout 30

router_id dir2

vrrp_mcast_group4 224.220.100.18

vrrp_instance VI_1 {

state BACKUP

interface eno16777736

virtual_router_id 51

priority 90

advert_int 1

authentication {

    auth_type PASS

    auth_pass zrszrs11

}   

virtual_ipaddress {

172.16.1.188/16 dev eno16777736 label eno16777736:0

}

}

vrrp_instance VI_2 {

state BACKUP

interface eno50332200

advert_int 1

authentication {

    auth_type PASS

    auth_pass zrszrs11

}   

virtual_ipaddress {

}

}

virtual_server 172.16.1.188 80 {

nat_mask 255.255.0.0

presistence_timeout 5

protocol TCP

sorry_server 127.0.0.1 80

real_server 192.168.1.3 80 {

    weight 1

    HTTP_GET {

        url {

          path /index.html

          status_code 200

        } 

        connect_timeout 3

        nb_get_retry 3

        delay_before_retry 1

    }   

}   

real_server 192.168.1.4 80 {

    weight 2

    HTTP_GET {

        url {

          path /index.html

          status_code 200

        } 

        connect_timeout 3

        nb_get_retry 3

        delay_before_retry 1

    }   

}   

}

保存并退出,重启服务,查看生成集群:

[root@zj01 keepalived]# systemctl startkeepalived

[root@zj01 keepalived]# ipvsadm

IP Virtual Server version 1.2.1(size=4096)

Prot LocalAddress:Port Scheduler Flags

-> RemoteAddress:Port Forward Weight ActiveConn InActConn

TCP 172.16.1.188:http rr

-> 192.168.1.3:http Masq 1 0 0

-> 192.168.1.4:http Masq 2 0 0

同样可以给rs1和rs2挂载nfs共享存储器,来部署php应用。

五、总结

事实上在keepalived中,无非是调用外来自定义脚本来实现其状态转移的,所有的脚本都可以使用vrrp_scprit调用再从vrrp_script中使用track_stript进行追踪定义的检测模块就可以了。keepalived在与LVS结合时是最佳选择,因为keepalived还自带了对real server的健康检测机制,这正好弥补了LVS的不足,而要知道的是keepalived不仅仅适用与LVS结合实现高可用,在其他需要高可用的环境keepalived依然可用,但总结起来keepalived更适用与作为负载均衡调度器应用类的高可用方案,比如nginx作为反向代理时,haproxy等这样的应用,不过这将是后续的博客内容了!