keepalived+haproxy 实现HA+LB

前言

https://wangtingwei.info/?p=1300这篇文章中,我主要介绍了keepalived的组件,架构原理以及keepalived配合其他负载均衡软件的使用场景。本节将会介绍其中的一种HA+LB的方案keepalived+haproxy 。haproxy和nginx一样都是七层负载均衡软件。但是相对于nginx,他的负载均衡算法很多,功能更全一些,比如支持基于cookie引导,session保持以及url的健康检查,不过这几年nginx版本不断更新,功能逐渐完善·社区比较活跃,实力不容小觑。

机器规划

192.168.137.41 node-1-test       keepalive+haproxy      (backup)   : 优先级高
192.168.137.42 node-2-test      keepalived+haproxy (backup) :优先级低
192.168.137.43 node-3-test       后端web-1  (httpd)
192.168.137.44 node-4-test       后端web-2  (httpd)

vip1:192.168.137.110

vip2:192.168.137.120

部署

我们整体的部署流程是从内到外,在生产环境中很多架构部署都是按照这个流程走,因为我们部署的服务都是分层的,有内而外扩展,这里我的流程如下:

  • 部署web服务器
  • 部署haproxy+keepalived

1.部署web服务器

为了测试方便,我这里直接yum安装httpd(43 44机器同时操作)

yum install httpd -y 

service httpd start 

chkconfig httpd on

2.编写web测试页面

为了方便测试,页面内容被主机ip标记

echo “web-1 主机:192.168.137.43” >>/var/www/html/index.html

echo “web-2 主机:192.168.137.44” >>/var/www/html/index.html

查看页面:

3.安装配置haproxy

  • 可以yum 或者编译安装,为了快速演示这里直接用yum安装

yum install haproxy -y

  • 配置文件在/etc/haproxy/haproxy.cfg

HAproxy配置文件主要由5个部分组成:

1、global部分:用来设定全局配置参数,属于进程级,通常和操作系统配置有关

2、defaults部分:默认参数配置部分。在此部分下,默认会自动引用到下面的frontend、backend和listen部分中,因此如果某些参数属于公用的配置,只需在defaults部分添加一次即可。

3、frontend部分:用于设置接收用户请求的前端虚拟节点。frontend是在HAProxy1.3版本之后才引入的一个组件,同时引入的还有backend组件。frontend可以根据ACL规则直接指定要使用的后端backend

4、backend部分:此部分用于设置集群后端服务器集群的配置,也就是用来添加一组真实服务器,以处理前端用户的请求,添加的真实服务器类似于LVS中的real server节点。

5、listen部分:此部分是frontend和backend部分的结合体。在HAProxy1.3版本之前,HAProxy的所有配置选项都在这个部分中设置。

完整配置文件如下:

root@node-1-test ~]# cat /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local0 #日志输出位置,所有日志都记录在本机,通过local0输出
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000 #限制单个进程的最大连接数
user haproxy
group haproxy
daemon #后台运行
stats socket /var/lib/haproxy/stats

defaults #公共模块配置
mode http #tcp http health 三种模式
log global
option httplog
option dontlognull
option http-server-close
option dontlognull #不记录空连接
option forwardfor #如果后端服务器需要获得客户端真实ip需要配置的参数,可以从Http Header中获得客户端ip
option httpclose #每次请求完毕后主动关闭http通道,haproxy不支持keep-alive,只能模拟这种模式的实现
option abortonclose #当服务器负载很高的时候,自动结束掉当前队列处理比较久的连接
option redispatch #在连接失败或断开的情况下,允许当前会话被重新分发
retries 3 #设置在一个服务器上链接失败后的重连次数
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
listen stats #设置haproxy 检测页面
mode http
bind 0.0.0.0:8080 #指定IP地址与Port
stats enable #开启Haproxy统计状态
stats refresh 3s #统计页面自动刷新时间间隔
stats hide-version #状态页面不显示版本号
stats uri /wangtingwei #统计页面的uri为”/wangtingwei”
stats realm Haproxy\wang #统计页面认证时提示内容信息
stats auth admin:admin #统计页面的用户名与密码
stats admin if TRUE #启用或禁用状态页面

frontend frontend_wangtingwei
bind *:80
mode http
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
default_backend backend_wangtingwei
use_backend backend_wangtingwei if url_static

backend backend_wangtingwei
balance roundrobin
server web-1 192.168.137.43:80 check rise 2 fall 1 weight 2
server web-2 192.168.137.44:80 check rise 2 fall 1 weight 2

#backend app
#balance roundrobin
#server app1 127.0.0.1:5001 check
#server app2 127.0.0.1:5002 check
#server app3 127.0.0.1:5003 check
#server app4 127.0.0.1:5004 check

备注:

frontend是一个字段代表前端,此字段用来配置转发规则acl,典型的场景就是动静分离。这里我只有httpd所以只是用了默认的配置。自定义一个前端规则组名为frontend_wangtingwei

acl   参数是用来定义规则的 url_static 可以自定义 后面规则可以自定义。这里我用的默认的

default_backend 定义默认后端服务器组。这里我定义了名为backend_wangtingwei。

use_backend 参数  配合if  xxx规则名(这里是url_static)实现了如果规则匹配那么将会把请求转给那个服务器组。这里我写的还是backend_wangtingwei

  • node-2-test配置相同并启动haproxy

4.安装配置keepalived

说明:

1.这里依然用yum安装

2.为了不浪费机器资源。我们采用互为主备的方式,每个keepalived定义两个实例,node-1和node-2会各有一个vip共两个。

3.切记互为主备就不要用非抢占模式了。否则即使故障机器恢复了两个vip也只会在一台机器,请求都落在一台keepalived主机。而不用非抢占模式,则是两个vip ,一人一个。一旦故障这个vip就会漂移到另一台,使得另一台同时接管两个vip。故障机器恢复后,ip各自一个。

  • 安装

yum install keepalived

  • keepalived配置文件

node-1-test配置文件:

[root@node-1-test keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from admin@allen.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_wangtingwei
}
vrrp_script check_haproxy {
script “/etc/keepalived/check_ha.sh”
interval 2
weight -2
}
vrrp_instance ha_1 {
state MASTER
interface ens33
virtual_router_id 56
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1056
}
virtual_ipaddress {
192.168.137.110
}
track_script {
check_haproxy
}
}
vrrp_instance ha_2 {
state BACKUP
interface ens33
virtual_router_id 58
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1058
}
virtual_ipaddress {
192.168.137.120
}
}


node-2-test配置文件

[root@node-2-test keepalived]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from admin@allen.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_wangtingwei
}
vrrp_script check_haproxy {
script “/etc/keepalived/check_ha.sh”
interval 2
weight -2
}
vrrp_instance ha_1 {
state BACKUP
interface ens33
virtual_router_id 56
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1056
}
virtual_ipaddress {
192.168.137.110
}
track_script {
check_haproxy
}
}
vrrp_instance ha_2 {
state MASTER
interface ens33
virtual_router_id 58
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1058
}
virtual_ipaddress {
192.168.137.120
}
}


check_ha.sh脚本如下:

#!/bin/bash
#作者:王庭威
#描述:检测haproxy进程
ha_process=`ps -ef |grep haproxy |grep -v grep|wc -l`
if [ $ha_process -eq 0 ];
then service haproxy restart
echo “时间是:$date ,尝试重启haproxy” >>/etc/keepalived/restart.log
sleep 3
if [ $ha_process -eq 0 ];
then service keepalived stop
echo “时间是:$date,尝试重启haproxy失败,关闭本机keepalived,开始故障转移” >>/etc/keepalived/failover.log
fi
fi

备注:脚本主要功能是检测haproxy进程是否存在,如果不存在尝试重新拉起服务,休眠3s后继续检测进程,如果进程不存在证明拉起服务失败,开始停掉keepalived  强制failover 。并且两个过程都记录日志。


  • 赋予脚本执行权限并手动检测脚本是否可以执行

chmod a+x check_ha.sh  

sh -x check_ha.sh     -x 开启调试模式

  • 分别启动两台keepalived服务

service keepalived start

chkconfig keepalived on

开始测试

  • node-1此时绑定一个vip 192.168.137.110

  • node-2此时绑定一个vip 192.168.137.200

  • 访问 vip 192.168.137.110 可以实现负载

  • 访问vip 192.168.137.120 可以实现负载

  • 只停掉haproxy,测试是否可以拉起并记录日志

  • 停掉keepalived服务,查看效果

  • node-1-test 的 vip 开始漂移 。node-2-test节点vip有两个vip

再次访问服务。依然正常。只不过请求都发给backup负载均衡主机。

  • 故障机器恢复,查看效果

node-test-1 的vip 重新接管。此时请求会分担给两个负载均衡主机,然后转发到后端机器。

  • 访问管理界面

http://192.168.137.110:8080/wangtingwei

账号:admin

密码:admin

问题

1.最初检测haproxy脚本名为check_haproxy.sh ,脚本中定义检测进程 ps -ef |grep haproxy    脚本中haproxy 和脚本名中的名称重复。导致进程检测不准确,本来haproxy进程不存在,可是执行脚本显示进程数为2.   这个多亏了sh -x 调试模式排查的。于是改了脚本名为check_ha.sh 后执行正常。

2.keepalived 主备模式下 ,又配置了非抢占模式。理解原理后。修改为抢占模式。

 

 

 

 

 

 

 

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Loading...