haproxy+keepalived實現高可用負載均衡


---恢復內容開始---

一、haproxy介紹:

  HAProxy提供高可用性、負載均衡以及基於TCP和HTTP應用的代理,支持虛擬主機。HAProxy特別適用於那些負載特大的web站點,這些站點通常又需要會話保持或七層處理。HAProxy運行在時下的硬件上,完全可以支持數以萬計的並發連接。並且它的運行模式使得它可以很簡單安全的整合進您當前的架構中, 同時可以保護你的web服務器不被暴露到網絡上。HAProxy實現了一種事件驅動、單一進程模型,此模型支持非常大的並發連接數。多進程或多線程模型受內存限制 、系統調度器限制以及無處不在的鎖限制,很少能處理數千並發連接。事件驅動模型因為在有更好的資源和時間管理的用戶端(User-Space) 實現所有這些任務,所以沒有這些問題。此模型的弊端是,在多核系統上,這些程序通常擴展性較差。這就是為什么他們必須進行優化以 使每個CPU時間片(Cycle)做更多的工作。

  在linux內核版本為2.6或打了epoll補丁的linux2.4上運行haproxy能獲得其最好的性能。

 

二、keepalived介紹:  

  keepalived理論工作原理

      keepalived可提供vrrp以及health-check功能,可以只用它提供雙機浮動的vip(vrrp虛擬路由功能),這樣可以簡單實現一個雙機熱備高可用功能。

      keepalived是一個類似於layer3, 4 & 5交換機制的軟件,也就是我們平時說的第3層、第4層和第5層交換。Keepalived的作用是檢測web 服務器的狀態。 Layer3,4&5工作在IP/TCP協議棧的IP層,TCP層,及應用層,原理分別如下:

      Layer3:Keepalived使用Layer3的方式工作式時,Keepalived會定期向服務器群中的服務器 發送一個ICMP的數據包(既我們平時用的Ping程序),如果發現某台服務的IP地址沒有激活,Keepalived便報告這台服務器失效,並將它從服務器群中剔除,這種情況的典型例子是某台服務器被非法關機。Layer3的方式是以服務器的IP地址是否有效作為服務器工作正常與否的標准。在本文中將采用這種方式。

 

      Layer4:如果您理解了Layer3的方式,Layer4就容易了。Layer4主要以TCP端口的狀態來決定服務器工作正常與否。如web server的服務端口一般是80,如果Keepalived檢測到80端口沒有啟動,則Keepalived將把這台服務器從服務器群中剔除。

 

      Layer5:Layer5就是工作在具體的應用層了,比Layer3,Layer4要復雜一點,在網絡上占用的帶寬也要大一些。Keepalived將根據用戶的設定檢查服務器程序的運行是否正常,如果與用戶的設定不相符,則Keepalived將把服務器從服務器群中剔除。

 

         vip即虛擬ip,是附在主機網卡上的,即對主機網卡進行虛擬,此IP仍然是占用了此網段的某個IP。

 

  keepalived的用途:

      Keepalived是一個基於VRRP協議來實現的WEB 服務高可用方案,可以利用其來避免單點故障。一個WEB服務至少會有2台服務器運行Keepalived,一台為主服務器(MASTER),一台為備份服務器(BACKUP),但是對外表現為一個虛擬IP,主服務器會發送特定的消息給備份服務器,當備份服務器收不到這個消息的時候,即主服務器宕機的時候,備份服務器就會接管虛擬IP,繼續提供服務,從而保證了高可用性。

      在lvs+keepalived高可用負載均衡架構中,lvs本身不支持對后端real server進行健康狀態檢測,而keepalived的誕生不僅能是lvs均衡器實現了高可用,而且還能對lvs后端的real server進行健康狀態檢測。如果有一台web服務器死機,或工作出現故障,Keepalived將檢測到,並將有故障的web服務器從系統中剔除,當web服務器工作正常后Keepalived自動將web服務器加入到服務器群中,這些工作全部自動完成,不需要人工干涉,需要人工做的只是修復故障的web服務器。

 

 

 

 

 

配置過程:

在配置之前,先將HA中個節點進行時間同步,主機名之間相互解析,以及配置雙機互信。

在haproxy1.daixiang.com上配置:

[root@haproxy1 ~]# vim /etc/hosts
    172.16.0.1 haproxy1.daixiang.com haproxy1
    172.16.0.2 haproxy2.daixiang.com haproxy2
[root@haproxy1 ~]# ssh-keygen -t rsa -P '' [root@haproxy1 ~]# ssh-copy-id haproxy2 [root@haproxy1 ~]# ntpdate s2c.time.edu.cn

在haproxy2.daixiang.com上配置:

[root@haproxy2 ~]# vim /etc/hosts
    172.16.0.1 haproxy1.daixiang.com haproxy1
    172.16.0.2 haproxy2.daixiang.com haproxy2

[root@haproxy2 ~]# ssh-keygen -t rsa -P ''
[root@haproxy2 ~]# ssh-copy-id haproxy1
[root@haproxy2 ~]# ntpdate s2c.time.edu.cn

 

安裝haproxy和keepalived:

  在haproxy1和haproxy2節點上進行同樣的操作:

[root@haproxy1 ~]# yum install keepalived haproxy -y
[root@haproxy1 ~]# cd /etc/keepalived/
[root@haproxy1 keepalived]# cp keepalived.conf{,.bak}

 

配置keepalived:雙主模型

[root@haproxy1 keepalived]# vim keepalived.conf

! Configuration File for keepalived

global_defs {
   notification_email {         #定義收件人郵箱
     root@localhost
   }
   notification_email_from root@localhost      #定義發件人郵箱
   smtp_server 127.0.0.1                              #定義郵件服務器地址
   smtp_connect_timeout 30                         #定有郵件服務器連接超時時長為30秒
   router_id LVS_DEVEL                                 #運行keepalive的機器的標識
}

vrrp_instance VI_1 {                      #定義VRRP實例,實例名自定義
    state MASTER                             #指定當前節點的角色,master為主,backup為從
    interface eth1                             #直接HA監測的接口
    virtual_router_id 51                    #虛擬路由標識,在同一VRRP實例中,主備服務器ID必須一樣
    priority 100                                 #定義節點優先級,數字越大越優先,主服務器優先級高於從服務器
    advert_int 1                                #設置主備之間永不檢查時間間隔,單位為秒
    authentication {                          設置主從之間驗證類型和密碼
        auth_type PASS
        auth_pass a23c7f32dfb519d6a5dc67a4b2ff8f5e

    }
    virtual_ipaddress {
        192.168.80.200                      #定義虛擬ip地址
    }
}    

vrrp_instance VI_2 {
    state BACKUP
    interface eth1
    virtual_router_id 52
    priority 99
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 56f7663077966379d4106e8ee30eb1a5

    }
    virtual_ipaddress {
        192.168.80.201
    }
}
View Code

  將此配置文件同步到另一個haproxy2.daixiang.com上:

[root@haproxy1 keepalived]# scp keepalived.conf haproxy2:/etc/keepalived/

  在haproxy2.daixiang.com上修改keepalived.conf配置文件:

[root@haproxy2 keepalived]# vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
   notification_email {
     root@localhost
   }
   notification_email_from root@localhost
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth1
    virtual_router_id 51
    priority 99
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass a23c7f32dfb519d6a5dc67a4b2ff8f5e

    }
    virtual_ipaddress {
        192.168.80.200
    }
}

vrrp_instance VI_2 {
    state MASTER
    interface eth1
    virtual_router_id 52
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 56f7663077966379d4106e8ee30eb1a5

    }
    virtual_ipaddress {
        192.168.80.201
    }
}
View Code

  重啟keepalived:

[root@haproxy1 keepalived]# service keepalived restart
[root@haproxy1 keepalived]# ssh haproxy2 'service keepalived restart'

 

 

配置haproxy:

先將原始配置文件進行備份:

[root@haproxy1 ~]# cd /etc/haproxy/
[root@haproxy1 haproxy]# cp haproxy.cfg{,.bak}

##節點2也進行同樣的操作

編輯其配置文件修改其內容如下:

[root@haproxy1 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將日志進行歸檔記錄,在/etc/rsyslog.conf配置文件中,添加‘local2.*     /var/log/haproxy',並且啟用$ModLoad imudp,$UDPServerRun 514,$ModLoad imtcp,$InputTCPServerRun 514 此四項功能,最后重啟rsyslog進程。                           
    chroot      /var/lib/haproxy          #指定haproxy進程工作的目錄
    pidfile     /var/run/haproxy.pid      #指定pid文件
    maxconn     4000                      #最大並發連接數
    user        haproxy                   #運行haproxy的用戶
    group       haproxy                   #運行haproxy的組
    daemon                                #以守護進程的形式運行,即后台運行

    # 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                         #工作模式,源碼包編譯默認為tcp
    log                       global                    #記錄全局日志
    option                  httplog                     #詳細記錄http日志
    option                  dontlognull                 #不記錄健康檢測的日志信息
    option http-server-close                            #啟用服務器端主動關閉功能
    option forwardfor       except 127.0.0.0/8          #傳遞client端IP至后端real server
    option                  redispatch                  #基於cookie做會話保持時,后端對應存放session的服務器出現故障時,會話會被重定向至別的服務器
    retries                 3                           #請求重傳次數
    timeout http-request    10s                         #斷開客戶端連接的時長
    timeout queue           1m                          #一個請求在隊列里的超時時長
    timeout connect         10s                         #設定在haproxy轉發至后端upstream server時等待的超時時長
    timeout client          1m                          #client的一次非活動狀態的超時時長
    timeout server          1m                          #等待服務器端的非活動的超時時長
    timeout http-keep-alive 10s                         #持久連接超時時長
    timeout check           10s                         #檢查請求連接的超時時長
    maxconn                 3000                        #最大連接數

#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend  webserver *:80
    acl url_static       path_beg       -i /static /images /javascript /stylesheets       #匹配path以/static,/images開始的,且不區分大小寫
    acl url_static       path_end       -i .jpg .gif .png .css .js .html
    acl url_static       hdr_beg(host)  -i img. video. download. ftp. imgs. image.

    acl url_dynamic      path_end       .php .jsp

    use_backend static          if url_static           #滿足名為url_static這條acl規則,則將請求轉發至后端名為static的real server組中去
    use_backend dynamic         if url_dynamic
    default_backend             static                  #如果上面所有acl規則都不滿足,將請求轉發到static組中

#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static                              #定義后端real server組,組名為static
    balance     roundrobin                  #支持動態權重修改,支持慢啟動
    server      static_1 172.16.0.100:80 check inter 3000 fall 3 rise 1 maxconn 30000
    server      static_2 172.16.0.101:80 check inter 3000 fall 3 rise 1 maxconn 30000
    server      static_Error 172.16.0.1:8080 backup check         #當此組中的所有server全部不能提供服務,才將請求調度至此server上
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------


backend dynamic
    cookie cookie_name insert nocache   #使用cookie實現session綁定,且不記錄緩存
    balance     roundrobin
    server  dynamic1 172.16.0.200:80 check inter 3000 fall 3 rise 1 maxconn 1000 cookie dynamic1
    server  dynamic2 172.16.0.201:80 check inter 3000 fall 3 rise 1 maxconn 1000 cookie dynamic2      #定義dynamic組中的server,將此server命名為dynamic2,每隔3000ms檢測一個健康狀態,如果檢測3次都失敗,將此server剔除。在離線的狀態下,只要檢測1次成功,就讓其上線,此server支持最大的並發連接數為1000,cookie的值為dynamic2
     

listen state                                            # 使用單獨輸出,不需要frontedn調用:定義haproxy的狀態統計頁面
    bind *:8001                                         # 監聽的地址
    mode http                                           # http 7層工作模式:對應用層數據做深入分析,因此支持7層的過濾、處理、轉換等機制
    stats enable                                        # 開啟統計頁面輸出
    stats hide-version                                  # 隱藏狀態頁面版本號
    stats uri /haproxyadmin?stats                       # 指定狀態頁的訪問路徑
    stats auth admin:admin                              # 基於用戶名,密碼驗證。
    stats admin if TRUE                                 # 驗證通過時運行登錄。
    acl num1 src 192.168.80.0/24                        # 定義源地址為192.168.80.0/24網段的acl規則,將其命名為num1
    tcp-request content accept if num1                  # 如果滿足此規則,則允許訪問
    tcp-request content reject                          # 拒絕其他所有的訪問

將此配置文件同步當另一個haproxy節點上去: 

[root@haproxy1 haproxy]# scp haproxy.cfg haproxy2:/etc/haproxy/

重啟haproxy服務:

[root@haproxy1 haproxy]# service haproxy restart
[root@haproxy1 haproxy]# ssh haproxy2 'service haproxy restart'

 

查看這兩個節點獲取ip的情況:

haproxy1.daixiang.com:

[root@haproxy1 ~]# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> 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: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 00:0c:29:52:3b:c0 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.1/16 brd 172.16.255.255 scope global eth1
    inet 192.168.80.200/32 scope global eth1
    inet6 fe80::20c:29ff:fe52:3bc0/64 scope link 
       valid_lft forever preferred_lft forever
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:52:3b:ca brd ff:ff:ff:ff:ff:ff
    inet 192.168.80.125/24 brd 192.168.80.255 scope global eth0
    inet6 fe80::20c:29ff:fe52:3bca/64 scope link 
       valid_lft forever preferred_lft forever
[root@haproxy1 ~]# 
View Code

haproxy2.daixiang.com:

[root@haproxy2 haproxy]# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> 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
4: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:ae:5c:b3 brd ff:ff:ff:ff:ff:ff
    inet 192.168.80.128/24 brd 192.168.80.255 scope global eth0
    inet6 fe80::20c:29ff:feae:5cb3/64 scope link 
       valid_lft forever preferred_lft forever
6: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 00:0c:29:ae:5c:a9 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.2/16 brd 172.16.255.255 scope global eth1
    inet 192.168.80.201/32 scope global eth1
    inet6 fe80::20c:29ff:feae:5ca9/64 scope link 
       valid_lft forever preferred_lft forever
View Code

 

在后端的real server提供測試頁面,測試的結果如下:

請求以.html結尾的文件,haproxy將請求代理至后端static組中的server處理:

請求以.php結尾的文件,haproxy將請求代理至后端dynamic組中server處理:

 

注意:本文在haproxy.cfg的配置文件中,將dynamic組中的server配置了基於cookie的session綁定,所以,用同一瀏覽器看不出負載均衡的效果來。換個瀏覽器再訪問一次或者清空瀏覽器的cookie記錄就能顯示效果,如下圖。

 

haproxy的統計頁面輸出效果:

 

       至此,實驗完結,但是對於haproxy的兩個節點,keepalived對於這兩節點是怎么進行心跳檢測,其工作原理是什么,此知識點比較模糊,求大神賜教。

 

 

  

  

 

  

  

 

  

 

  

---恢復內容結束---


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM