对于负载均衡器来说,常用的有硬件解决方案,如CitrixNetscaler,F5Bigip,还有软件级别的解决方案,如对于大型网站来说的LVS,对于流量不是很大的网站来说,HAproxy还有Nginx,而HAproxy+Keepalived可以达到亿pv/日,而且还非常稳定,所以对于中小企业来说是个不错的选择。
Keepalived是常见的高可用解决方案之一,原创的目的是为了LVSDirectorServer的高可用,当然也可也用于其他服务的高可用,如nginx,HAProxy等服务,Keepaliaved使用VRRP协议,使得虚拟IP和虚拟MAC在可个物理节点间流动。同样通过脚本可以使得其他资源在各节点上流动。
Keepalived主要有两个进程,一个为VRRP负责资源的迁移,另外一个为Checkers.负责健康状态的检查,还有一个watchDog的进程,负责监控VRRP和Checkers是否存活。
我们来实现一下HAProxy与双主keepalived结合
ROLE | IP | HostName |
虚拟ip | 172.16.11.15 172.16.11.16 | |
HAProxy节点1 | 172.16.11.12eth0 | ha1.sysbo.net |
HAProxy节点2 | 172.16.11.13eth0 | ha2.sysbo.net |
后端nginx节点1(静态) | 172.16.11.21 | rs1.sysbo.net |
后端nginx节点2(动态) | 172.16.11.22 | rs2.sysbo.net |
后端nginx节点3(动态) | 172.16.11.23 | rs3.sysbo.net |
下面是拓扑图
先来解释下,为什么要双主keepalived,怎样实现双主keepalived
对于这个架构来说,keepalived的虚拟IP就是暴露在最外边给客户端访问的,所以使用在DNS添加上两个A记录,可以用负载均衡的作用,两台keepalived主机互为主备,即添加了可用性又有负载均衡的作用,而实现的过程仅仅是添加两个实例就可以了。
在来看下下面所定义的代码中,keepalived的工作流程,有图有真相
在每个节点/etc/hosts文件中添加如下行
172.16.11.12 ha1 ha1.sysbo.net172.16.11.13 ha2 ha2.sysbo.net192.168.0.1 rs1 rs1.sysbo.net192.168.0.2 rs2 rs2.sysbo.net192.168.0.3 rs3 rs3.sysbo.net
在ha1和ha2中开启端口转发
[root@ha1 ~]# vim /etc/sysctl.confnet.ipv4.ip_forward = 1[root@ha1 ~]# sysctl –p
在ha1和ha2中安装keepavlived
[root@ha1 ~]# yum install keepalived –y[root@ha1 ~]# vim /etc/keepalived/keepalived.conf! Configuration File for keepalivedglobal_defs {notification_email {sysadmin@sysbo.net //定义收件人,别忘了加上你主管的名字哦}notification_email_from ha@sysbo.net //定义发件人邮箱smtp_server 127.0.0.1smtp_connect_timeout 30router_id LVS_DEVEL}vrrp_script chk_haproxy{ //检查haproxy是否存活的脚本script "killall -0 haproxy" //killall -0 是代价最低的interval 1 //检查频率weight -2 //检查失败,权重-2}vrrp_instance VI_1 { //定义第一个实例state MASTER //这个主机在这个实例中为主节点interface eth0 //通知端口virtual_router_id 59 //每个实例有不同的vitrual_route id,这个是虚拟MAC地址的最后一位priority 100 //优先级 100,优先级大的就会被选为MASTERadvert_int 1 //通告时间authentication { //验证选项auth_type PASS //使用与共享秘钥验证auth_pass 1111 //与共享秘钥}virtual_ipaddress { //定义虚拟ip172.16.11.15/16 dev eth0 label eth0:0 //漂移的虚拟ip地址将会在eth0:0 上}track_script { //定义在这个实例中使用的脚本chk_haproxy}modify_master "/etc/keepalived/notify.sh master" //如果检测到此节点变为了master/etc/keepalived/notify.sh ,并且给一个master参数modify_backup "/etc/keepalived/notify.sh backup"modify_fault "/etc/keepalived/notify.sh fault"}vrrp_instance VI_2 {state BACKUP //注意,在实例2中,此节点为BACKUPinterface eth0virtual_router_id 60 //与上面不同哦,不同的虚拟ip对应不同的MAC地址priority 99advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.16.11.16/16 dev eth0 label eth0:0}track_script {chk_haproxy}modify_master "/etc/keepalived/notify2.sh master"modify_backup "/etc/keepalived/notify2.sh backup"modify_fault "/etc/keepalived/notify2.sh fault"}
定义故障通知脚本/etc/keepalived/notify.sh
#!/bin/bashvip=172.16.11.15 //notify.sh对应vrrp_INSTANCE V1_1,对应v1_2再复制一份与此相同的脚本,VIP=172.16.11.16 即可contact='root@localhost'notify() {mailsubject="`hostname` to be $1: $vip floating"mailbody="`date '+%F %H:%M:%S'`: vrrp transition, `hostname` changed to be $1"echo $mailbody | mail -s "$mailsubject" $contact}case "$1" inmaster)notify master/etc/rc.d/init.d/haproxy startexit 0;;backup)notify backup/etc/rc.d/init.d/haproxy restart //如果服务宕掉,他会重启exit 0;;fault)notify faultexit 0;;*)echo 'Usage: `basename $0` {master|backup|fault}'exit 1;;esac
复制上面内容至ha2
[root@ha1 keepalived]# scp keepalived.conf ha2:/etc/keepalived/[root@ha1 keepalived]# scp notify.sh ha2:/etc/keepalived/[root@ha1 keepalived]# scp notify2.sh ha2:/etc/keepalived/
修改ha2中的内容
vrrp_instance VI_1state BACKUP //此节点实例1为BACKUPpriority 99 //相应优先级为99vrrp_instance VI_2state MASTER //此节点实例2为MASTERpriority 100 //相应优先级为100
至此双主keepalived部署完成
我们接着部署HAproxy
两个节点都安装haproxy
[root@ha1 ~]# yum install haproxy –yhaproxy的配置文件一般分为全局配置(global),代理配置(defaults, frontend, backend, listen)[root@ha1 ~]# vim /etc/haproxy/haproxy.cfggloballog 127.0.0.1 local2 //log日志信息发往127.0.0.1 facility 为local2chroot /var/lib/haproxy //是否使用chrootpidfile /var/run/haproxy.pid //pid 文件存放位置maxconn 4000 //每个haproxy 进程可以接受最大的并发连接数,等于命令选项 “-n” “ulimit –n”自动计算的结果会参照此值得设定user haproxygroup haproxydaemon //独立守护进程# turn on stats unix socketstats socket /var/lib/haproxy/statsdefaults //默认选项,如果没有做特殊说明就按着这个选项执行mode http //默认工作在7层httplog global //使用全局日志option httplogoption dontlognulloption http-server-closeoption forwardfor except 127.0.0.0/8option redispatchretries 3timeout http-request 10stimeout queue 1mtimeout connect 10stimeout client 1mtimeout server 1mtimeout http-keep-alive 10stimeout check 10smaxconn 30000listen stats //使用状态通告mode httpbind 0.0.0.0:1080stats enablestats hide-versionstats uri /haproxyadmin?stats //uri地址stats realm Haproxy\ Statisticsstats auth admin:admin //账号和密码stats admin if TRUEfrontend http-in //前端选项bind *:80 //默认绑定80端口mode httplog globaloption httpclose //支持长连接,服务器端关闭option logasapoption dontlognullcapture request header Host len 20 //抓取请求报文的前20字节capture request header Referer len 60acl url_static path_beg -i /static /p_w_picpaths /javascript /stylesheet//定义acl规则,如果请求uri开始 为/static /p_w_picpaths /javascript /stylesheet 就符合此此规则,此规则不区分大小写,此规则的名字叫 url_staticacl url_static path_end -i .jpg .jpeg .gif .png .css .js//定义acl规则,如果请求uri的结束符为.jpg jpeg gif .png css .js将符合此规则,此规则不区分大小写,此规则名字也叫 url_staticuse_backend static_servers if url_static//如果请求内容符合acl url_static 则将内容发往static_serverdefault_backend dynamic_servers//其他发往dynmic_servers,这样就实现了动静分离backend static_servers //定义静态服务器组balance roundrobin //是用roundrobin 轮训算法server rs1 172.16.11.21:80 check maxconn 6000//imgsrv1 是这个后端静态服务器的名字,对应的IP为192.168.0.1,使用80端口,最大连接数为6000backend dynamic_servers //定义动态服务器balance sourceserver rs2 172.16.11.22:80 check maxconn 1000server rs3 192.16.11.23:80 check maxconn 1000
在生产环境中动态服务器应该部署一样的东西,静态服务器应该是图片,css样式表等
ha1
ha2
最后要写明白的一点怎样保持用户seesion,对于DNS,本来就有TTL值可以保证用户解析到同一IP,而对于haproxy,backend中使用的souce算法,也保证使其始终发往同一服务器。
至此HAproxy+双主Keepalived就告一段落,我还会继续努力,做最好的自己