前言

    软件负载均衡一般通过两种方式来实现:基于操作系统的软负载实现和基于第三方应用的软负载均衡。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地址                软件包               VIPmail                      192.168.5.10          ansible+mysqldnode1                     192.168.5.11          haproxy+keepalived   192.168.5.9node2                     192.168.5.12          haproxy+keepalived   192.168.5.8node3                     192.168.5.13          lampnode4                     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 node42、ansible设置及管理节点探测:# cd /etc/ansible/# vim hosts[haproxy]node1node2[dynamic]node3 [p_w_picpaths]node4# ansible all -m pingnode3 | 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 2016192.168.5.11 | success | rc=0 >>Fri Jan 29 16:22:07 CST 2016192.168.5.13 | success | rc=0 >>Fri Jan 29 16:22:07 CST 2016192.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]# lskeepalived.conf  keepalived.conf.bak[root@node1 keepalived]# vim keepalived.conf! Configuration File for keepalivedglobal_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/keepalivedkeepalived.conf                                     100%  515     0.5KB/s   00:00在node2节点上修改keepalived# cat keepalived.conf ! Configuration File for keepalivedglobal_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 forever2: 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 forevernode1 | 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 forever2: 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/haproxyhaproxy.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'

查看静态页面

查看动态页面