前言
软件负载均衡一般通过两种方式来实现:基于操作系统的软负载实现和基于第三方应用的软负载均衡。LVS是基于Linux操作系统实现的一种软负载,而Haproxy则是基于第三方应用实现的软负载。Haproxy相比LVS的使用要简单很多,但跟LVS一样,Haproxy自己并不能实现高可用,一旦Haprox节点故障,将会影响整个站点。本文是haprox基于keepalived实现web高可用及动静分离。
相关介绍
HAProxy
haproxy是一款提供高可用性、负载均衡以及基于TCP和HTTP应用的代理软件,Haproxy是完全免费的,借助Haproxy可以快速并且可靠的提供基于TCP和HTTP应用的代理解决方案。Haproxy适用于那些负载较大的Web站点,这些站点通常又需要会话保持或七层出来。Haproxy可以支持数以万计的并发连接,并且Haproxy的运行模式使得它可以很简单安全的整合进架构中,同时可以包含web服务器不被暴露在网络上。
keepalived
keepalived是基于VRRP(virtual router redundancy protocol,虚拟路由冗余协议)热备份协议工作的,以软件的方式实现linux服务器的多机热备功能。VRRP是针对路由器的一种备份解决方案----由多台路由器组成一个热备组。通过共用的虚拟IP地址对外提供服务;每个热备组内同一时刻只有一台主服务器提供服务,其他服务器处于冗余状态,若当前在线的服务器失败,其他服务器会自动接替(优先级决定接替顺序)虚拟IP地址,以继续提供服务。
高可用解决方案拓扑
一、测试环境:Centos6.7+Centos7.1;使用5台虚拟机
分别对他们设置主机名: 主机名 ip地址 软件包 VIP mail 192.168.5.10 ansible+mysqld node1 192.168.5.11 haproxy+keepalived 192.168.5.9 node2 192.168.5.12 haproxy+keepalived 192.168.5.8 node3 192.168.5.13 lamp node4 192.168.5.14 httpd
二、准备工作:这里基于ansible做一下简单部署
1、基于ssh通信,先做密钥; # ssh-copy-id -i /root/.ssh/id_rsa.pub node1 # ssh-copy-id -i /root/.ssh/id_rsa.pub node2 # ssh-copy-id -i /root/.ssh/id_rsa.pub node3 # ssh-copy-id -i /root/.ssh/id_rsa.pub node4 2、ansible设置及管理节点探测: # cd /etc/ansible/ # vim hosts [haproxy] node1 node2 [dynamic] node3 [p_w_picpaths] node4 # ansible all -m ping node3 | success >> { "changed": false, "ping": "pong" } node1 | success >> { "changed": false, "ping": "pong" } node2 | success >> { "changed": false, "ping": "pong" } node4 | success >> { "changed": false, "ping": "pong" }
三、在node1和node2上安装haproxy和keepalived
时间同步 # ansible all -m shell -a 'ntpdate cn.pool.ntp.org' # ansible all -m shell -a 'date' 192.168.5.12 | success | rc=0 >> Fri Jan 29 16:22:07 CST 2016 192.168.5.11 | success | rc=0 >> Fri Jan 29 16:22:07 CST 2016 192.168.5.13 | success | rc=0 >> Fri Jan 29 16:22:07 CST 2016 192.168.5.14 | success | rc=0 >> Fri Jan 29 16:22:07 CST 2016 主机互信 [root@node1 ~]# ssh-keygen -t rsa [root@node1 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub node2 [root@node2 ~]# ssh-keygen -t rsa [root@node2 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub node1 安装所需程序 # ansible haproxy -m shell -a 'yum -y install haproxy keepalived' # ansible haproxy -m yum -a 'name=haproxy,keepalived state=present' (两条命令,任选一条) 1、配置keepalived 在node1节点上修改keepalived [root@node1 keepalived]# cp keepalived.conf{,.bak} [root@node1 keepalived]# ls keepalived.conf keepalived.conf.bak [root@node1 keepalived]# vim keepalived.conf ! Configuration File for keepalived global_defs { #全局设置,设置报警的收件人 notification_email { root@localhost #指定通知的邮箱地址 } notification_email_from root #指定通知邮件时由谁发送的 smtp_server 127.0.0.1 #指定smtp邮件服务器地址 smtp_connect_timeout 30 router_id LVS_DEVEL } vrrp_instance VI_1 { #定义VRRP实例,实例名自定义 state MASTER #指定keepalived的角色,MASTER为主服务器,BACKUP为备用服务器 interface eth0 #指定HA检测接口 virtual_router_id 61 #虚拟路由标识(1-255),在一个VRRP实例中主备服务器ID必须一样 priority 100 #指定优先级,注意,主的一定要比从的优先级数字大 advert_int 5 #指定主备同步时间间隔,单位秒 authentication { #设置验证类型和密码 auth_type PASS #验证类型 auth_pass 1234 #指定认证密码,同一实例中主备密码必须一致 } virtual_ipaddress { 192.168.5.9 #指定VIP } } vrrp_instance VI_2 { #定义VRRP实例,实例名自定义 state BACKUP #指定keepalived的角色,MASTER为主服务器,BACKUP为备用服务器 interface eth0 #指定HA检测接口 virtual_router_id 71 #虚拟路由标识(1-255),在一个VRRP实例中主备服务器ID必须一样 priority 98 #指定优先级,注意,主的一定要比从的优先级数字大 advert_int 5 #指定主备同步时间间隔,单位秒 authentication { #设置验证类型和密码 auth_type PASS #验证类型 auth_pass 2345 #指定认证密码,同一实例中主备密码必须一致 } virtual_ipaddress { 192.168.5.8 #指定VIP } } # scp keepalived.conf node2:/etc/keepalived keepalived.conf 100% 515 0.5KB/s 00:00 在node2节点上修改keepalived # cat keepalived.conf ! Configuration File for keepalived global_defs { #全局设置,设置报警的收件人 notification_email { root@localhost #指定通知的邮箱地址 } notification_email_from root #指定通知邮件时由谁发送的 smtp_server 127.0.0.1 #指定smtp邮件服务器地址 smtp_connect_timeout 30 router_id LVS_DEVEL } vrrp_instance VI_1 { #定义VRRP实例,实例名自定义 state BACKUP #指定keepalived的角色,MASTER为主服务器,BACKUP为备用服务器 interface eth0 #指定HA检测接口 virtual_router_id 61 #虚拟路由标识(1-255),在一个VRRP实例中主备服务器ID必须一样 priority 88 #指定优先级,注意,主的一定要比从的优先级数字大 advert_int 5 #指定主备同步时间间隔,单位秒 authentication { #设置验证类型和密码 auth_type PASS #验证类型 auth_pass 1234 #指定认证密码,同一实例中主备密码必须一致 } virtual_ipaddress { 192.168.5.9 #指定VIP } } vrrp_instance VI_2 { #定义VRRP实例,实例名自定义 state MASTER #指定keepalived的角色,MASTER为主服务器,BACKUP为备用服务器 interface eth0 #指定HA检测接口 virtual_router_id 71 #虚拟路由标识(1-255),在一个VRRP实例中主备服务器ID必须一样 priority 100 #指定优先级,注意,主的一定要比从的优先级数字大 advert_int 5 #指定主备同步时间间隔,单位秒 authentication { #设置验证类型和密码 auth_type PASS #验证类型 auth_pass 2345 #指定认证密码,同一实例中主备密码必须一致 } virtual_ipaddress { 192.168.5.8 #指定VIP } r } # ansible haproxy -m shell -a 'service keepalived start' node1 | success | rc=0 >> Starting keepalived: [ OK ] node2 | success | rc=0 >> Starting keepalived: [ OK ] # ansible haproxy -m shell -a 'ip addr show' node2 | success | rc=0 >> 1: lo:mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:31:87:be brd ff:ff:ff:ff:ff:ff inet 192.168.5.12/24 brd 192.168.5.255 scope global eth0 inet 192.168.5.8/32 scope global eth0 inet6 fe80::20c:29ff:fe31:87be/64 scope link valid_lft forever preferred_lft forever node1 | success | rc=0 >> 1: lo: mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:8d:8c:c3 brd ff:ff:ff:ff:ff:ff inet 192.168.5.11/24 brd 192.168.5.255 scope global eth0 inet 192.168.5.9/32 scope global eth0 inet6 fe80::20c:29ff:fe8d:8cc3/64 scope link valid_lft forever preferred_lft forever ###可以看出VIP在node1和node2上各一个 2、配置Haproxy 在node1节点上修改haproxy # vim haproxy.cfg #--------------------------------------------------------------------- # Example configuration for a possible web application. See the # full configuration options online. # # http://haproxy.1wt.eu/download/1.4/doc/configuration.txt # #--------------------------------------------------------------------- #--------------------------------------------------------------------- # Global settings #--------------------------------------------------------------------- global # to have these messages end up in /var/log/haproxy.log you will # need to: # # 1) configure syslog to accept network log events. This is done # by adding the '-r' option to the SYSLOGD_OPTIONS in # /etc/sysconfig/syslog # # 2) configure local2 events to go to the /var/log/haproxy.log # file. A line like the following can be added to # /etc/sysconfig/syslog # # local2.* /var/log/haproxy.log # log 127.0.0.1 local2 #日志通过rsyslog进行归档记录 chroot /var/lib/haproxy #运行的安装路径 pidfile /var/run/haproxy.pid #pid文件存放位置 maxconn 4000 #最大连接数 user haproxy #运行程序使用haproxy用户 group haproxy #运行程序使用haproxy组 daemon #以后台模式运行haproxy # turn on stats unix socket stats socket /var/lib/haproxy/stats #--------------------------------------------------------------------- # common defaults that all the 'listen' and 'backend' sections will # use if not designated in their block #--------------------------------------------------------------------- defaults mode http #工作模式 log global #记录日志 option httplog #详细记录http日志 option dontlognull #不记录健康检查的日志信息 option http-server-close #启用服务器端主动关闭 option forwardfor except 127.0.0.0/8 #传递客户端IP option redispatch retries 3 #请求重试次数 timeout http-request 10s #http请求超时时间 timeout queue 1m #一个请求在队列里的超时时间 timeout connect 10s #连接服务器超时时间 timeout client 1m #客户端超时时间 timeout server 1m #客户端超时时间 timeout http-keep-alive 10s #持久连接超时时间 timeout check 10s #心跳检测超市时间 maxconn 3000 #最大连接数 #--------------------------------------------------------------------- # main frontend which proxys to the backends #--------------------------------------------------------------------- frontend proxy *:80 #定义ACL acl url_static path_beg -i /static /p_w_picpaths /javascript /stylesheets acl url_static path_end -i .jpg .gif .png .css .js acl url_dynamic path_end -i .php .jsp use_backend dynamic if url_dynamic #调用后端服务器并检查ACL规则是否被匹配 default_backend static #--------------------------------------------------------------------- # static backend for serving up p_w_picpaths, stylesheets and such #--------------------------------------------------------------------- backend static #后端算法 balance source server static 192.168.5.13:80 inter 1500 rise 2 fall 3 check #--------------------------------------------------------------------- listen statistics mode http #http 7 层模式 bind *:8080 #监听地址 stats enable #启用状态监控 stats auth admin:admin #验证的用户与密码 stats uri /admin?status #访问路径 stats hide-version #隐藏状态页面版本号 stats admin if TRUE #如果验证通过了就允许登录 stats refresh 3s #每3秒刷新一次 acl allow src 192.168.5.0/24 #允许的访问的IP地址 tcp-request content accept if allow #允许的地址段就允许访问 tcp-request content reject #拒绝非法连接 #--------------------------------------------------------------------- # round robin balancing between the various backends #--------------------------------------------------------------------- backend dynamic balance source server synamic 192.168.5.14:80 check inter 1500 rise 2 fall 3 #check inter 1500是检测心跳频率 #rise2 2次正确认为服务器可用 #fall3 3次失败认为服务器不可用 将配置文件拷贝到node2上 [root@node1 haproxy]# scp haproxy.cfg node2:/etc/haproxy haproxy.cfg 100% 4737 4.6KB/s 00:00 配置web页面 ##node3(static)静态页面服务器 [root@node3 ~]# yum -y install httpd [root@node3 ~]# echo "node3.bjwf125.com" > /var/www/html/index.html [root@node3 ~]# systemctl start httpd.service ##node4(dynamic)动态服务器 [root@node4 ~]# yum -y install httpd php php-mysql [root@node4 ~]# vim /var/www/html/index.php node4.bjwf125.com [root@node4 ~]# systemctl start httpd.service 启动haproxy # ansible haproxy -m shell -a 'service haproxy start'
查看静态页面
查看动态页面