天天看點

叢集之LVS(負載均衡)詳解

提高伺服器響應能力的方法

scale on  在原有伺服器的基礎上進行更新或者直接換一台新的性能更高的伺服器。

scale out  橫向擴充,将多台伺服器并發向外響應用戶端的請求。優點:成本低,擴充架構比較簡單。

叢集(Cluster),通俗地講就是按照某種組織方式将幾台電腦組織起來完成某種特定任務的這樣一種架構。

三種叢集類型:

LB,Load Balancing 負載均衡:在一定程度上能夠實作高可用的目的。

HA,High Availability 高可用:實時線上,能夠及時響應用戶端請求,企業應用要求達到

     7*24小時,99.999%時間線上。

HP,High Performance 高性能 提供大量超級運算能力的叢集。

LB 負載均衡架構:

Director(dispatcher):負責接收用戶端請求,并将請求按照某種算法分發到背景真正提供服務的伺服器上。既可以基于硬體(F5)來實作,也可以基于軟體來實作。基于軟體實作的又分為四層交換:基于IP位址和端口号組合起來對服務做重定向(LVS)。七層交換:通常指的是反向代理(proxy),例如:squid。

LVS:Linux Virtual  Server

類似于iptables的架構,在核心中有一段代碼用于實時監聽資料包來源的請求,當資料包到達端口時做一次重定向。這一系列的工作必須在核心中實作。在核心中實作資料包請求處理的代碼叫做ipvs。ipvs僅僅提供了功能架構,還需要自己手動定義是資料對哪個服務的請求,

而這種定義需要通過寫規則來實作,寫規則的工具就稱為ipvsadm。

應用場景

高吞吐量(higher throughput)

備援    (redundancy)

适應性  (adaptability)   

<a href="http://lyp0909.blog.51cto.com/attachment/201104/17/508999_1303015365KF4P.png"></a>

                                LVS負載均衡架構 

Virtual IP(VIP)address:Director用來向用戶端提供服務的IP位址

Real IP (RIP) address:叢集節點(背景真正提供服務的伺服器)所使用的IP位址

Director's IP (DIP) address:Director用來和D/RIP 進行聯系的位址

Client computer's IP (CIP) address:公網IP,用戶端使用的IP。

根據前端Director和背景Real Server的通信方式将LVS分為三類:

Network Address Translation(LVS-NAT)

<a href="http://lyp0909.blog.51cto.com/attachment/201104/17/508999_1303015367qdUb.png"></a>

目标位址轉換 所有用戶端的請求都被Director根據通路請求和算法被定向到背景的Real Server 上。

資料包位址轉換過程:

S:CIP D:VIP-------&gt;Director------&gt;S:CIP D:RIP------&gt;Real Server------&gt;

-----&gt;S:RIP  D:CIP-----&gt;Director-----&gt;S:VIP  D:CIP                                      

Director和Real Server必須在同一個網段中;

一般情況下,RIP是私有位址,隻用于叢集内部節點間通信;

Director 會響應所有的請求在用戶端和Real Server之間,所承擔的負載較大;

所有的Real IP 網關必須指向DIP以響應用戶端請求;

Director可以重映射網絡端口,即前端使用标準端口,後端可以使用非标準端口;

背景的Real Server可以使用任何作業系統;

Director可能會成為系統瓶頸。

Director routing (LVS-DR )

<a href="http://lyp0909.blog.51cto.com/attachment/201104/17/508999_1303015369UhCQ.png"></a>

直接路由 用戶端請求經過Director,Real Server直接回應用戶端

S:CIP D:VIP-----&gt;Director---&gt;S:CIP D:RIP -----&gt; Real Server---&gt; S:VIP D:CIP

Real Server 上必須配置VIP切需要隐藏起來,隻有在響應用戶端請求時才使用VIP作為源位址,除此之外并不使用此VIP。

叢集節點和Director必須在同一個網絡中;

RIP不要求為私有位址;

Director僅處理所有進來的請求;

Real Server 不能以DIP作為網關,而是以公網上的某台路由器作為網關;

Director 不能再使用端口重映射;

大多數作業系統可以被用來作為Real Server,windows除外;

LVS-DR模式可以處理比LVS-NAT更多的請求。

實際生産環境中最常用的一種方式,優點:

RIP 為公網位址,管理者可以遠端連接配接Real Server來檢視工作狀态;

一旦Director 當機,可以通過修改DNS記錄将A記錄指向RIP 繼續向外提供服務;

IP tunneling (LVS-TUN )

<a href="http://lyp0909.blog.51cto.com/attachment/201104/17/508999_1303015371sMbm.png"></a>

與DR的網絡結構一樣,但Director和Real Server可以在不同的網絡當中,可以實作異地容災的功能。DIP-----&gt;VIP 基于隧道來傳輸,在資料包外層額外封裝了S:DIP D :RIP 的位址。

Director和Real Server 必須在同一個實體網絡中;

RIP一定不能是私有位址;

Director隻負責處理進來的資料包;

Real Server直接将資料包傳回給用戶端,是以Real Server預設網關不能是DIP,必須是公網上某個路由器的位址;

Director不能做端口重映射;

隻有支援隧道協定的作業系統才能作為Real Server。

分發時所采用的算法

固定排程算法:按照某種既定的算法,不考慮實時的連接配接數予以配置設定。

Round-robin(RR)輪詢:當新請求到達時候,從服務清單中選擇一個Real Server,将請求重定向給這台Real Server。

Weighted round-robin(WRR)權重輪詢:給每台Real Server配置設定一個權重/位列,權重越大,分到的請求數越多。

Destination hashing (DH)目标散列:來自于同一個IP位址的請求都被重定向到同一台Real Server上(保證目标位址不變)。

Source hashing(SH)源位址散列:Director必須確定響應的資料包必須通過請求資料包所經過的路由器或者防火牆(保證原位址不變)。

動态排程算法:通過檢查伺服器上目前連接配接的活動狀态來重新決定下一步排程方式該如何實作。

Lease Connection (LC) 最少連接配接  哪一個Real Server上的連接配接數少就将下一個連接配接請求定向到那台Real Server上去。 【算法:連接配接數=活動連接配接數*256+非活動連接配接數】

Weight Least-Connection(WLC) 權重最少連接配接  在最少連接配接的基礎上給每台Real Server配置設定一個權重。 【算法:連接配接數=(活動連接配接數*256+非活動連接配接數)÷權重】 一種比較理想的算法。

Shortest Expected Delay (SED)  最短期望延遲 不再考慮非活動連接配接數

             【算法:連接配接數=(活動連接配接數+1) *256 ÷權重】

Never Queue (NQ) 永不排隊算法,對SED的改進,當新請求過來的時候不僅要取決于SED算法所得到的值,還要取決于Real Server上是否有活動連接配接。

Locality-Based Least-Connection  (LBLC) 基于本地狀态的最少連接配接,在DH算法的基礎上還要考慮伺服器上的活動連接配接數。

Locality-Based Least-Connection  with  Replication  Scheduling  (LBLCR) 帶複制的基于本地的最少連接配接  LBLC算法的改進

下面我們就來做一個基于LVS-NAT的負載均衡實驗:

<a href="http://lyp0909.blog.51cto.com/attachment/201104/17/508999_13030153779o5X.png"></a>

實驗環境搭建:

Director :VIP192.168.0.127 橋接  

          DIP192.168.10.1 僅主機

Real Server 1:RIP 192.168.10.2   僅主機   網關指向:192.168.10.1

Real Server 2:RIP 192.168.10.3   僅主機   網關指向:192.168.10.1

Client:192.168.0.1   實體機

每台Real Server上分别安裝有http服務。我們這裡為了示範效果,每個http服務的頁面不同。

Real Server 1

[root@station39 html]# ifconfig eth0 192.168.10.2

[root@station39 html]# route add default gw 192.168.10.1

Real Server 2

[root@station26 html]# ifconfig eth0 192.168.10.3

[root@station26 html]# route add default gw 192.168.10.1

Director :

[root@server27 ~]# ifconfig eth1 192.168.10.1

打開核心路由功能

[root@server27 ~]# echo 1 &gt; /proc/sys/net/ipv4/ip_forward

確定永久有效:

[root@server27 ~]# vim /etc/sysctl.conf

# Controls IP packet forwarding

net.ipv4.ip_forward = 1

[root@server27 ~]# sysctl -p

net.ipv4.conf.default.rp_filter = 1

net.ipv4.conf.default.accept_source_route = 0

kernel.sysrq = 0

kernel.core_uses_pid = 1

net.ipv4.tcp_syncookies = 1

kernel.msgmnb = 65536

kernel.msgmax = 65536

kernel.shmmax = 4294967295

kernel.shmall = 268435456

OK,準備工作已經就緒,下面開始實驗的關鍵步驟:

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

使用步驟:1.定義服務 2 .為服務定義Real Server

[root@server27 ~]# ipvsadm -A -t 192.168.0.127:80 -s rr

[root@server27 ~]# ipvsadm -Ln

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

  -&gt; RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  192.168.0.127:80 rr

[root@server27 ~]# ipvsadm -a -t 192.168.0.127:80 -r 192.168.10.2 -m -w 2

[root@server27 ~]# ipvsadm -a -t 192.168.0.127:80 -r 192.168.10.3 -m -w 5

-g,  --gatewaying      Use gatewaying (direct routing). This is the  default.

-i,   --ipip           Use ipip encapsulation (tunneling).

-m,  --masquerading   Use masquerading  (network  access  transla-tion, or NAT).

PS:在這裡設定的權重對于RR算法來說并沒有什麼意義,我們隻是為後面的實驗而設定的。

  -&gt; 192.168.10.3:80              Masq    5      0          16       

  -&gt; 192.168.10.2:80              Masq    2      0          15  

此時,我們使用實體機通路192.168.0.127就會發現頁面交替變化,這是由RR算法的特性決定的。

我們改變為WRR算法試試:

[root@server27 ~]# ipvsadm -E -t 192.168.0.127:80 -s wrr

TCP  192.168.0.127:80 wrr

  -&gt; 192.168.10.3:80              Masq    5      0          86       

  -&gt; 192.168.10.2:80              Masq    2      0          43

改變為LBLC算法試試:

LBLC:基于本地狀态的最少連接配接,在DH算法的基礎上還要考慮伺服器上的活動連接配接數。

[root@server27 ~]# ipvsadm -E -t 192.168.0.127:80 -s lblc

TCP  192.168.0.127:80 lblc

  -&gt; 192.168.10.3:80              Masq    5      0          112      

  -&gt; 192.168.10.2:80              Masq    2      0          41    

此時無論用戶端怎麼重新整理,通路頁面都不會改變。

儲存規則:

ipvsadm -S &gt;&gt;/etc/sysconfig/ipvs-config  ==  ipvsadm-save

ipvsadm -R &lt; /etc/sysconfig/ipvs-config == ipvsadm-restore

PS:Director分發到Real Server的過程中,資料包的源位址和目标位址都沒有發生改變,Director僅僅是将目标mac位址轉換成某台Real Server的mac位址,源mac位址改為Director内網網卡的mac位址。

兩個技術難題

1  Real Server要避免對用戶端發來的對VIP的arp位址解析請求;

   解決方法

1)  修改核心的兩個參數:arp_announce, arp_ignore。

arp_announce :定義不同級别:當ARP請求通過某個端口進來是否利用這個接口來回應。

         0 - (default) Use any local address, configured on any interface.

          利用本地的任何位址,不管配置在哪個接口上去響應ARP請求;

         1 - Try to avoid local addresses that are not in the target's subnet for this interface.

           避免使用另外一個接口上的mac位址去響應ARP請求;

         2 - Always use the best local address for this target.

           盡可能使用能夠比對到ARP請求的最佳位址。

arp_ignore:當ARP請求發過來後發現自己正是請求的位址是否響應;

     0 - (default): reply for any local target IP address, configured on any interface

       利用本地的任何位址,不管配置在哪個接口上去響應ARP請求;

     1 - reply only if the target IP address is local address configured on the incoming   

       interface.

      哪個接口上接受ARP請求,就從哪個端口上回應。

PS:對linux來說IP位址屬于系統而不屬于某個接口。

2)  Red Hat 提供了arptables工具,利用arp防火牆也可以實作。

2  當Real Server内網網卡響應用戶端請求時,要以VIP作為源位址,不能以RIP作為源位址。

解決方法

添加一條路由:route add -host 192.168.0.127 dev lo:0使用戶端通路VIP,就讓VIP來響應用戶端。這樣避免了使用RIP作為源位址。

Director:VIP:響應用戶端請求;

         DIP:與RIP彼此間實作arp解析,并将用戶端的請求轉發給Real Server。

<a href="http://lyp0909.blog.51cto.com/attachment/201104/17/508999_1303015380WWQi.png"></a>

Director :eth0:0  VIP192.168.0.127  

          eth0    DIP192.168.0.10 橋接

Real Server 1: eth0  RIP 192.168.0.12   橋接

              lo:0  VIP 192.168.0.127 

Real Server 2: eth0  RIP 192.168.0.13   橋接

              lo:0  VIP 192.168.0.127

[root@station39 ~]# vim /etc/sysctl.conf

net.ipv4.conf.lo.arp_ignore = 1

net.ipv4.conf.all.arp_ignore = 1

net.ipv4.conf.lo.arp_announce = 2

net.ipv4.conf.all.arp_announce = 2

[root@station39 ~]# sysctl -p

[root@station39 ~]# ifconfig eth0 192.168.0.12/24

[root@station39 ~]# ifconfig lo:0 192.168.0.127 broadcast 192.168.0.127 netmask  255.255.255.255

[root@station39 ~]# route add -host 192.168.0.127 dev lo:0

[root@station26 ~]# vim /etc/sysctl.conf

[root@station26 ~]# sysctl -p

[root@station26 ~]# ifconfig eth0 192.168.0.13/24

[root@station26 ~]# ifconfig lo:0 192.168.0.127 broadcast 192.168.0.127 netmask  255.255.255.255

[root@station26 ~]# route add -host 192.168.0.127 dev lo:0

Director

[root@server27 ~]# ifconfig eth0 192.168.0.10/24

[root@server27 ~]# ifconfig eth0:0 192.168.0.127 broadcast 192.168.0.127 netmask 255.255.255.255

[root@server27 ~]# route add -host 192.168.0.127 dev eth0:0

[root@server27 ~]# ipvsadm -C

[root@server27 ~]# ipvsadm -A -t 192.168.0.127:80 -s wlc

[root@server27 ~]# ipvsadm -a -t 192.168.0.127:80 -r 192.168.0.12 -g -w 5

[root@server27 ~]# ipvsadm -a -t 192.168.0.127:80 -r 192.168.0.13 -g -w 8

TCP  192.168.0.127:80 wlc

  -&gt; 192.168.0.13:80              Route   8      0          18       

  -&gt; 192.168.0.12:80              Route   5      0          11

PS:如果要保持通路的頁面一緻,我們可以另外準備一台伺服器專門用來存放網頁檔案,然後通過NFS共享的方式挂載到Real Server的網頁目錄下,就可以實作真正的負載均衡了。

實作持久連接配接:

[root@server27 ~]# ipvsadm -E -t 192.168.0.127:80 -s wlc -p 3600

TCP  192.168.0.127:80 wlc persistent 3600

  -&gt; 192.168.0.13:80              Route   8      0          62       

  -&gt; 192.168.0.12:80              Route   5      0          0

此時,你會發現無論通路頁面怎麼重新整理都不會再改變,這就是LVS持久性。

LVS  Persistence 持久性

盡管我們選擇了LVS的分發方法,但是大多時候我們要保證傳回給用戶端的所有響應請求必須來自于同一台Real Server,這裡我們就要用到LVS Persistence(持久性)。

當使用SSL會話的時候,我們常常期望隻交換一次密鑰就可以建立永久連接配接,是以,LVS持久性在SSL會話中經常被用到。

當使用LVS持久性的時候,Director在内部使用一個連接配接根據記錄稱之為“持久連接配接模闆”來確定所有來自同一個用戶端的請求被分發到同一台Real Server上。

LVS 持久性類型:PCC  PPC  PNMP  混合類型。

Persistent client connections (PCC), cause all services a client is accessing to persist. (Also called zero port connections.)

來自同一用戶端所有服務的請求都被重定向到同一台Real Server上,以IP位址為準。

PCC是一個虛拟服務沒有端口号(或者端口号為0),以"-p" 來辨別服務。

缺陷:定向所有服務,期望通路不同的Real Server無法實作。

假設一個使用者在通路購物網站時同時使用HTTP(80)和HTTPS(443)兩種協定,就需要這樣定義:

ipvsadm -A  -t  192.168.0.220:0 -s rr -p

ipvsadm -a  -t  192.168.0.220.3:0 -r 192.168.10.11 -m

ipvsadm -a  -t  192.168.0.220:0 -r 192.168.10.11 -m

Persistent port connections (PPC), which cause a single service to persist.

來自同一服務的請求都被重定向到同一台Real Server上,以端口号為準。

例如:client----&gt;LVS(80,22)------&gt;RS1   client-----&gt;LVS(23)-----&gt;RS2

缺陷:期望通路不同的端口到同一台RS上,無法實作。

Persistent Netfilter Marked Packet persistence, which causes packets that have been marked with the iptables utility to persist.

根據iptables 的規則,将對于某類服務/幾個不同端口的通路定義為一類。

先對某一特定類型的資料包打上标記,然後再将基于某一類标記的服務送到背景的Real Server上去,背景的Real Server 并不識别這些标記。

PS:在LVS-NAT的環境下做這個實驗,由于前邊的DR模型使用了網卡别名,是以并不适合這個實驗。

[root@server27 ~]# iptables -t mangle -A PREROUTING -i eth0 -d 192.168.0.127 -p tcp --dport 80 -j MARK --set-mark 2

[root@server27 ~]#  ipvsadm -A -f 2 -s wlc -p 3600

[root@server27 ~]# ipvsadm -a -f 2 -r 192.168.10.2 -m -w 2

[root@server27 ~]# ipvsadm -a -f 2 -r 192.168.10.3 -m -w 5

<a href="http://lyp0909.blog.51cto.com/attachment/201104/17/508999_13030153869tK5.png"></a>

将持久和防火牆标記結合起來就能夠實作端口姻親功能,隻要是來自某一用戶端的對某一特定服務(需要不同的端口)的通路都定義到同一台Real Server上去。

假設這樣一種場景:一個使用者在通路購物網站時同時使用HTTP(80)和HTTPS(443)兩種協定,我們需要将其定義到同一台Real Server上,而其他的服務不受限制,我們可以這樣做:

實驗基于LVS-NAT的環境。

先做一個自簽名的證書

Real Server 1:

[root@station39 ~]# cd /etc/pki/tls/certs/

[root@station39 certs]# make httpd.pem

<a href="http://lyp0909.blog.51cto.com/attachment/201104/17/508999_1303015389aUFN.png"></a>

[root@station39 certs]# mv httpd.pem /etc/httpd/

[root@station39 httpd]# yum install mod_ssl -y

[root@station39 httpd]# cd conf.d/

[root@station39 conf.d]# vim ssl.conf

SSLCertificateFile /etc/httpd/httpd.pem   //** line 112

SSLCertificateKeyFile /etc/httpd/httpd.pem   //** line 119

重新開機httpd 服務。

[root@station39 ~]# vim /etc/hosts

192.168.10.2    web1.a.com              web1

Real Server 2 :

[root@station26 ~]# yum install mod_ssl -y

[root@station26 certs]# cd /etc/httpd

[root@station26 httpd]# make -C /etc/pki/tls/certs httpd.pem

<a href="http://lyp0909.blog.51cto.com/attachment/201104/17/508999_1303015391c6bI.png"></a>

[root@station26 httpd]# mv /etc/pki/tls/certs/httpd.pem ./

[root@station26 httpd]# cd conf.d/

[root@station26 conf.d]# vim ssl.conf

[root@station26 ~]# vim /etc/hosts

192.168.10.3    web2.a.com              web2

Director:

[root@server27 ~]# iptables -t mangle -A PREROUTING -i eth0 -d 192.168.0.127 -p tcp --dport 80 -j MARK --set-mark 5

[root@server27 ~]# iptables -t mangle -A PREROUTING -i eth0 -d 192.168.0.127 -p tcp --dport 443 -j MARK --set-mark 5

[root@server27 ~]# ipvsadm -A -f 5 -s wlc -p

[root@server27 ~]# ipvsadm -a -f 5 -r 192.168.10.2 -m -w 2

[root@server27 ~]# ipvsadm -a -f 5 -r 192.168.10.3 -m -w 5

<a href="http://lyp0909.blog.51cto.com/attachment/201104/17/508999_1303015392GDh7.png"></a>

OK,修改windows用戶端的C:\WINDOWS\system32\drivers\etc\hosts 檔案,添加兩條名稱解析記錄:

192.168.0.127 web1.a.com

192.168.0.127 web2.a.com

此時實體機通路192.168.0.127無論是http還是https 服務都會被定義到同一台Real Server上去。

<a href="http://lyp0909.blog.51cto.com/attachment/201104/17/508999_13030153948XrW.png"></a>

這裡我們是為了示範實驗的效果,使用的不同的證書,不同的頁面。真實的生産環境中要求這些必須是一緻的。

FTP connections (FTP connections require careful handling due to the complex nature of FTP connections).

PS:指定一個範圍,将範圍内的端口打上标記。然後使VSFTPD在被動模式下不再使用随機端口,而是使用範圍内的随機端口,進而實作FTP的負載均衡。

1 Limiting the port range for passive connections, you must also configure the VSFTP server to use a matching port range:

vim  /etc/vsftpd.conf:

pasv_min_port=10000

pasv_max_port=20000

2 You must also control the address that the server displays to the client for passive FTP connections. In a NAT routed LVS system, add the following line to /etc/vsftpd.conf to override the real server IP address to the VIP, which is what the client sees upon connection. For example:

pasv_address=n.n.n.n

3 iptables定義端口姻親:

iptables -t mangle -A PREROUTING -p tcp -d n.n.n.n/32 --dport 21 -j MARK --set-mark 21

iptables -t mangle -A PREROUTING -p tcp -d n.n.n.n/32 --dport 10000:20000 -j MARK --set-mark 21

Expired persistence, which is used internally by the Director to expire connection tracking entries when the persistent connection template expires.

本文轉自 490999122 51CTO部落格,原文連結:http://blog.51cto.com/lyp0909/546865,如需轉載請自行聯系原作者

繼續閱讀