0
点赞
收藏
分享

微信扫一扫

高可用中间件之Keepalived的原理介绍与部署实践

(文章目录)

前言

Keepalived是一个用c语言编写的路由软件。这个实验的主要目标是为Linux系统和基于Linux的基础设施提供简单而健壮的负载平衡和高可用性工具。

keepalive实现了一组检查器,可以根据服务器的运行状况动态地、自适应地维护和管理负载平衡的服务器池。另一方面,通过VRRP协议实现高可用性

VRRP协议(选举协议)

​ ——虚拟路由器冗余协议

两种角色:master、backup

  • master承担实际的数据流量转发任务
  • backup路由器监听Master路由器状态,并在其发生故障时顶替

而选举master的方法就是——VRRP协议

工作在网络层

安装了keepalived软件就可以运行vrrp协议,就可以选举出master

vrrp工作原理

选举的过程:

  1. 所有的路由器或者服务器发送vrrp宣告报文,进行选举,必须是相同vrid和认证密码的,优先级高的服务器或者路由器会被选举为master,其他的机器都是backup
  2. master定时(Advertisement Interval)发送VRRP通告报文,以便向Backup路由器告 知自己的存活情况。 默认是间隔1秒
  3. 接收Master设备发送的VRRP通告报文,判断Master设备的状态是否正常。 如果超过1秒没有收到vrrp报文,就认为master挂了,开始重新选举新的master,vip会漂移到新的master上

vip(虚拟ip)

真正对外提供服务的IP地址,用户真正访问的ip,谁是master谁的ip就是vip

vrrp通告

所有开启了vrrp服务的服务器向外通信时的目的ip都使用224.0.0.18这个ip地址,这是个组播地址,只有使用vrrp的服务器可以识别该信息,而不使用vrrp协议的服务器不会理会这个信息

vrrp头部格式

vrrp头部格式

Keepalived工作原理

三个进程

启动keepalived后会出现三个进程

[root@lb1 keepalived]# ps aux|grep keep
root 10815 0.0 0.0 118712 1380 ? Ss 16:59 0:00 /usr/sbin/keepalived -D
root 10816 0.0 0.0 122912 2420 ? S 16:59 0:00 /usr/sbin/keepalived -D
root 10817 0.0 0.0 122912 2428 ? S 16:59 0:00 /usr/sbin/keepalived -D
root 10827 0.0 0.0 112828 988 pts/0 S+ 17:00 0:00 grep --color=auto keep

一个是父进程,负责内存管理和监控其子进程,一个是vrrp子进程,另外一个是healthcheckers子进程 两个子进程都被系统watchdog看管,两个子进程各自负责复杂自己的事。

healthcheck子进程检查各自服务器的健康状况,例如http、lvs。如果master上的healthcheck进程检查到服务不可用了,就会通知本机上的VRRP子进程,让他删除通告,并且去掉vip,转换为BACKUP状态

Keepalived组件

keepalived是模块化设计,不同模块负责不同的功能。

  • core:keepalived的核心,负责主进程的启动和维护,全局配置文件的加载解析等;
  • check:负责healthchecker(健康检查),包括了各种健康检查方式,以及对应的配置文件的解析;
  • Vrrp:VRRPD子进程,用来实现VRRP协议;
  • libipfwc:iptables(ipchains)库,配置LVS;
  • libipvs:配置LVS:

ip漂移

当master挂掉时,vip会自动转移到某个backup上(通过比较优先级)

但每当有机器加入到VRRP实例时(包括挂掉的机器恢复),都会重新选举,优先级最高的机器当选master

配置文件中的vrrp_strict参数

keepalived的配置文件中的vrrp_strict参数用于控制是否启用严格模式的VRRP协议。

默认情况下该参数的值为off。这意味着在VRRP协议中,备用节点可以在没有收到来自主节点的VRRP广告时成为主节点。

如果将vrrp_strict设置为on,则备用节点必须在规定的时间内接收到来自主节点的VRRP广告才能成为主节点

在off情况下可能导致网络故障和数据丢失,或许是因为转换比较突然吧。因此,建议将vrrp_strict设置为on以确保VRRP协议的可靠性。

vrrp_strict参数后面可以添加以下参数:

  1. on – 表示启用vrrp_strict模式。
  2. off – 表示禁用vrrp_strict模式。
  3. backup – 表示只有备用节点才能成为主节点。
  4. master – 表示只有主节点才能成为主节点。
  5. equal – 表示备用节点和主节点都可以成为主节点。
  6. lower-priority – 表示优先级低的节点不能成为主节点。

什么是脑裂

多台机器出现同一个vip

为什么会出现脑裂?

​ 1.vrid(虚拟路由id)不一样 ​ 2.网络通信有问题:如防火墙阻止了网络之间的选举的过程,vrrp报文的通信 ​ 3.认证密码不一样也会出现脑裂

脑裂有没有危害?如果有危害对业务有什么影响?

  • 没有危害,能正常访问,反而有点负载均衡的作用,主要看路由器发出arp广播时谁先响应,先响应的服务器的mac地址存入arp缓存表,但过几分钟左右缓存过期后路由器又会重发所以有一定的的随机性。

  • 脑裂恢复的时候,还是有影响的,会有短暂的中断,多少影响一点业务的

Keepalived架构

​ 单vip 架构: 只有master上有vip,backup上没有vip,这个时候master会比较忙,backup机器会比较闲,设备使用率比较低 ​ 双vip 架构: 启动2个vrrp实例,每台机器上都启用2个vrrp实例,一个做master,一个做backup,启用2个vip,每台机器上都会有一个vip,这2个vip都对外提供服务,这样就可以避免单vip的情况下,一个很忙一个很闲。 可以提升设备的使用率

搭建步骤

现在我会在两台服务器上(LB1、LB2)依次搭建单vip架构和双vip架构

单vip

安装

在lb服务器上安装keepalived软件

yum install keepalived -y

配置

修改/etc/keepalived/keepalived.conf文件

保留如下部分即可:

[root@lb1 keepalived]# vim keepalived.conf 
! Configuration File for keepalived

global_defs {
……全部保留……
}

vrrp_instance VI_1 { # 定义一个vrrp协议的实例,名字叫VI_1
state MASTER # 做master
interface eth0 # 指定监听网络的接口,其实就是vip绑定到那个网络接口上
virtual_router_id 51 # 虚拟路由器id --》相当于帮派,51是帮派的编号,位于0~255之间
priority 100 # 优先级,0~255,越高越容易当选
advert_int 1 # 宣告的时间间隔,1s --interval 间隔
authentication { # 认证
auth_type PASS # 采用密码认证
auth_pass 1111 # 具体密码
}
virtual_ipaddress { # vip,虚拟ip,
192.168.200.16
192.168.200.17
192.168.200.18
}

}

以上是默认文件,下面是我的配置:

LB1:

global_defs {
……
#vrrp_strict # 注释这一行
……
}
vrrp_instance VI_1 {
state MASTER # 更想让LB1当master
interface ens33 # 网卡为ens33
virtual_router_id 51 # id默认51就行
priority 120 # 优先级调高一点,更容易当选
advert_int 1 # 默认1s,不改
authentication { # 默认就行
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { # vip保留一个就行,先确保这个ip没机器在用
192.168.10.188
}
}

LB2:

global_defs {
……
#vrrp_strict # 注释这一行
……
}
vrrp_instance VI_1 {
state BACKUP # 希望LB2当backup
interface ens33
virtual_router_id 51 # 和LB1保持一致
priority 100 # 优先级比LB1低一点,更容易当backup
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { # 同样只保留一个,与LB1一致
192.168.10.188
}
}

启动服务查看进程和ip

[root@lb1 keepalived]# service keepalived start
Redirecting to /bin/systemctl start keepalived.service
[root@lb1 keepalived]# ps aux|grep keep
root 10815 0.0 0.0 118712 1380 ? Ss 16:59 0:00 /usr/sbin/keepalived -D
root 10816 0.0 0.0 122912 2420 ? S 16:59 0:00 /usr/sbin/keepalived -D
root 10817 0.0 0.0 122912 2428 ? S 16:59 0:00 /usr/sbin/keepalived -D
root 10827 0.0 0.0 112828 988 pts/0 S+ 17:00 0:00 grep --color=auto keep

分别查看LB1和LB2的ip

[root@lb1 keepalived]# ip ad
……
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:f1:73:a1 brd ff:ff:ff:ff:ff:ff
inet 192.168.10.129/24 brd 192.168.10.255 scope global noprefixroute dynamic ens33
valid_lft 1643sec preferred_lft 1643sec
inet 192.168.10.188/32 scope global ens33 # LB1多了一个vip,说明以当选为master
valid_lft forever preferred_lft forever
[root@lb2 conf]# ip ad # LB2还是原来的ip,所以为backup
……
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:6b:8d:65 brd ff:ff:ff:ff:ff:ff
inet 192.168.10.143/24 brd 192.168.10.255 scope global noprefixroute dynamic ens33
valid_lft 1217sec preferred_lft 1217sec

双vip

在配置文件中添加一个实例

[root@lb1 keepalived]# vim keepalived.conf 
vrrp_instance VI_2 { # 添加实例2
state BACKUP # LB1在实例2中作为backup
interface ens33
virtual_router_id 52 # 虚拟路由器id需与上一个实例不一致
priority 100 # 优先级调低
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.199 # vip也需与上一个实例不一致
}
}

[root@lb2 keepalived]# vim keepalived.conf
vrrp_instance VI_2 { # LB2同样添加实例2
state MASTER # LB2在实例2中作为master
interface ens33
virtual_router_id 52 # 与LB1保持一致
priority 120 # 优先级比LB1高
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.199 # 与LB1保持一致
}
}

此时重启服务后LB1增加实例1中的vip,LB2增加实例2中的vip,并互为主备。

健康检测-监控脚本

例:监控nginx进程是否正常运行,没运行的话优先级减30

如何知道nginx正在运行?

  1. pidof nginx ——返回nginx的pid号,通过$?判断是否正常运行
  2. killall -0 nginx —— -0表示检查进程是否运行,正常运行$?为0,否则为1
  3. netstat -anplut |grep nginx ——正常运行$?为0,否则为1
  4. ss -anplut|grep nginx ——正常运行$?为0,否则为1
  5. lsof -i:80 ——不推荐,查看目的端口或者源端口为80的进程,所以不一定是nginx

编写监控脚本

[root@lb1 nginx_sh]# vim check_nginx.sh
#!/bin/bash

if /usr/sbin/pidof nginx &>/dev/null ;then
exit 0
else
exit 1
fi

定义并使用脚本

[root@lb1 keepalived]# vim keepalived.conf 
……
# 定义监控脚本
vrrp_script chk_nginx { # 脚本名自定义,“{”前面必须有空格
script /mybin/nginx_sh/check_nginx.sh # 存放监控脚本路径,当脚本执行返回值为1时优先级才-30
interval 1 # 执行脚本间隔
weight -30 # 优先级-30,这样LB1的优先级会低于LB2,成为backup
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 120
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.188
}
#调用监控脚本
track_script { # 在实例内调用脚本,“{”前面必须有空格
chk_nginx # 使用前面定义的脚本名
}
}

notify

当转换到某种状态时执行某些命令

notify_backup——当前节点成为backup时

notify_master——当前节点成为master时

notify_stop——当前节点服务停止时

notify_fault——当前节点出现故障

[root@lb1 keepalived]# vim keepalived.conf 
……
#调用监控脚本
track_script {
chk_nginx
}
notify_backup service keepalived stop # 加这一条命令即可,也可以写脚本的绝对路径,echo内容是看不到的
notify_master /usr/local/hht99/sbin/nginx # 成为master时启动nginx,这样nginx都不需要设置开机自启了
}
举报

相关推荐

0 条评论