温故而知新,每次学习都有不一样的收获,今天就来爬爬keepalived的坑。
成都创新互联于2013年成立,是专业互联网技术服务公司,拥有项目成都网站建设、网站设计网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元印台做网站,已为上家服务,为印台各地企业和个人服务,联系电话:028-86922220
摘抄自官网的介绍:
Keepalived is a routing software written in C.
The main goal of this project is to provide simple and robust facilities for loadbalancing and high-availability to Linux system and Linux based infrastructures.
项目地址:https://github.com/acassen/keepalived
Keepalived的作用是检测服务器状态,如果一台服务器宕机或者出现其他故障导致当前服务器不可用,keep alived就会检测到并将故障的服务器从系统中剔除,同时使用备用服务器替代该服务器的工作,当服务器工作正常后Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。
Keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP功能。因此,Keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx、Haproxy、MySQL等)的高可用解决方案软件。
Keepalived软件主要是通过VRRP协议实现高可用功能的。VRRP是Virtual Router RedundancyProtocol(虚拟路由器冗余协议)的缩写,VRRP出现的目的就是为了解决静态路由单点故障问题的,它能够保证当个别节点宕机时,整个网络可以不间断地运行。
所以,Keepalived 一方面具有配置管理LVS的功能,同时还具有对LVS下面节点进行健康检查的功能,另一方面也可实现系统网络服务的高可用功能。
管理LVS软件
基于VRRP实现高可用
健康检查,故障切换
通过官网的介绍我们可以看到Keepalived提供了两个重要的功能:loadbalancing和high-availability。最初是专门为LVS负载均衡软件设计,可以用来管理并监控LVS集群系统中各个服务节点的状态,后来的版本中又加入了可以实现高可用的VRRP功能。
因此,Keeaplived主要有两种应用场景,一个是通过配置keepalived结合ipvs做到负载均衡(LVS+Keepalived);另一个是通过自身健康检查、资源接管等功能做高可用(双机热备),实现故障转移,功能近似于Heartbeat。
目前全球监控的分布式MySQL集群,使用了Keeaplived来实现proxy的双机热备功能,所以下面只介绍在高可用场景下的相关知识。
1.VRRP协议
keepalived是以VRRP协议为实现基础的,VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议,可以认为是实现路由器高可用的协议。
对应到高可用的场景,实际上就是把路由器换成了服务器或者服务器上的应用:
通常情况下是将两台linux服务器组成一个热备组(master-backup),同一时间热备组内只有一台主服务器(master)提供服务,同时master会虚拟出一个共用IP地址(VIP),这个VIP只存在master上并对外提供服务。
如果keepalived检测到master宕机或服务故障,备服务器(backup)会自动接管VIP成为master,keepalived并将master从热备组移除,当master恢复后,会自动加入到热备组,默认再抢占成为master,起到故障转移功能。
2.核心组件
keepalived是模块化设计,不同模块负责不同的功能,主要有三个模块,分别是core、check和VRRP,其中:
此外还有:
3.分层工作
keepalived做负载均衡时工作在TCP/IP协议的3/4/5层,做高可用时工作在OSI七层协议模型的3/4/7层,基本上是一样的,叫法不同而已
分层 | 功能 | 相关协议 |
---|---|---|
应用层 | 网络服务和最终用户的一个接口 | TFTP,HTTP,SNMP,DNS,FTP,SMTP,TELNET |
表示层 | 数据的表示、安全、压缩 | 无协议 |
会话层 | 会话的建立、管理、中止 | 无协议 |
传输层 | 定义传输数据的协议端口号,以及流控和差错校验 | TCP,UDP |
网络层 | 进行逻辑地址寻址,实现不同网络之间的路径选择 | IP,ICMP,RIP,OSPF,BGP,IGMP |
数据链路层 | 建立逻辑连接、硬件地址寻址、差错校验等功能 | SLIP,CSLIP,PPP,ARP,RARP,MTU |
物理层 | 建立、连接、断开物理连接 | ISO2110,IEEE802,IEEE802.2 |
Layer3:工作在三层时,keepalived会定期向热备组中的服务器发送一个ICMP数据包,来判断某台服务器是否故障,如果没有响应则将这台服务器从热备组移除。
Layer4:工作在四层时,keepalived以TCP端口的状态判断服务器是否故障,比如检测MySQL的3306端口,如果无法访问则将这台服务器从热备组移除。
Layer7:工作在七层时,keepalived根据用户设定的策略判断服务器上的程序是否正常运行,比如使用HTTP请求的方式,如果返回错误的状态码则将这台服务器从热备组移除。
在Keepalived服务器群之间,只有作为主的服务器不断发送VRRP广播包,告诉备它还活着,此时备不会抢占主,只有当主不可用,既备接受不到主的VRRP广播包,这时候备就会启动相关的服务接管主的任务向外提供服务,以保证服务的正常使用。
4.工作状态
keepalived正常启动的时候,共启动3个进程:
一个是父进程,负责监控其子进程;一个是VRRP子进程,另外一个是checkers子进程;
两个子进程都被系统watchlog看管,Healthcheck子进程检查各自服务器的健康状况。
如果healthchecks进程检查到master上服务不可用了,就会通知本机上的VRRP子进程,让他删除通告,并且去掉虚拟IP,转换为BACKUP状态。
1.配置介绍
keepalived配置文件按层级和模块划分的,每层由"{ }"来界定。在主配置文件中可以通过include来涵盖多个子配置文件。
详细语法说明:官方文档
配置文件包括以下几个模块:
- [root@localhost ~]# cat /etc/keepalived/keepalived.conf
- ! 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_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的端口
- }
- }
- }
- }
2.使用keepalived对nginx进行高可用搭建
2.1 环境准备
主机ip | 角色 | 部署软件 |
---|---|---|
192.168.73.135 | master | keepalived、nginx |
192.168.73.136 | salve | keepalived、nginx |
192.168.73.100 | 虚ip |
2.2 nginx软件安装和配置
在192.168.73.136操作为例,135上把index改成135即可
- [root@localhost ~]# yum -y install nginx
- [root@localhost ~]# cd /usr/share/nginx/html/
- [root@localhost html]# mv index.html index.html.back
- [root@localhost html]# echo "I am 192.168.73.136" > index.html
- [root@localhost html]# systemctl start nginx
- [root@localhost html]# curl 192.168.73.136
- I am 192.168.73.136
2.3 Keepalived软件安装
- [root@localhost ~]# yum install keepalived -y
- [root@localhost ~]# rpm -ql keepalived
- /etc/keepalived
- /etc/keepalived/keepalived.conf # 主配置文件
- /etc/sysconfig/keepalived
- /usr/bin/genhash
- /usr/lib/systemd/system/keepalived.service
- /usr/libexec/keepalived
- /usr/sbin/keepalived
2.4 监听存活脚本
- [root@localhost ~]# vim /etc/keepalived/check_port.sh
- #!/bin/bash
- #keepalived 监控端口脚本
- #使用方法:
- #在keepalived的配置文件中
- #vrrp_script check_port {#创建一个vrrp_script脚本,检查配置
- # script "/etc/keepalived/check_port.sh 80" #配置监听的端口
- # interval 2 #检查脚本的频率,单位(秒)
- #}
- CHK_PORT=$1
- if [ -n "$CHK_PORT" ];then
- PORT_PROCESS=`ss -lnt|grep $CHK_PORT|wc -l`
- if [ $PORT_PROCESS -eq 0 ];then
- echo "Port $CHK_PORT Is Not Used,End."
- exit 1
- fi
- else
- echo "Check Port Cant Be Empty!"
- fi
- [root@localhost ~]# chmod +x /etc/keepalived/check_port.sh
2.5 最终配置文件
(1)Master配置
- [root@localhost ~]# vim /etc/keepalived/keepalived.conf
- ! Configuration File for keepalived
- global_defs {
- router_id 192.168.73.136
- }
- vrrp_script chk_nginx {
- script "/etc/keepalived/check_port.sh 80"
- interval 2
- weight -20
- }
- vrrp_instance VI_1 {
- state MASTER
- interface ens33
- virtual_router_id 251
- priority 100
- advert_int 1
- authentication {
- auth_type PASS
- auth_pass 11111111
- }
- track_script {
- chk_nginx
- }
- virtual_ipaddress {
- 192.168.73.100
- }
- }
(2)Slave配置
- ! Configuration File for keepalived
- global_defs {
- router_id 192.168.73.135
- }
- vrrp_script chk_nginx {
- script "/etc/keepalived/check_port.sh 80"
- interval 2
- weight -20
- }
- vrrp_instance VI_1 {
- state BACKUP
- interface ens33
- virtual_router_id 251
- priority 90
- advert_int 1
- authentication {
- auth_type PASS
- auth_pass 11111111
- }
- track_script {
- chk_nginx
- }
- virtual_ipaddress {
- 192.168.73.100
- }
- }
2.6 启动主从的Keepalived
- [root@localhost ~]]systemctl start keepalived && systemctl enable keepalive
2.7 查看VIP是否启动
- [root@localhost keepalived]# ip addr
- 1: lo:
mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 - link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
- inet 127.0.0.1/8 scope host lo
- valid_lft forever preferred_lft forever
- inet6 ::1/128 scope host
- valid_lft forever preferred_lft forever
- 2: ens33:
mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 - link/ether 00:0c:29:6f:74:0a brd ff:ff:ff:ff:ff:ff
- inet 192.168.73.136/24 brd 192.168.73.255 scope global noprefixroute ens33
- valid_lft forever preferred_lft forever
- inet 192.168.73.100/32 scope global ens33
- valid_lft forever preferred_lft forever
- inet6 fe80::af0e:a936:d997:18da/64 scope link noprefixroute
- valid_lft forever preferred_lft forever
2.8 测试
首先在浏览器中访问vip,可以看到我们访问的是BACKUP上的web地址
关掉master上的nginx,查看VIP是否漂移到备机。
- # 关闭主nginx
- [root@localhost ~]# systemctl stop nginx
- # 查看备上的IP信息,我们发现vip已经偏移到备机上了
- [root@localhost ~]# ip addr
- 1: lo:
mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 - link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
- inet 127.0.0.1/8 scope host lo
- valid_lft forever preferred_lft forever
- inet6 ::1/128 scope host
- valid_lft forever preferred_lft forever
- 2: ens33:
mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 - link/ether 00:0c:29:6f:74:0a brd ff:ff:ff:ff:ff:ff
- inet 192.168.73.136/24 brd 192.168.73.255 scope global noprefixroute ens33
- valid_lft forever preferred_lft forever
- inet6 fe80::af0e:a936:d997:18da/64 scope link noprefixroute
- valid_lft forever preferred_lft forever
在浏览器中访问vip,可以看到我们访问的是master上的web地址
1.脑裂介绍
在高可用系统中,如果两个节点的心跳线断开,本来两个节点为一个整体、动作协调的一个HA系统,现在由于两个之间的心跳线断开导致它们分裂成了两个单独的个体。由于双方互相失去了联系,都会以为对方出了故障。这时候这两个单独的个体就像"脑裂人"一样互相争抢共享资源、争用应用服务,这样就会造成严重问题:
共享资源被瓜分,两边服务都起不来;
两边服务都起来了,同时提供服务,同时读写存储,导致数据不一致甚至损坏。
1.1 产生脑裂的原因
一般来说,脑裂的发生,有以下几种原因:
(1)HA服务器之间心跳线故障,导致无法正常通信;
(2)HA服务器上开启了防火墙,阻挡了心跳线的信息传输;
(3)HA服务器上心跳网卡配置不正确,导致心跳信息发送失败;
(4)其他服务器配置不当的原因。比如心跳方式不同,心跳广播冲突,软件BUG等;
(5)Keepalived配置里同一 VRRP实例中如果 virtualrouterid两端参数配置不一致也会导致裂脑问题发生。
1.2 常见的解决办法
在实际环境中,我们可以从以下几个方面来防止脑裂的问题:
(1)同时使用串行线路或者以太网电缆连接,同时使用两条心跳线路,如果一条坏了,另外一条还能正常提供服务;
(2)当检测到脑裂时强行关闭一个节点(该功能需要特殊设备支持,如Stonith,feyce),相当于备节点接受不到心跳消息,通过单独的线路发送关机命令关闭主节点的电源;
(3)做好脑裂监控报警(用zabbix等来监控),在问题发生时能在第一时间介入仲裁,降低损失。
(4)启动磁盘锁。正在服务一方锁住共享磁盘,“裂脑”发生时,让对方完全“抢不走”共享磁盘资源。但使用锁磁盘也会有一个不小的问题,如果占用共享盘的一方不主动“解锁”,另一方就永远得不到共享磁盘。现实中假如服务节点突然死机或崩溃,就不可能执行解锁命令。后备节点也就接管不了共享资源和应用服务。于是有人在HA中设计了“智能”锁。即:正在服务的一方只在发现心跳线全部断开(察觉不到对端)时才启用磁盘锁,平时就不上锁了;
(5)加入仲裁机制。例如设置网关IP,当脑裂发生时,两个节点都各自ping以下这个网关IP,不通则表明断点就在本端,不仅“心跳”、还兼对外“服务”的本端网络链路断了,即使启动(或继续)应用服务也没有用了,那就主动放弃竞争,让能够ping通网关IP的一端去起服务。更保险一些,ping不通网关IP的一方干脆就自我重启,以彻底释放有可能还占用着的那些共享资源。
1.3 Keepalived监控nginx防止脑裂
(1)执行脚本,用来检测
- [root@zdd211-11 ~]# vim /etc/keepalived/check_keepalived.sh
- #!/bin/bash
- NGINX_SBIN="which nginx"
- NGINX_PORT=80
- function check_nginx(){
- NGINX_STATUS="nmap localhost -p ${NGINX_PORT} | grep "80/tcp open" | awk '{print $2}'"
- NGINX_PROCESS="ps -ef | grep nginx|grep -v grep|wc -l"
- }
- check_nginx
- if [ "$NGINX_STATUS" != "open" -o $NGINX_PROCESS -lt 2 ]
- then
- ${NGINX_SBIN} -s stop
- ${NGINX_SBIN}
- sleep 3
- check_nginx
- if [ "$NGINX_STATUS" != "open" -o $NGINX_PROCESS -lt 2 ];then
- systemctl stop keepalived
- fi
- fi
- [root@localhost ~]# chmod +x /etc/keepalived/check_port.sh
(2)安装nmap
因为上面脚本有用到这个工具,因此两个主机都需要安装
- [root@localhost ~]# yum install nmap -y
(3) 修改master配置
- [root@localhost ~]# vim /etc/keepalived/keepalived.conf
- ! Configuration File for keepalived
- global_defs {
- router_id 192.168.73.136
- }
- vrrp_script chk_nginx {
- script "/etc/keepalived/check_port.sh 80"
- interval 2
- weight -20
- }
- vrrp_script chk_nginx {
- script "/etc/keepalived/check_keepalive.sh" # 脚本路径
- interval 2 # 执行时间间隔
- weight -5 # 计算权重值,脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5
- fall 3 # 检测连续3次失败才算确定是真失败。会用weight减少优先级(1-255之间)
- rise 2 # 检测2次成功就算成功。但不修改优先级
- vrrp_instance VI_1 {
- state MASTER
- interface ens33
- virtual_router_id 251
- priority 100
- advert_int 1
- authentication {
- auth_type PASS
- auth_pass 11111111
- }
- track_script {
- chk_nginx
- }
- virtual_ipaddress {
- 192.168.73.100
- }
- }
(4) 修改Slave配置配置
- ! Configuration File for keepalived
- global_defs {
- router_id 192.168.73.135
- }
- vrrp_script chk_nginx {
- script "/etc/keepalived/check_keepalive.sh"
- interval 2 # 执行时间间隔
- weight -5 # 计算权重值,脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5
- fall 3 # 检测连续3次失败才算确定是真失败。会用weight减少优先级(1-255之间)
- rise 2 # 检测2次成功就算成功。但不修改优先级
- vrrp_instance VI_1 {
- state BACKUP
- interface ens33
- virtual_router_id 251
- priority 90
- advert_int 1
- authentication {
- auth_type PASS
- auth_pass 11111111
- }
- track_script {
- chk_nginx
- }
- virtual_ipaddress {
- 192.168.73.100
- }
- }
2.Keepalived设置故障恢复后不重新抢回VIP
通常生产环境是不允许VIP来回漂移,当主机的业务出问题之后,vip漂移到备机上保证业务不中断,就算故障恢复keepalived也不会把vip切到主机上;需要进行对应的问题问题,确认主机环境没有问题之后手动重启主机上keepalived服务,让vip切回到主机上。
为了满足这样的业务场景,可以使用nopreempt参数,不抢占VIP的机制实现
修改master配置如下:
- [root@localhost ~]# vim /etc/keepalived/keepalived.conf
- ! Configuration File for keepalived
- global_defs {
- router_id 192.168.73.136
- }
- vrrp_script chk_nginx {
- script "/etc/keepalived/check_keepalive.sh" # 脚本路径
- interval 2 # 执行时间间隔
- weight -5 # 计算权重值,脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5
- fall 3 # 检测连续3次失败才算确定是真失败。会用weight减少优先级(1-255之间)
- rise 2 # 检测2次成功就算成功。但不修改优先级
- }
- vrrp_instance VI_1 {
- state MASTER
- interface ens33
- virtual_router_id 251
- priority 100
- advert_int 1
- nopreempt ##不抢VIP 机制
- authentication {
- auth_type PASS
- auth_pass 11111111
- }
- track_script {
- chk_nginx
- }
- virtual_ipaddress {
- 192.168.73.100
- }
- }
可以自己重启keepalived,然后停止web,然后再启动web,验证是否能够自动漂移回主机
3.组播地址冲突问题
当在同一个局域网内部署了多组keepalived服务器时,可能会发生高可用接管的严重故障问题。
因为keepalived高可用功能是通过VRRP协议实现的,VRRP协议默认通过IP多播的形式实现高可用对之间的通信,如果同一个局域网内存在多组Keepalived服务器对,就会造成IP多播地址冲突问题,导致接管错乱.
不同组的keepalived都会使用默认的224.0.0.18作为多播地址。此时的解决办法是,在同组的keepalived服务器所有的配置文件里指定独一无二的多播地址,配置如下:
- global_defs
- {
- ``router_id LVS_19
- ``vrrp_mcast_group4 224.0.0.19` `#指定多播地址
- }
分享文章:Keepalived的原理和Web服务高可用实践
网页路径:http://www.gawzjz.com/qtweb2/news29/13029.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联