1. 程式人生 > >lvs+keepalived+nginx負載均衡搭建測試

lvs+keepalived+nginx負載均衡搭建測試

lvs keepalived nginx centos7 ipvsadm

1. 簡介

1.1 LVS簡介

LVS(Linux Virtual Server),也就是Linux虛擬服務器, 是一個由章文嵩博士發起的自由軟件項目。使用LVS技術要達到的目標是:通過LVS提供的負載均衡技術和Linux操作系統實現一個高性能、高可用的服務器群集,它具有良好可靠性、可擴展性和可操作性。從而以低廉的成本實現最優的服務性能。

LVS主要用來做四層負載均衡。


1.2 Keepalived簡介

Keepalived是分布式部署系統解決系統高可用的軟件,結合LVS(Linux Virtual Server)使用,其功能類似於heartbeat,解決單機宕機的問題。

Keepalived是以VRRP協議為實現基礎的,VRRP全稱Virtual Router Redundancy Protocol,即虛擬路由冗余協議。通過VRRP協議結合LVS,對組群服務器監控情況,若master出現宕機情況,則將VIP漂移到backup機上。實現了分布式系統高可用。可以理解為:keepalived是LVS的管理軟件,根據監控情況,將宕機服務器從ipvsadm移除掉。
Keepalived的誕生最初是為LVS ipvs(director)提供高可用性的,後來發展一個多功能、通用的輕量級高可用組件,可以為ipvs、nginx、haproxy等諸多服務提供高可用功能,主要應用在負載均衡調度器上,同時也可以檢查後端各realserver的健康狀態。


1.3 Nginx簡介

Nginx(發音同engine x)是一個網頁服務器,它能反向代理HTTP, HTTPS, SMTP, POP3, IMAP的協議鏈接,以及一個負載均衡器和一個HTTP緩存。

Nginx主要用來做七層負載均衡。


1.4 負載均衡

四層負載均衡工作在OSI模型的傳輸層,由於在傳輸層,只有TCP/UDP協議,這兩種協議中除了包含源IP、目標IP以外,還包含源端口號及目的端口號。四層負載均衡服務器在接受到客戶端請求後,以後通過修改數據包的地址信息(IP+端口號)將流量轉發到應用服務器。

七層負載均衡工作在OSI模型的應用層,應用層協議較多,常用http、radius、dns等。七層負載就可以基於這些協議來負載。這些應用層協議中會包含很多有意義的內容。比如同一個Web服務器的負載均衡,除了根據IP加端口進行負載外,還可根據七層的URL、瀏覽器類別、語言來決定是否要進行負載均衡。

四層通過虛擬 IP + 端口接收請求,然後再分配到真實的服務器,七層通過虛擬的 URL 或主機名接收請求,然後再分配到真實的服務器。所謂的四到七層負載均衡,就是在對後臺的服務器進行負載均衡時,依據四層的信息或七層的信息來決定怎麽樣轉發流量。


1.5 LVS和Nginx區別

1.lvs工作在第4層,負載能力強,邏輯簡單,能對幾乎所有應用進行負載,包括web和數據庫;nginx工作在第7層,適用場合遠多於lvs,負載能力相對較差。
2.lvs對網絡穩定性依賴比較大;Nginx對網絡的依賴比較小,理論上只要Ping得通,網頁訪問正常就能連通。
3.Nginx可以通過服務器處理網頁返回的狀態碼、超時等來檢測服務器內部的故障,並會把返回錯誤的請求重新發送到另一個節點;目前LVS和LDirectd 也支持對服務器內部情況的監控,但不能重新發送請求。
4.Nginx安裝和配置比較簡單,測試起來比較方便,它基本能把錯誤用日誌打印出來;LVS的配置、測試耗時較長。
5.每日PV1000萬以下或並發請求1萬以下都可以考慮用Nginx;構建大型網站或者提供重要服務且機器較多時,可多加考慮利用LVS。


2. 搭建過程及測試

2.1 架構圖

技術分享圖片


2.2 主機配置

主機名
ip
操作系統
軟件
端口
lvs01
172.27.9.7
CentOS 7
lvs keepalived
81
lvs02
172.27.9.8
CentOS 7lvs keepalived
81
nginx01
172.27.9.91
CentOS 7nginx
81
nginx02
172.27.9.92
CentOS 7nginx
81


2.3 搭建準備

2.3.1 關閉防火墻

關閉4臺服務器防火墻

[root@lvs01 ~]# firewall-cmd --state
running
[root@lvs01 ~]# systemctl stop firewalld.service
[root@lvs01 ~]# firewall-cmd --state
not running


2.3.2 關閉防selinux

閉4臺服務器selinux,修改/etc/selinux/config,將SELINUX由enforcing設置為disabled,重啟服務器。

查看selinux狀態:

[root@lvs01 ~]# sestatus -v
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed

更改selinux狀態:

[root@lvs01 ~]# view /etc/selinux/config 
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.


2.4 ipvs安裝

LVS無需安裝,安裝的是管理工具,第一種叫ipvsadm,第二種叫keepalive。ipvsadm是通過命令行管理,而keepalive讀取配置文件管理。

分別在lvs01和lvs02執行如下操作:

[root@lvs01 ~]# yum -y install ipvsadm

把ipvsadm模塊加載進系統

[root@lvs01 ~]# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
[root@lvs01 ~]# lsmod | grep ip_vs
ip_vs                 141092  0 
nf_conntrack          111302  1 ip_vs
libcrc32c              12644  2 xfs,ip_vs


2.5 keepalived安裝

分別在lvs01和lvs02執行如下操作:

[root@lvs01 ~]# yum -y install keepalived

2.6 keepalived配置

lvs01配置如下:

[root@lvs01 ~]# more /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
   router_id LVS_DEVEL          #設置lvs的id,在一個網絡內應該是唯一的
}
vrrp_instance VI_1 {            #vrrp實例定義部分
    state MASTER               #設置lvs的狀態,MASTER和BACKUP兩種,必須大寫 
    interface ens33               #設置對外服務的接口
    virtual_router_id 100        #設置虛擬路由標示,這個標示是一個數字,同一個vrrp實例使用唯一標示 
    priority 100               #定義優先級,數字越大優先級越高,在一個vrrp——instance下,master的優先級必須大於backup
    advert_int 1              #設定master與backup負載均衡器之間同步檢查的時間間隔,單位是秒
    authentication {           #設置驗證類型和密碼
        auth_type PASS         #主要有PASS和AH兩種
        auth_pass 1111         #驗證密碼,同一個vrrp_instance下MASTER和BACKUP密碼必須相同
    }
    virtual_ipaddress {         #設置虛擬ip地址,可以設置多個,每行一個
        172.27.9.100 
    }
}
virtual_server 172.27.9.100 80 {       #設置虛擬服務器,需要指定虛擬ip和服務端口
    delay_loop 6                 #健康檢查時間間隔
    lb_algo wrr                  #負載均衡調度算法
    lb_kind DR                   #負載均衡轉發規則
    persistence_timeout 50        #設置會話保持時間,對動態網頁非常有用
    protocol TCP               #指定轉發協議類型,有TCP和UDP兩種
    real_server 172.27.9.91 80 {    #配置服務器節點1,需要指定real server的真實IP地址和端口
    weight 1               #設置權重,數字越大權重越高
    TCP_CHECK {              #realserver的狀態監測設置部分單位秒
       connect_timeout 10       #連接超時為10秒
       retry 3             #重連次數
       delay_before_retry 3        #重試間隔
       connect_port 80         #連接端口為80,要和上面的保持一致
       }
    }
     real_server 172.27.9.92 80 {    #配置服務器節點1,需要指定real server的真實IP地址和端口
     weight 1                  #設置權重,數字越大權重越高
     TCP_CHECK {               #realserver的狀態監測設置部分單位秒
       connect_timeout 10         #連接超時為10秒
       retry 3               #重連次數
       delay_before_retry 3        #重試間隔
       connect_port 80          #連接端口為80,要和上面的保持一致
       }
     }
}

lvs02配置如下:

[root@lvs02 ~]# more /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
   router_id LVS_DEVEL          #設置lvs的id,在一個網絡內應該是唯一的
}
vrrp_instance VI_1 {            #vrrp實例定義部分
    state BACKUP              #設置lvs的狀態,MASTER和BACKUP兩種,必須大寫 
    interface ens33           #設置對外服務的接口
    virtual_router_id 100         #設置虛擬路由標示,這個標示是一個數字,同一個vrrp實例使用唯一標示 
    priority 99             #定義優先級,數字越大優先級越高,在一個vrrp——instance下,master的優先級必須大於backup
    advert_int 1              #設定master與backup負載均衡器之間同步檢查的時間間隔,單位是秒
    authentication {            #設置驗證類型和密碼
        auth_type PASS         #主要有PASS和AH兩種
        auth_pass 1111         #驗證密碼,同一個vrrp_instance下MASTER和BACKUP密碼必須相同
    }
    virtual_ipaddress {         #設置虛擬ip地址,可以設置多個,每行一個
        172.27.9.100 
    }
}
virtual_server 172.27.9.100 80 {      #設置虛擬服務器,需要指定虛擬ip和服務端口
    delay_loop 6             #健康檢查時間間隔
    lb_algo wrr              #負載均衡調度算法
    lb_kind DR               #負載均衡轉發規則
    persistence_timeout 50          #設置會話保持時間,對動態網頁非常有用
    protocol TCP              #指定轉發協議類型,有TCP和UDP兩種
    real_server 172.27.9.91 80 {       #配置服務器節點1,需要指定real server的真實IP地址和端口
    weight 1                #設置權重,數字越大權重越高
    TCP_CHECK {              #realserver的狀態監測設置部分單位秒
       connect_timeout 10         #連接超時為10秒
       retry 3                #重連次數
       delay_before_retry 3       #重試間隔
       connect_port 80           #連接端口為80,要和上面的保持一致
       }
    }
     real_server 172.27.9.92 80 {   #配置服務器節點1,需要指定real server的真實IP地址和端口
     weight 1                #設置權重,數字越大權重越高
     TCP_CHECK {              #realserver的狀態監測設置部分單位秒
       connect_timeout 10          #連接超時為10秒
       retry 3             #重連次數
       delay_before_retry 3        #重試間隔
       connect_port 80         #連接端口為80,要和上面的保持一致
       }
     }
}


2.7 參數說明

IPVS三種IP負載均衡技術:

VS/NAT 即(Virtual Server via Network Address Translation)
也就是網絡地址翻譯技術實現虛擬服務器,當用戶請求到達調度器時,調度器將請求報文的目標地址(即虛擬IP地址)改寫成選定的Real Server地址,同時報文的目標端口也改成選定的Real Server的相應端口,最後將報文請求發送到選定的Real Server。在服務器端得到數據後,Real Server返回數據給用戶時,需要再次經過負載調度器將報文的源地址和源端口改成虛擬IP地址和相應端口,然後把數據發送給用戶,完成整個負載調度過程。
可以看出,在NAT方式下,用戶請求和響應報文都必須經過Director Server地址重寫,當用戶請求越來越多時,調度器的處理能力將稱為瓶頸。

VS/TUN即(Virtual Server via IP Tunneling)
也就是IP隧道技術實現虛擬服務器。它的連接調度和管理與VS/NAT方式一樣,只是它的報文轉發方法不同,VS/TUN方式中,調度器采用IP隧道技術將用戶請求轉發到某個Real Server,而這個Real Server將直接響應用戶的請求,不再經過前端調度器,此外,對Real Server的地域位置沒有要求,可以和Director Server位於同一個網段,也可以是獨立的一個網絡。因此,在TUN方式中,調度器將只處理用戶的報文請求,集群系統的吞吐量大大提高。

VS/DR: 即(Virtual Server via Direct Routing)
也就是用直接路由技術實現虛擬服務器。它的連接調度和管理與VS/NAT和VS/TUN中的一樣,但它的報文轉發方法又有不同,VS/DR通過改寫請求報文的MAC地址,將請求發送到Real Server,而Real Server將響應直接返回給客戶,免去了VS/TUN中的IP隧道開銷。這種方式是三種負載調度機制中性能最高最好的,但是必須要求Director Server與Real Server都有一塊網卡連在同一物理網段上,且真實服務器網絡設備或設備別名不作 ARP 響應


IPVS調度器實現了如下八種負載調度算法:

輪叫(Round Robin)
調度器通過"輪叫"調度算法將外部請求按順序輪流分配到集群中的真實服務器上,它均等地對待每一臺服務器,而不管服務器上實際的連接數和系統負載。

加權輪叫(Weighted Round Robin)
調度器通過"加權輪叫"調度算法根據真實服務器的不同處理能力來調度訪問請求。這樣可以保證處理能力強的服務器處理更多的訪問流量。調度器可以自動問詢真實服務器的負載情況,並動態地調整其權值。

最少鏈接(Least Connections)
調度器通過"最少連接"調度算法動態地將網絡請求調度到已建立的鏈接數最少的服務器上。如果集群系統的真實服務器具有相近的系統性能,采用"最小連接"調度算法可以較好地均衡負載。

加權最少鏈接(Weighted Least Connections)
在集群系統中的服務器性能差異較大的情況下,調度器采用"加權最少鏈接"調度算法優化負載均衡性能,具有較高權值的服務器將承受較大比例的活動連接負載。調度器可以自動問詢真實服務器的負載情況,並動態地調整其權值。

基於局部性的最少鏈接(Locality-Based Least Connections)
"基於局部性的最少鏈接" 調度算法是針對目標IP地址的負載均衡,目前主要用於Cache集群系統。該算法根據請求的目標IP地址找出該目標IP地址最近使用的服務器,若該服務器 是可用的且沒有超載,將請求發送到該服務器;若服務器不存在,或者該服務器超載且有服務器處於一半的工作負載,則用"最少鏈接"的原則選出一個可用的服務 器,將請求發送到該服務器。

帶復制的基於局部性最少鏈接(Locality-Based Least Connections with Replication)
"帶復制的基於局部性最少鏈接"調度算法也是針對目標IP地址的負載均衡,目前主要用於Cache集群系統。它與LBLC算法的不同之處是它要維護從一個 目標IP地址到一組服務器的映射,而LBLC算法維護從一個目標IP地址到一臺服務器的映射。該算法根據請求的目標IP地址找出該目標IP地址對應的服務 器組,按"最小連接"原則從服務器組中選出一臺服務器,若服務器沒有超載,將請求發送到該服務器,若服務器超載;則按"最小連接"原則從這個集群中選出一 臺服務器,將該服務器加入到服務器組中,將請求發送到該服務器。同時,當該服務器組有一段時間沒有被修改,將最忙的服務器從服務器組中刪除,以降低復制的 程度。

目標地址散列(Destination Hashing)
"目標地址散列"調度算法根據請求的目標IP地址,作為散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器,若該服務器是可用的且未超載,將請求發送到該服務器,否則返回空。

源地址散列(Source Hashing)
"源地址散列"調度算法根據請求的源IP地址,作為散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器,若該服務器是可用的且未超載,將請求發送到該服務器,否則返回空。


本例中采用DR負載均衡和wrr負載調度算法


2.8 nginx搭建

nginx搭建詳見Centos7安裝nginx 。


2.9 realserver.sh配置

打開Nginx所在服務器的“路由”功能、關閉“ARP查詢”功能並設置回環ip,nginx01和nginx02配置如下:

[root@nginx01 init.d]# more /etc/rc.d/init.d/realserver.sh 
#!/bin/bash
    SNS_VIP=172.27.9.100
    /etc/rc.d/init.d/functions
    case "$1" in
    start)
        ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP
        /sbin/route add -host $SNS_VIP dev lo:0
        echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
        echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
        echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
        echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
        sysctl -p >/dev/null 2>&1
        echo "RealServer Start OK"
        ;;
    stop)
        ifconfig lo:0 down
        route del $SNS_VIP >/dev/null 2>&1
        echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
        echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
        echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
        echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
        echo "RealServer Stoped"
        ;;
    *)
        echo "Usage: $0 {start|stop}"
        exit 1
    esac
    exit 0

此腳本用於節點服務器綁定 VIP ,並抑制響應 VIP 的 ARP 請求。這樣做的目的是為了不讓關於 VIP 的 ARP 廣播時,節點服務器應答( 因為節點服務器都綁定了 VIP ,如果不做設置它們會應答,就會亂套 )。


給realserver.sh腳本授予執行權限:

[root@nginx01 init.d]# chmod u+x realserver.sh


3. 負載均衡及高可用測試

3.1 啟動Keepalived

lvs01和lvs02分別執行:


[root@lvs01 ~]# service keepalived start

查看ip,lvs01上有vip172.27.9.100,lvs02沒有:

技術分享圖片

技術分享圖片



3.2 啟動nginx

如果nginx未運行則在nginx01和nginx02執行:

[root@nginx01 ~]# nginx


3.3 運行realserver.sh腳本

在nginx01和nginx02執行realserver.sh腳本:

[root@nginx01 ~]# /etc/rc.d/init.d/realserver.sh start


3.4 修改nginx默認首頁

nginx01和nginx02上分別修改index.html:

[root@nginx01 html]# view /usr/local/nginx/html/index.html

新增內容如圖:

技術分享圖片技術分享圖片


3.5 頁面訪問

3.5.1 訪問vip

通過不同瀏覽器訪問http://172.27.9.100:81

技術分享圖片




3.5.2 Master上檢查連接情況

lvs01上執行ipvsadm -ln:

技術分享圖片


3.5.3 ipvsadm參數說明

ipvsadm:

-L|-l(–list):顯示內核虛擬服務器表

-n–numeric):輸出IP 地址和端口的數字形式

輸出參數說明:

Forward 轉發方式,當前是路由轉發
Weight 權重
ActiveConn 當前活躍的連接數
InActConn 當前不活躍的連接數

3.5.4 修改keepalived參數

通過ipvsadm命令發現訪問請求都被分配到92(nginx02)這臺服務器,沒有實現負載均衡。這個和keepalived參數配置persistence_timeout有關,這個參數的意義是保持客戶端的請求在這個時間段內全部發到同一個真實服務器。

分別註釋lvs01和lvs02的persistence_timeout:

[root@lvs01 keepalived]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
[root@lvs01 keepalived]# view /etc/keepalived/keepalived.conf
#persistence_timeout 50

重啟兩臺lvs服務器keepalived服務:

[root@lvs01 keepalived]# service keepalived restart

再次測試:

技術分享圖片

發現連接均勻的分配到後臺兩臺nginx服務器。


3.5.5 lvs高可用測試

恢復keepalived配置並重啟服務。

lvs01宕機前訪問頁面:

技術分享圖片

停止lvs01的keepalived服務,模擬lvs01宕機:

[root@lvs01 keepalived]# service keepalived stop
Redirecting to /bin/systemctl stop  keepalived.service
[root@lvs01 keepalived]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:ef:97:ad brd ff:ff:ff:ff:ff:ff
    inet 172.27.9.7/24 brd 172.27.9.255 scope global ens33
       valid_lft forever preferred_lft forever
[root@lvs01 keepalived]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

查看lvs01的keepalived日誌和狀態:

技術分享圖片

查看lvs02情況:

[root@lvs02 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:e3:ea:c1 brd ff:ff:ff:ff:ff:ff
    inet 172.27.9.8/24 brd 172.27.9.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet 172.27.9.100/32 scope global ens33
       valid_lft forever preferred_lft forever

發現vip已飄至lvs02。

http://172.27.9.100:81/,訪問正常:

技術分享圖片

恢復lvs01的keepalived服務:

[root@lvs01 keepalived]# service keepalived start
Redirecting to /bin/systemctl start  keepalived.service
[root@lvs01 keepalived]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:ef:97:ad brd ff:ff:ff:ff:ff:ff
    inet 172.27.9.7/24 brd 172.27.9.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet 172.27.9.100/32 scope global ens33
       valid_lft forever preferred_lft forever

發現vip飄回至lvs01,vip頁面訪問正常


3.5.6 nginx高可用測試

目前通過vip訪問的後端nginx服務器為92即nginx02,現在停止92上的nginx服務,模擬nginx02宕機,查看vip頁面訪問情況:

[root@nginx02 init.d]# ps -ef|grep nginx
root       2216      1  0 4月04 ?       00:00:00 nginx: master process nginx
nobody     2217   2216  0 4月04 ?       00:00:00 nginx: worker process
root       2390   2196  0 00:06 pts/0    00:00:00 grep --color=auto nginx
[root@nginx02 init.d]# kill -9 2216 2217

查看頁面訪問:

技術分享圖片

發現後端nginx連接轉至91即nginx01,在lvs01上查看連接情況:

技術分享圖片



總結:

當 MASTER 服務器無法提供服務時,VIP 會在 MASTER 上自動移除,BACKUP 服務器會提升為 MASTER 狀態,綁定 VIP 、接管服務。
當 MASTER 修復加入網絡後,會自動搶回 VIP ,成為 MASTER 身份。
當後端提供服務nginx服務掛起時,會自動切換至其它nginx服務器。




lvs+keepalived+nginx負載均衡搭建測試