LVS+Keepalived實現負載均衡

周旭龍發表於2015-02-11

一、負載均衡:必不可少的基礎手段

1.1 找更多的牛來拉車吧

當前大多數的網際網路系統都使用了伺服器叢集技術,叢集即將相同服務部署在多臺伺服器上構成一個叢集整體對外提供服務,這些叢集可以是Web應用伺服器叢集,也可以是資料庫伺服器叢集,還可以是分散式快取伺服器叢集等等。

cowls

古人有云:當一頭牛拉不動車的時候,不要去尋找一頭更強壯的牛,而是用兩頭牛來拉車

load balance

在實際應用中,在Web伺服器叢集之前總會有一臺負載均衡伺服器,負載均衡裝置的任務就是作為Web伺服器流量的入口,挑選最合適的一臺Web伺服器,將客戶端的請求轉發給它處理,實現客戶端到真實服務端的透明轉發。最近幾年很火的「雲端計算」以及分散式架構,本質上也是將後端伺服器作為計算資源、儲存資源,由某臺管理伺服器封裝成一個服務對外提供,客戶端不需要關心真正提供服務的是哪臺機器,在它看來,就好像它面對的是一臺擁有近乎無限能力的伺服器,而本質上,真正提供服務的,是後端的叢集。

1.2 負載均衡的型別

負載均衡可以採用硬體裝置(例如常常聽見的F5),也可以採用軟體負載。

商用硬體負載裝置成本通常較高(一臺幾十萬上百萬很正常),所以在條件允許的情況下我們會採用軟體負載;

軟體負載解決的兩個核心問題是:選誰、轉發,其中最著名的是LVS(Linux Virtual Server)。

傳送門->關於負載均衡的實現方式型別等介紹請瀏覽我的另一篇博文:《大型網站技術架構》讀書筆記之六:永無止境之網站的伸縮性架構

二、初識LVS:Linux Virtual Server

2.1 LVS是神馬東西

LVS是Linux Virtual Server的簡稱,也就是Linux虛擬伺服器, 是一個由章文嵩博士發起的自由軟體專案,它的官方站點是www.linuxvirtualserver.org。現在LVS已經是 Linux標準核心的一部分,在Linux2.4核心以前,使用LVS時必須要重新編譯核心以支援LVS功能模組,但是從Linux2.4核心以後,已經完全內建了LVS的各個功能模組,無需給核心打任何補丁,可以直接使用LVS提供的各種功能。

2.2 LVS有神馬作用

LVS主要用於伺服器叢集的負載均衡。它工作在網路層,可以實現高效能,高可用的伺服器叢集技術。它廉價,可把許多低效能的伺服器組合在一起形成一個超級伺服器。它易用,配置非常簡單,且有多種負載均衡的方法。它穩定可靠,即使在叢集的伺服器中某臺伺服器無法正常工作,也不影響整體效果。另外可擴充套件性也非常好。

LVS自從1998年開始,發展到現在已經是一個比較成熟的技術專案了。可以利用LVS技術實現高可伸縮的、高可用的網路服務,例如WWW服務、Cache服務、DNS服務、FTP服務、MAIL服務、視訊/音訊點播服務等等,有許多比較著名網站和組織都在使用LVS架設的叢集系統,例如:Linux的入口網站(www.linux.com)、向RealPlayer提供音訊視訊服務而聞名的Real公司(www.real.com)、全球最大的開源網站(sourceforge.net)等。

2.3 LVS的體系結構

使用LVS架設的伺服器叢集系統有三個部分組成:

(1)最前端的負載均衡層,用Load Balancer表示;

(2)中間的伺服器叢集層,用Server Array表示;

(3)最底端的資料共享儲存層,用Shared Storage表示;

在使用者看來,所有的內部應用都是透明的,使用者只是在使用一個虛擬伺服器提供的高效能服務。

傳送門->關於體系結構的詳細介紹,請瀏覽南飛螞蟻的blog:http://ixdba.blog.51cto.com/2895551/552947

2.4 LVS負載均衡機制

(1)LVS是四層負載均衡,也就是說建立在OSI模型的第四層——傳輸層之上,傳輸層上有我們熟悉的TCP/UDP,LVS支援TCP/UDP的負載均衡。因為LVS是四層負載均衡,因此它相對於其它高層負載均衡的解決辦法,比如DNS域名輪流解析、應用層負載的排程、客戶端的排程等,它的效率是非常高的。

(2)LVS的轉發主要通過修改IP地址(NAT模式,分為源地址修改SNAT和目標地址修改DNAT)、修改目標MAC(DR模式)來實現。

①NAT模式:網路地址轉換

NAT

NAT(Network Address Translation)是一種外網和內網地址對映的技術。NAT模式下,網路資料包的進出都要經過LVS的處理。LVS需要作為RS(真實伺服器)的閘道器。當包到達LVS時,LVS做目標地址轉換(DNAT),將目標IP改為RS的IP。RS接收到包以後,彷彿是客戶端直接發給它的一樣。RS處理完,返回響應時,源IP是RS IP,目標IP是客戶端的IP。這時RS的包通過閘道器(LVS)中轉,LVS會做源地址轉換(SNAT),將包的源地址改為VIP,這樣,這個包對客戶端看起來就彷彿是LVS直接返回給它的。客戶端無法感知到後端RS的存在。

②DR模式:直接路由

DR

DR模式下需要LVS和RS叢集繫結同一個VIP(RS通過將VIP繫結在loopback實現),但與NAT的不同點在於:請求由LVS接受,由真實提供服務的伺服器(RealServer, RS)直接返回給使用者,返回的時候不經過LVS。詳細來看,一個請求過來時,LVS只需要將網路幀的MAC地址修改為某一臺RS的MAC,該包就會被轉發到相應的RS處理,注意此時的源IP和目標IP都沒變,LVS只是做了一下移花接木。RS收到LVS轉發來的包時,鏈路層發現MAC是自己的,到上面的網路層,發現IP也是自己的,於是這個包被合法地接受,RS感知不到前面有LVS的存在。而當RS返回響應時,只要直接向源IP(即使用者的IP)返回即可,不再經過LVS。

(3)DR負載均衡模式資料分發過程中不修改IP地址,只修改mac地址,由於實際處理請求的真實物理IP地址和資料請求目的IP地址一致,所以不需要通過負載均衡伺服器進行地址轉換,可將響應資料包直接返回給使用者瀏覽器,避免負載均衡伺服器網路卡頻寬成為瓶頸。因此,DR模式具有較好的效能,也是目前大型網站使用最廣泛的一種負載均衡手段。

三、構建實戰:LVS+Keepalived實現負載均衡

3.1 實驗結構總覽

(1)本次基於VMware Workstation搭建一個四臺Linux(CentOS 6.4)系統所構成的一個伺服器叢集,其中兩臺負載均衡伺服器(一臺為主機,另一臺為備機),另外兩臺作為真實的Web伺服器(向外部提供http服務,這裡僅僅使用了CentOS預設自帶的http服務,沒有安裝其他的類似Tomcat、Jexus服務)。

(2)本次實驗基於DR負載均衡模式,設定了一個VIP(Virtual IP)為192.168.80.200,使用者只需要訪問這個IP地址即可獲得網頁服務。其中,負載均衡主機為192.168.80.100,備機為192.168.80.101。Web伺服器A為192.168.80.102,Web伺服器B為192.168.80.103。

3.2 基礎準備工作

以下工作針對所有伺服器,也就是說要在四臺伺服器中都要進行配置:

(1)繫結靜態IP地址

命令模式下可以執行setup命令進入設定介面配置靜態IP地址;x-window介面下可以右擊網路圖示配置;配置完成後執行service network restart重新啟動網路服務;

驗證:執行命令ifconfig

(2)設定主機名

①修改當前會話中的主機名,執行命令hostname xxxx (這裡xxxx為你想要改為的名字)

②修改配置檔案中的主機名,執行命令vi /etc/sysconfig/network (√一般需要進行此步湊才能永久更改主機名)

驗證:重啟系統reboot

(3)IP地址與主機名的繫結

執行命令vi /etc/hosts,增加一行內容,如下(下面的從節點以你自己的為主,本實驗搭建了兩個從節點):

  192.168.80.100 lvs-master

  192.168.80.101 lvs-slave

  #下面是本次試驗的兩個真實伺服器節點

  192.168.80.102 lvs-webserver1

  192.168.80.103 lvs-webserver2

儲存後退出

驗證:ping lvs-master

(4)關閉防火牆

①執行關閉防火牆命令:service iptables stop

驗證:service iptables stauts

②執行關閉防火牆自動執行命令:chkconfig iptables off

驗證:chkconfig –list | grep iptables

3.3 配置兩臺Web伺服器

以下操作需要在角色為Web伺服器的兩臺中進行,不需要在負載均衡伺服器中進行操作:

(1)開啟http服務

命令:service httpd start

補充:chkconfig httpd on –>將httpd設為自啟動服務

(2)在宿主機訪問Web網頁,並通過FTP工具上傳自定義網頁:這裡上傳一個靜態網頁,並通過更改其中的html來區別兩臺Web伺服器,以下圖所示為例,其中一臺顯示from 192.168.80.102,而另一臺顯示from 192.168.80.103;

(3)編輯realserver指令碼檔案

①進入指定資料夾:cd /etc/init.d/

②編輯指令碼檔案:vim realserver

SNS_VIP=192.168.80.200
/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

這裡我們設定虛擬IP為:192.168.80.200

③儲存指令碼檔案後更改該檔案許可權:chmod 755 realserver

④開啟realserver服務:service realserver start

3.4 配置主負載伺服器

(1)安裝Keepalived相關包

yum install -y keepalived

在CentOS下,通過yum install命令可以很方便地安裝軟體包,但是前提是你的虛擬機器要聯網;

(2)編輯keepalived.conf配置檔案

①進入keepalived.conf所在目錄:cd /etc/keepalived

②首先清除掉keepalived原有配置:> keepalived.conf

③重新編輯keepalived配置檔案:vi keepalived.conf

global_defs {  
   notification_email {  
         edisonchou@hotmail.com  
   }  
   notification_email_from sns-lvs@gmail.com  
   smtp_server 192.168.80.1  
   smtp_connection_timeout 30
   router_id LVS_DEVEL  # 設定lvs的id,在一個網路內應該是唯一的
}  
vrrp_instance VI_1 {  
    state MASTER   #指定Keepalived的角色,MASTER為主,BACKUP為備          
    interface eth1  #指定Keepalived的角色,MASTER為主,BACKUP為備
    virtual_router_id 51  #虛擬路由編號,主備要一致
    priority 100  #定義優先順序,數字越大,優先順序越高,主DR必須大於備用DR    
    advert_int 1  #檢查間隔,預設為1s
    authentication {  
        auth_type PASS  
        auth_pass 1111  
    }  
    virtual_ipaddress {  
        192.168.80.200  #定義虛擬IP(VIP)為192.168.2.33,可多設,每行一個
    }  
}  
# 定義對外提供服務的LVS的VIP以及port
virtual_server 192.168.80.200 80 {  
    delay_loop 6 # 設定健康檢查時間,單位是秒                    
    lb_algo wrr # 設定負載排程的演算法為wlc                   
    lb_kind DR # 設定LVS實現負載的機制,有NAT、TUN、DR三個模式   
    nat_mask 255.255.255.0                
    persistence_timeout 0          
    protocol TCP                  
    real_server 192.168.80.102 80 {  # 指定real server1的IP地址
        weight 3   # 配置節點權值,數字越大權重越高              
        TCP_CHECK {  
        connect_timeout 10         
        nb_get_retry 3  
        delay_before_retry 3  
        connect_port 80  
        }  
    }  
    real_server 192.168.80.103 80 {  # 指定real server2的IP地址
        weight 3  # 配置節點權值,數字越大權重越高  
        TCP_CHECK {  
        connect_timeout 10  
        nb_get_retry 3  
        delay_before_retry 3  
        connect_port 80  
        }  
     }  
}

(3)開啟keepalived服務

service keepalived start

3.5 配置從負載伺服器

從負載伺服器與主負載伺服器大致相同,只是在keepalived的配置檔案中需要改以下兩處:

(1)將state由MASTER改為BACKUP

(2)將priority由100改為99

vrrp_instance VI_1 {  
    state BACKUP # 這裡改為BACKUP
    interface eth1  
    virtual_router_id 51  
    priority 99 # 這裡改為99,master優先順序是100
    advert_int 1  
    authentication {  
        auth_type PASS  
        auth_pass 1111  
    }  
    virtual_ipaddress {  
        192.168.80.200  
    }  
}

3.6 驗證性測試

(1)指定請求的均衡轉發:因為兩個Web伺服器的權重都一樣,所以會依次轉發給兩個Web伺服器;

(2)Web伺服器發生故障時:

①A發生故障後,只從B獲取服務;

這裡模擬192.168.80.102發生故障,暫停其http服務:service httpd stop

再來看看這時從外部訪問VIP時,便會只從192.168.80.103獲取網頁:

②A故障修復後,又從A獲取服務;

這裡模擬192.168.80.102修復完成,重啟其http服務:service httpd start

再來看看這時從外部訪問VIP,又可以從192.168.80.102獲取網頁:

(3)主負載均衡伺服器發生故障時,備機立即充當主機角色提供請求轉發服務:

這裡模擬192.168.80.100發生故障,暫停其keepalived服務:service keepalived stop

再來看看這時從外部訪問VIP,還是可以正常獲取網頁:

學習小結

LVS是目前廣為採用的軟體負載均衡解決方案,在一些大型企業級系統及網際網路系統中應用。本次,簡單地瞭解了一下LVS,並在Linux下搭建了一個小小的測試環境,藉助Keepalived實現了一個最小化的負載均衡測試環境。LVS是一個可以工作在網路第四層的負載均衡軟體,因此它相對於Nginx一類工作在第七層的負載均衡軟體有著無可比擬的效能優勢,而且它還是我國的章文嵩博士(現在阿里的副總裁,淘寶的技術專家)作為創始人發起的,現已經成為Linux核心的組成部分。

當然,目前流行的LVS解決方案中,在Web伺服器端也有采用了Nginx+Tomcat這樣的搭配型別,靜態檔案和動態檔案分開進行處理,也不失為一種有效的嘗試。在以後的日子裡,我還會嘗試下在Linux下藉助Jexus跑ASP.NET MVC專案,試試.NET專案在Linux下的執行效果,希望到時也可以做一些分享。好了,今天就到此停筆。

相關文章