天天看點

Lvs之NAT、DR、TUN三種模式的應用配置案例

LVS

一、LVS簡介

    LVS是Linux Virtual Server的簡寫,意即Linux虛拟伺服器,是一個虛拟伺服器叢集系統。本項目在1998年5月由章文嵩博士成立,是中國國内最早出現的自由軟體之一。

二、LVS的分類

LVS-NAT:位址轉換

LVS-DR: 直接路由

LVS-TUN:隧道

三、ipvsadm用法

其實LVS的本身跟iptables很相似,而且連指令的使用格式都很相似,其實LVS是根據iptables的架構開發的,那麼LVS的本身分成了兩個部分,第一部分是工作在核心空間的一個IPVS的子產品,其實LVS的功能都是IPVS子產品實作的,,第二部分是工作在使用者空間的一個用來定義叢集服務的一個工具ipvsadm, 這個工具的主要作用是将管理者定義的叢集服務清單傳送給工作在核心空間中的IPVS子產品,下面來簡單的介紹下ipvsadm指令的用法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

<code>ipvsadm元件定義規則的格式:</code>

<code>1.定義叢集服務格式:</code>

<code>(1).添加叢集服務:</code>

<code>ipvsadm -A|E -t|u|f service-address [-s scheduler]</code>

<code>              </code><code>[-p [timeout]] [-M netmask]</code>

<code>-A:                  表示添加一個新的叢集服務</code>

<code>-E:                  編輯一個叢集服務</code>

<code>-t:                  表示tcp協定</code>

<code>-u:                  表示udp協定</code>

<code>-f:                  表示firewall-Mark,防火牆标記</code>

<code>service-address:     叢集服務的IP位址,即VIP</code>

<code>-s                    指定排程算法</code>

<code>-p                    持久連接配接時長,如</code><code>#ipvsadm -Lcn ,檢視持久連接配接狀态</code>

<code>-M                    定義掩碼</code>

<code>ipvsadm -D -t|u|f service-address      删除一個叢集服務</code>

<code>ipvsadm -C                             清空所有的規則</code>

<code>ipvsadm -R                             重新載入規則</code>

<code>ipvsadm -S [-n]                        儲存規則</code>

<code>2.向叢集服務添加RealServer規則:</code>

<code>(1).添加RealServer規則</code>

<code>ipvsadm -a|e -t|u|f service-address -r server-address</code>

<code>              </code><code>[-g|i|m] [-w weight]</code>

<code>-a                 添加一個新的realserver規則</code>

<code>-e                 編輯realserver規則</code>

<code>-t                 tcp協定</code>

<code>-u                 udp協定</code>

<code>-f                 firewall-Mark,防火牆标記</code>

<code>service-address    realserver的IP位址</code>

<code>-g                 表示定義為LVS-DR模型</code>

<code>-i                 表示定義為LVS-TUN模型</code>

<code>-m                 表示定義為LVS-NAT模型</code>

<code>-w                 定義權重,後面跟具體的權值</code>

<code>ipvsadm -d -t|u|f service-address -r server-address          --删除一個realserver</code>

<code>ipvsadm -L|l [options]                                       --檢視定義的規則</code>

<code>如:</code><code>#ipvsadm -L -n  </code>

<code>ipvsadm -Z [-t|u|f service-address]                          --清空計數器</code>

四、lvs的10種排程算法

可以分為兩大類

<code>LVS Scheduling Method LVS的排程方法:</code>

<code>1.Fixed Scheduling Method  靜态調服方法</code>

<code>(1).RR     輪詢</code>

<code>(2).WRR    權重輪詢</code>

<code>(3).DH     目标位址</code><code>hash</code>

<code>(4).SH     源位址</code><code>hash</code>

<code>2.Dynamic Scheduling Method 動态調服方法</code>

<code>(1).LC     最少連接配接</code>

<code>(2).WLC    權重最少連接配接</code>

<code>(3).SED    最少期望延遲</code>

<code>(4).NQ     從不排隊排程方法</code>

<code>(5).LBLC   基于本地的最少連接配接</code>

<code>(6).LBLCR  帶複制的基于本地的最少連接配接</code>

LVS-NAT

一、架構平台環境

<code>系統平台:CentOS 6.4 64bit 核心:2.6.32</code>

<code>相關服務和專有名詞定義</code>

<code>Director:負責排程叢集的主機;也簡稱排程器、分發器</code>

<code>VIP:Virtual IP 向外提供服務的IP;通常此IP綁定域名</code>

<code>DIP:與内部主機RIP通信的IP,在Director主機上</code>

<code>RIP:RealServer IP;内部真正提供服務的主機</code>

<code>CIP:用戶端IP</code>

二、LVS-NAT架構

<a href="http://s3.51cto.com/wyfs02/M01/48/BA/wKioL1QLF4zxkkT8AAXJtlkKfIc596.jpg" target="_blank"></a>

三、LVS-NAT模型實作負載均衡的工作方式

NAT模型其實就是通過網絡位址轉換來實作負載均衡的,它的工作方式幾乎跟DNAT一模一樣的,目前的DNAT隻能轉發到一個目标位址,早期的DNAT是可以将請求轉發到多個目标的,在LVS出現之後就将此功能從DNAT種去掉了,下面來說說NAT模型的工作方式或者說NAT模型是怎麼實作負載均衡的,根據上圖,

1.使用者請求VIP(也可以說是CIP請求VIP)

2,Director Server 收到使用者的請求後,發現源位址為CIP請求的目标位址為VIP,那麼Director Server會認為使用者請求的是一個叢集服務,那麼Director Server 會根據此前設定好的排程算法将使用者請求負載給某台Real Server ;假如說此時Director Server 根據排程算法的結果會将請求分攤到RealServer1上去,那麼Director Server 會将使用者的請求封包中的目标位址,從原來的VIP改為RealServer1的IP,然後再轉發給RealServer1

3,此時RealServer1收到一個源位址為CIP目标位址為自己的請求,那麼RealServer1處理好請求後會将一個源位址為自己目标位址為CIP的資料包通過Director Server 發出去,

4.當Driector Server收到一個源位址為RealServer1 的IP 目标位址為CIP的資料包,此時Driector Server 會将源位址修改為VIP,然後再将資料包發送給使用者,

四、LVS-NAT的性能瓶頸

在LVS/NAT的叢集系統中,請求和響應的資料封包都需要通過負載排程器(Director),當真實伺服器(RealServer)的數目在10台和20台之間時,負載排程器(Director)将成為整個叢集系統的新瓶頸。大多數Internet服務都有這樣的特點:請求封包較短而響應封包往往包含大量的資料。如果能将請求和響應分開處理,即在負載排程器(Director)中隻負責排程請求而響應直接(RealServer)傳回給客戶,将極大地提高整個叢集系統的吞吐量。

五、部署環境

1、準備工作

<code>(1)關閉所有節點的iptables和selinux服務</code>

<code>setenforce 0</code>

<code>service iptables stop &amp;&amp; chkconfig iptables off</code>

<code>(2)HA中所有節點盡可能保證時間是一緻的,方法是時間同步+任務計劃同步時間;</code>

<code>注意:對于LB來說時間的影響不是很大,但是對于HP來說各節點之間的時間偏差不應該超出一秒鐘:</code>

<code>ntpdate -u asia.pool.ntp.org</code>

2、拓撲圖位址規劃

<code>LVS Director機器:</code>

<code>公網位址:vip</code>

<code>主機名:lvs</code>

<code>vip位址: 192.168.0.200</code>

<code>子網路遮罩:255.255.255.0</code>

<code>網關:    192.168.0.1 </code>

<code>網絡連接配接方式:Bridge</code>

<code>私網位址:dip</code>

<code>dip位址: 172.16.100.1</code>

<code>子網路遮罩:255.255.0.0</code>

<code>網關:    不指定網關</code>

<code>網絡連接配接方式:Host-Only</code>

<code>RealServer機器:</code>

<code>私網位址:rip1</code>

<code>主機名:web1</code>

<code>rip1位址:172.16.100.10 </code>

<code>子網路遮罩:255.255.0.0   </code>

<code>網關:    172.16.100.1 </code>

<code>私網位址:rip2</code>

<code>主機名:web2</code>

<code>rip1位址:172.16.100.11</code>

3、在RealServer上部署httpd服務并測試

<code>安裝httpd服務,建立httpd測試頁面,啟動httpd服務</code>

<code>[root@web1 ~]</code><code># yum -y install httpd</code>

<code>[root@web1 ~]</code><code># service httpd start</code>

<code>[root@web1 ~]</code><code># echo "RS1-web1 Allentuns.com" &gt; /var/www/html/index.html</code>

<code>[root@web2 ~]</code><code># yum -y install httpd</code>

<code>[root@web2 ~]</code><code># echo "RS2-web2 Allentuns.com" &gt; /var/www/html/index.html</code>

<code>[root@web2 ~]</code><code># service httpd start</code>

<code>測試httpd服務是否OK!</code>

<code>[root@web1 ~]</code><code># curl http://localhost</code>

<code>RS1-web1 Allentuns.com</code>

<code>[root@web1 ~]</code><code># curl http://172.16.100.11</code>

<code>RS2-web2 Allentuns.com</code>

4、在Director上部署ipvs服務并測試

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

<code>(1)确定本機ip_vs子產品是否加載,也就是是否支援lvs,2.4.2後都支援了;然後安裝ipvsadm 使用者操作指令</code>

<code>[root@LVS ~]</code><code># grep -i "ip_vs" /boot/config-2.6.32-358.el6.x86_64 </code>

<code>CONFIG_IP_VS=m   </code><code>#将ipvs定義成子產品</code>

<code>CONFIG_IP_VS_IPV6=y</code>

<code># CONFIG_IP_VS_DEBUG is not set</code>

<code>CONFIG_IP_VS_TAB_BITS=12</code>

<code>CONFIG_IP_VS_PROTO_TCP=y  </code><code>#IPVS支援哪些叢集服務</code>

<code>CONFIG_IP_VS_PROTO_UDP=y</code>

<code>CONFIG_IP_VS_PROTO_AH_ESP=y</code>

<code>CONFIG_IP_VS_PROTO_ESP=y</code>

<code>CONFIG_IP_VS_PROTO_AH=y</code>

<code>CONFIG_IP_VS_PROTO_SCTP=y</code>

<code>CONFIG_IP_VS_RR=m   </code><code>#ipvs支援的十種排程算法</code>

<code>CONFIG_IP_VS_WRR=m</code>

<code>CONFIG_IP_VS_LC=m</code>

<code>CONFIG_IP_VS_WLC=m</code>

<code>CONFIG_IP_VS_LBLC=m</code>

<code>CONFIG_IP_VS_LBLCR=m</code>

<code>CONFIG_IP_VS_DH=m</code>

<code>CONFIG_IP_VS_SH=m</code>

<code>CONFIG_IP_VS_SED=m</code>

<code>CONFIG_IP_VS_NQ=m</code>

<code>CONFIG_IP_VS_FTP=m  </code><code>#支援代理ftp協定的</code>

<code>(2)安裝ipvsadm</code>

<code>[root@LVS ~]</code><code># yum -y install ipvsadm</code>

<code>(3)添加叢集服務</code>

<code>[root@LVS ~]</code><code># ipvsadm -A -t 192.168.0.200:80 -s rr               #定義一個叢集服務</code>

<code>[root@LVS ~]</code><code># ipvsadm -a -t 192.168.0.200:80 -r 172.16.100.10 -m  #添加RealServer并指派排程算法為NAT</code>

<code>[root@LVS ~]</code><code># ipvsadm -a -t 192.168.0.200:80 -r 172.16.100.11 -m  #添加RealServer并指派排程算法為NAT</code>

<code>[root@LVS ~]</code><code># ipvsadm -L -n                                     #檢視ipvs定義的規則清單</code>

<code>IP Virtual Server version 1.2.1 (size=4096)</code>

<code>Prot LocalAddress:Port Scheduler Flags</code>

<code>  </code><code>-&gt; RemoteAddress:Port           Forward Weight ActiveConn InActConn</code>

<code>TCP  192.168.0.200:80 rr</code>

<code>  </code><code>-&gt; 172.16.100.10:80             Masq    1      0          0         </code>

<code>  </code><code>-&gt; 172.16.100.11:80             Masq    1      0          0   </code>

<code>[root@LVS ~]</code><code># cat /proc/sys/net/ipv4/ip_forward                    #檢視Linux是否開啟路由轉發功能</code>

<code>0</code>

<code>[root@LVS ~]</code><code># echo 1 &gt; /proc/sys/net/ipv4/ip_forward               #啟動Linux的路由轉發功能</code>

<code>[root@LVS ~]</code><code># cat /proc/sys/net/ipv4/ip_forward </code>

<code>1</code>

<code>(4)測試通路http頁面</code>

<code>[root@LVS ~]</code><code># curl http://192.168.0.200/index.html</code>

<code>RS2-web2 Allentuns.com  </code><code>#第一次是web2</code>

<code>RS1-web1 Allentuns.com  </code><code>#第二次是web1</code>

<code>RS2-web2 Allentuns.com  </code><code>#第三次是web1</code>

<code>RS1-web1 Allentuns.com  </code><code>#第四次是web2</code>

<code>(5)更改LVS的排程算并壓力測試,檢視結果</code>

<code>[root@LVS ~]</code><code># ipvsadm -E -t 192.168.0.200:80 -s wrr</code>

<code>[root@LVS ~]</code><code># ipvsadm -e -t 192.168.0.200:80 -r 172.16.100.10 -m -w 3</code>

<code>[root@LVS ~]</code><code># ipvsadm -e -t 192.168.0.200:80 -r 172.16.100.11 -m -w 1</code>

<code>[root@LVS ~]</code><code># ipvsadm -L -n</code>

<code>TCP  192.168.0.200:80 wrr</code>

<code>  </code><code>-&gt; 172.16.100.10:80             Masq    3      0          2         </code>

<code>  </code><code>-&gt; 172.16.100.11:80             Masq    1      0          2  </code>

<code>  </code> 

<code>RS1-web1 Allentuns.com </code>

<code>(6)永久儲存LVS規則并恢複</code>

<code>第一種方法:</code>

<code>[root@LVS ~]</code><code># service ipvsadm save</code>

<code>ipvsadm: Saving IPVS table to </code><code>/etc/sysconfig/ipvsadm</code><code>:      [确定]</code>

<code>第二種方法:</code>

<code>[root@LVS ~]</code><code># ipvsadm -S &gt; /etc/sysconfig/ipvsadm.s1</code>

<code>模拟清空ipvsadm規則來恢複</code>

<code>[root@LVS ~]</code><code># ipvsadm -C</code>

<code>[root@LVS ~]</code><code># ipvsadm -R &lt; /etc/sysconfig/ipvsadm.s1 </code>

<code>  </code><code>-&gt; 172.16.100.10:80             Masq    3      0          0         </code>

<code>  </code><code>-&gt; 172.16.100.11:80             Masq    1      0          0</code>

六、LVS-NAT服務控制腳本部署在Director上

<code>#!/bin/bash</code>

<code>#</code>

<code># chkconfig: - 88 12</code>

<code># description: LVS script for VS/NAT</code>

<code>. </code><code>/etc/rc</code><code>.d</code><code>/init</code><code>.d</code><code>/functions</code>

<code>VIP=192.168.0.200</code>

<code>DIP=172.16.100.1</code>

<code>RIP1=172.16.100.10</code>

<code>RIP2=172.16.100.11</code>

<code>case</code> <code>"$1"</code> <code>in</code>

<code>start)           </code>

<code># /sbin/ifconfig eth1:0 $VIP netmask 255.255.255.0 up</code>

<code># Since this is the Director we must be able to forward packets</code>

<code>  </code><code>echo</code> <code>1 &gt; </code><code>/proc/sys/net/ipv4/ip_forward</code>

<code># Clear all iptables rules.</code>

<code>  </code><code>/sbin/iptables</code> <code>-F</code>

<code># Reset iptables counters.</code>

<code>  </code><code>/sbin/iptables</code> <code>-Z</code>

<code># Clear all ipvsadm rules/services.</code>

<code>  </code><code>/sbin/ipvsadm</code> <code>-C</code>

<code># Add an IP virtual service for VIP 192.168.0.219 port 80</code>

<code># In this recipe, we will use the round-robin scheduling method. </code>

<code># In production, however, you should use a weighted, dynamic scheduling method. </code>

<code>  </code><code>/sbin/ipvsadm</code> <code>-A -t $VIP:80 -s rr</code>

<code># Now direct packets for this VIP to</code>

<code># the real server IP (RIP) inside the cluster</code>

<code>  </code><code>/sbin/ipvsadm</code> <code>-a -t $VIP:80 -r $RIP1 -m</code>

<code>  </code><code>/sbin/ipvsadm</code> <code>-a -t $VIP:80 -r $RIP2 -m</code>

<code>  </code><code>/bin/touch</code> <code>/var/lock/subsys/ipvsadm</code><code>.lock</code>

<code>;;</code>

<code>stop)</code>

<code># Stop forwarding packets</code>

<code>  </code><code>echo</code> <code>0 &gt; </code><code>/proc/sys/net/ipv4/ip_forward</code>

<code># Reset ipvsadm</code>

<code># Bring down the VIP interface</code>

<code>  </code><code>ifconfig</code> <code>eth1:0 down</code>

<code>  </code><code>rm</code> <code>-rf </code><code>/var/lock/subsys/ipvsadm</code><code>.lock</code>

<code>status)</code>

<code>  </code><code>[ -e </code><code>/var/lock/subsys/ipvsadm</code><code>.lock ] &amp;&amp; </code><code>echo</code> <code>"ipvs is running..."</code> <code>|| </code><code>echo</code> <code>"ipvsadm is stopped..."</code>

<code>*)</code>

<code>  </code><code>echo</code> <code>"Usage: $0 {start|stop}"</code>

<code>esac</code>

七、分享LVS-NAT一鍵安裝腳本

<code># 一鍵安裝lvs-nat腳本,需要注意的是主機名成和ip的變化稍作修改就可以了 </code>

<code>HOSTNAME=`</code><code>hostname</code><code>`</code>

<code>Director=</code><code>'LVS'</code>

<code>VIP=</code><code>"192.168.0.200"</code>

<code>RIP1=</code><code>"172.16.100.10"</code>

<code>RIP2=</code><code>"172.16.100.11"</code>

<code>RealServer1=</code><code>"web1"</code>

<code>RealServer2=</code><code>"web2"</code>

<code>Httpd_config=</code><code>"/etc/httpd/conf/httpd.conf"</code>

<code>#Director Server Install configure ipvsadm</code>

<code>if</code> <code>[ </code><code>"$HOSTNAME"</code> <code>= </code><code>"$Director"</code> <code>];</code><code>then</code>

<code>ipvsadm -C</code>

<code>yum -y remove ipvsadm</code>

<code>yum -y </code><code>install</code> <code>ipvsadm</code>

<code>/sbin/ipvsadm</code> <code>-A -t $VIP:80 -s rr</code>

<code>/sbin/ipvsadm</code> <code>-a -t $VIP:80 -r $RIP1 -m</code>

<code>/sbin/ipvsadm</code> <code>-a -t $VIP:80 -r $RIP2 -m</code>

<code>echo</code> <code>1 &gt; </code><code>/proc/sys/net/ipv4/ip_forward</code>

<code>echo</code> <code>"========================================================"</code>

<code>echo</code> <code>"Install  $Director sucess   Tel:13260071987 Qq:467754239"</code>

<code>fi</code>

<code>#RealServer Install htpd</code>

<code>if</code> <code>[ </code><code>"$HOSTNAME"</code> <code>= </code><code>"$RealServer1"</code> <code>];</code><code>then</code>

<code>yum -y remove httpd</code>

<code>rm</code> <code>-rf </code><code>/var/www/html/index</code><code>.html</code>

<code>yum -y </code><code>install</code> <code>httpd</code>

<code>echo</code> <code>"web1 Allentuns.com"</code> <code>&gt; </code><code>/var/www/html/index</code><code>.html</code>

<code>sed</code> <code>-i </code><code>'/#ServerName www.example.com:80/a\ServerName localhost:80'</code> <code>$Httpd_config</code>

<code>service httpd start</code>

<code>echo</code> <code>"Install $RealServer1 success Tel:13260071987 Qq:467754239"</code>

<code>if</code> <code>[ </code><code>"$HOSTNAME"</code> <code>= </code><code>"$RealServer2"</code> <code>];</code><code>then</code>

<code>echo</code> <code>"web2 Allentuns.com"</code> <code>&gt; </code><code>/var/www/html/index</code><code>.html</code>

<code>echo</code> <code>"Install $RealServer2"</code>

<code>echo</code> <code>"========================================================="</code>

LVS-DR

一、LVS-DR架構

<a href="http://s3.51cto.com/wyfs02/M02/48/BE/wKioL1QLQFziBAF-AAYp7vxkqd0554.jpg" target="_blank"></a>

二、DR模型實作負載均衡的工作方式,

         上面說了NAT模型的實作方式,那麼NAT模型有個缺陷,因為進出的每個資料包都要經過Director Server,當叢集系統負載過大的時候Director Server将會成為整個叢集系統的瓶頸,那麼DR模型就避免了這樣的情況發生,DR模型在隻有請求的時候才會經過Director Server, 回應的資料包由Real Server 直接響應使用者不需要經過Director Server,其實三種模型中最常用的也就是DR模型了,下面來說DR模型具體是怎麼實作負載均衡的,根據上圖,

1, 首先使用者用CIP請求VIP, 

2, 根據上圖可以看到,不管是Director Server還是Real Server上都需要配置VIP,那麼當使用者請求到達我們的叢集網絡的前端路由器的時候,請求資料包的源位址為CIP目标位址為VIP,此時路由器會發廣播問誰是VIP,那麼我們叢集中所有的節點都配置有VIP,此時誰先響應路由器那麼路由器就會将使用者請求發給誰,這樣一來我們的叢集系統是不是沒有意義了,那我們可以在網關路由器上配置靜态路由指定VIP就是Director Server,或者使用一種機制不讓Real Server 接收來自網絡中的ARP位址解析請求,這樣一來使用者的請求資料包都會經過Director Servre,

3,當Director Server收到使用者的請求後根據此前設定好的排程算法結果來确定将請求負載到某台Real Server上去,假如說此時根據排程算法的結果,會将請求負載到Real Server 1上面去,此時Director Server 會将資料幀中的目标MAC位址修改為Real Server1的MAC位址,然後再将資料幀發送出去,

4,當Real Server1 收到一個源位址為CIP目标位址為VIP的資料包時,Real Server1發現目标位址為VIP,而VIP是自己,于是接受資料包并給予處理,當Real Server1處理完請求後,會将一個源位址為VIP目标位址為CIP的資料包發出去,此時的響應請求就不會再經過Director Server了,而是直接響應給使用者

<code>編輯DR有三種方式</code>

<code>第一種方式:在路由器上明顯說明vip對應的位址一定是Director上的MAC,隻要綁定,以後再跟vip通信也不用再請求了,這個綁定是靜态的,是以它也不會失效,也不會再次發起請求,但是有個前提,我們的路由裝置必須有操作權限能夠綁定MAC位址,萬一這個路由器是運作商操作的,我們沒法操作怎麼辦?第一種方式固然很簡便,但未必可行。</code>

<code>第二種方式:在給别主機上(例如:紅帽)它們引進的有一種程式arptables,它有點類似于iptables,它肯定是基于arp或基于MAC做通路控制的,很顯然我們隻需要在每一個real server上定義arptables規則,如果使用者arp廣播請求的目标位址是本機的vip則不予相應,或者說相應的封包不讓出去,很顯然網關(gateway)是接受不到的,也就是director相應的封包才能到達gateway,這個也行。第二種方式我們可以基于arptables。</code>

<code>第三種方式:在相對較新的版本中新增了兩個核心參數(kernelparameter),第一個是arp_ignore定義接受到ARP請求時的相應級别;第二個是arp_announce定義将自己位址向外通告是的通告級别。【提示:很顯然我們現在的系統一般在核心中都是支援這些參數的,我們用參數的方式進行調整更具有樸實性,它還不依賴于額外的條件,像arptables,也不依賴外在路由配置的設定,反而通常我們使用的是第三種配置】</code>

<code>arp_ignore:定義接受到ARP請求時的相應級别</code>

<code>0:隻要本地配置的有相應位址,就給予響應。</code>

<code>1:僅在請求的目标位址配置請求到達的接口上的時候,才給予響應</code>

<code>2:隻回答目标IP位址是來訪網絡接口本地位址的ARP查詢請求,且來訪IP必須在該網絡接口的子網段内</code>

<code>3:不回應該網絡界面的arp請求,而隻對設定的唯一和連接配接位址做出回應</code>

<code>4-7:保留未使用</code>

<code>8:不回應所有(本地位址)的arp查詢</code>

<code>     </code> 

<code>arp_ignore </code>

<code>設定為1,當别人的arp請求過來的時候,如果接收的裝置上面沒有這個ip,就不響應,預設是0,隻要這台機器上面任何一個裝置上面有這個ip,就響應arp請求,并發送MAC位址應答。</code>

<code>arp_announce:定義将自己位址向外通告是的通告級别;</code>

<code>0: 将本地任何接口上的任何位址向外通告</code>

<code>1:試圖僅想目标網絡通告與其網絡比對的位址</code>

<code>2:僅向與本地借口上位址比對的網絡進行通告</code>

<code>所有的Director和RealServer都在同一個實體網絡中(交換機)并且都隻有一塊網卡,交換機前面有個路由器,這個路由器可能是我們機房内部的,也有可能是網絡運作商的。</code>

<code>當用戶端的請求被送到R2和Switch之間的時候,這個時候源ip是cip,目标位址是vip。vip一定在Director上是毋庸置疑的,是以這個封包就背送到Director的vip網卡上。</code>

<code>當用戶端的請求被送到Switch和Director之間的時候,這個時候源ip仍然是cip,目标位址是vip。Director發現目前本機配置的有vip位址,是以請求的一定是目前主機</code>

<code>是以封包經過Prerouting鍊到達Input鍊,而監控在Input鍊上的ipvs規則發現請求的是一個叢集服務,比如監聽在80端口的web叢集服務。這個時候lvs要根據ipvs規則</code>

<code>等等要修改封包了,在LVS-DR模型下封包送到Director上的時候,Director不會拆它的IP首部,也不會拆它的TCP首部,Director隻要将MAC位址或者幀首部拆掉了。</code>

<code>為什麼Director要拆開幀首部MAC位址呢?因為封包的目的位址就是Director本地主機,隻要到達目的主機,網卡就會拆開幀首部的。因為目标MAC就是本地主機。</code>

<code>拆掉幀首部以後,檢視IP首部和TCP首部,它發現請求的封包通路的是一個叢集服務。</code>

<code>是以為了實作LVS-DR模型的效果,在源有的IP首部之上(切記源IP、目标IP、源端口、目标端口等等沒有動),僅僅是在原有的封包外面又重新封裝了一個MAC位址幀首部</code>

<code>幀首部有源MAC和目标MAC,這個時候發送的主機是Director。于是Director把本地網卡的MAC位址作為整個封包的源MAC位址,而目的MAC就是選擇的後端某台RealServer</code>

<code>[選擇後端的某台RealServe是Director根據它的一些排程算法(rr,wrr...)選擇的]。假如選擇的是RealServer2,那麼會找到RealServer2 IP對應的MAC位址,于是找到了</code>

<code>RealServer2網卡對應的MAC位址,它是通過ARP位址解析找到的RealServer2對應的MAC位址。</code>

<code>那麼Director到RealServer2之間的封包傳送是源MAC位址是Director網卡對應的MAC位址,目标MAC位址是RealServer2網卡對應的MAC位址。</code>

<code>RealServer2接收到封包以後,發現請求的封包真的是自已,于是拆掉了MAC的幀首部,拆掉後發現請求的封包源位址是cip,目标位址是VIP。如果RealServer2上沒有VIP</code>

<code>,那麼RealServer2是不會接受這個封包的,是以必須在每個RealServer上配置VIP位址。因為RealServer2上有VIP位址,封包被接收下來,拆掉了IP首部,發現了封包</code>

<code>請求的是一個服務,比如80 因為傳輸層沒有做任何修改,使用者請求的是80服務,那麼RealServer2接收到的封包也是請求的80服務。如果RealServer2上有80服務,于是</code>

<code>RealServer2把這個請求轉交給使用者空間的程序,由使用者空間處理完成後,向外響應的。而請求封包的源位址是CIP,目标位址是VIP。那麼盡可能讓它使用CIP是目标位址</code>

<code>VIP是源位址,于是這個響應封包直接被發送到了交換機上。</code>

<code>當RealServer2響應封包到達Switch的時候,這個時候源位址是VIP,目标位址是CIP。</code>

<code>因為目标位址是CIP,假如VIP和CIP不在同一個網段當中,這個時候要根據目标位址CIP做路由選擇,比如預設路由,網關才能響應CIP的封包請求</code>

<code>大家都知道目标位址CIP是網際網路位址,那麼每個RealServer的網關要指向哪呢??????</code>

<code>要指向能夠通路網際網路的裝置,不應該指向Director的DIP位址。而是直接指向了能夠通路網際網路的路由裝置。所有(很有可能)指向的是R2路由的私有位址做網關。</code>

<code>為什麼是很有可能而不是說一定呢????</code>

<code>當封包被送到Switch和R2的時候,這個時候的源位址是VIP,目标位址是CIP。那麼這個時候封包被送到R2網關的時候,R2發現目标位址是網際網路的位址CIP,它會通過</code>

<code>路由NAT然後被送到CIP上的。</code>

<code>這裡要考慮一個問題,為了實作每台RealServer在向外發送響應封包的時候,可以把VIP作為源位址,是以我們在每台RealServer上配置了VIP位址。</code>

<code>假如用戶端發送請求封包被送到R2路由器的時候,那麼R2路由器會拆開用戶端的請求封包發現源位址是CIP,目标位址是VIP;無論是将請求送給Director還是RealServer,必須要根據</code>

<code>MAC位址向内轉發,因為在同一網段,那麼它怎麼知道VIP對應的MAC位址是什麼呢????</code>

<code>那麼将進行廣播說:‘我知道有一個家夥的VIP位址,那麼請告訴我它對應的MAC位址’,那麼它發送的廣播請求,同一網段的所有主機都能收到,于是配置有VIP位址的所有主機都進行相應并告訴自已的MAC位址,那麼如果所有的主機都進行相應,那麼前端的路由裝置就混亂了,它就無法分辨誰才是VIP對應的MAC位址。</code>

<code>預設情況下,誰相應的快,就會把用戶端的請求封包發送給那台主機,如果被送到RealServer2 那麼就不符合我們負載均衡的條件了。</code>

<code>那麼我們在這裡需要做一個非常重要的事情,就是每台配置有RealServer的VIP位址不給予ARP響應。那麼我們如果屏蔽它不能響應呢?</code>

<code>那麼所有的RealServer上都要關閉對ARP廣播的響應。 </code>

<code>要達到的目的:讓我們的前端路由或者網關,實作封包發送的時候,僅僅能夠将封包對目标IP為VIP發送給Director?</code>

<code>實作的方式有以下三種:</code>

<code>1、在R2路由器的内部接口上手動綁定一個靜态的解析位址,明确指明目标是VIP的MAC一定是Director的MAC</code>

<code>   </code><code>那麼以後發送封包的時候就不用再次請求了,可以由指定的靜态解析位址直接發送給Director</code>

<code>   </code><code>這個綁定是靜态的也不會失效</code>

<code>   </code><code>缺點:</code>

<code>   </code><code>R2路由是内部路由器,那麼VIP是私有位址;如果R2是網絡營運商提供的路由裝置,也就是VIP是公網位址,我們就無法再R2上進行靜态綁定了。</code>

<code>2、arptables:</code>

<code>   </code><code>基于MAC位址做通路控制的,我們隻需要在每台RealServer上定義arptables規則,如果使用者的arp廣播請求的目标位址是本機的VIP則不給予響應或者響應的封包不出去。</code>

<code>   </code><code>那麼這個情況所有的RealServer上不響應arp廣播請求,隻有Director響應給路由則封包就必然被發送給Director。</code>

<code>3、kernel paramter:</code>

<code>    </code><code>arp_ignore</code>

<code>    </code><code>arp_announce</code>

<code>    </code><code>作用:限定我們的Linux主機對arp廣播請求的響應級别,以及向外通告自已ip位址的通告級别的。</code>

三、配置叢集服務

1、在Real Server1 和Real Server2上做以下配置

<code># echo 1 &gt; /proc/sys/net/ipv4/conf/lo/arp_ignore </code>

<code># echo 2 &gt; /proc/sys/net/ipv4/conf/lo/arp_announce </code>

<code># echo 1 &gt; /proc/sys/net/ipv4/conf/all/arp_ignore </code>

<code># echo 2 &gt; /proc/sys/net/ipv4/conf/all/arp_announce </code>

<code>以上指令需填加到</code><code>/etc/rc</code><code>.</code><code>local</code><code>檔案中讓其開機自動生效 </code>

<code># vim /etc/sysconfig/network-scripts/ifcfg-lo:0 内容如下 </code>

<code>DEVICE=lo:0 </code>

<code>IPADDR=172.16.100.100</code>

<code>NETMASK=255.255.255.255 </code>

<code>BROADCAST=172.16.100.100</code>

<code>ONBOOT=</code><code>yes</code> 

<code>NAME=loopback </code>

<code> </code> 

<code># ifdown lo:0</code>

<code># ifup lo:0</code>

<code># route add -host 172.16.100.100 dev lo:0</code>

<code># echo "route add -host 172.16.100.100 dev lo:0" &gt;&gt; /etc/rc.local</code>

2、在Director Server上做以下配置

<code># vim /etc/sysconfig/network-scripts/ifcfg-eth2:0  内容如下  </code>

<code>DEVICE=eth2:0  </code>

<code>IPADDR=172.16.100.100  </code>

<code>NETMASK=255.255.255.255  </code>

<code>BROADCAST=172.16.100.100  </code>

<code>ONBOOT=</code><code>yes</code>  

<code># ifdown eth2:0 </code>

<code># ifup eth2:20</code>

<code># route add -host 172.16.100.100 dev eth2:0 </code>

<code># echo "route add -host 172.16.100.100 dev eth2:0" &gt;&gt; /etc/rc.local </code>

<code># echo "1" &gt; /proc/sys/net/ipv4/ip_forward </code>

<code># echo "echo "1" &gt; /proc/sys/net/ipv4/ip_forward" &gt;&gt; /etc/rc.local </code>

<code># ipvsadm -A -t 172.16.100.100:80 -s wlc</code>

<code># ipvsadm -a -t 172.16.100.100:80 -r 172.16.100.10 -g -w 2</code>

<code># ipvsadm -a -t 172.16.100.100:80 -r 172.16.100.11 -g -w 1</code>

3、浏覽器通路測試

<a href="http://s3.51cto.com/wyfs02/M01/48/BC/wKiom1QLRD3D8IqnAAEbKvwNX9Y141.jpg" target="_blank"></a>

<a href="http://s3.51cto.com/wyfs02/M02/48/BE/wKioL1QLREWQ0M2NAAEbKvwNX9Y969.jpg" target="_blank"></a>

<a href="http://s3.51cto.com/wyfs02/M02/48/BC/wKiom1QLRD3xqokvAAEYza3vqZM559.jpg" target="_blank"></a>

四、分享腳本

Director腳本:

<code># LVS script for VS/DR</code>

<code>VIP=172.16.100.100</code>

<code>PORT=80</code>

<code>start)</code>

<code>  </code><code>/sbin/ifconfig</code> <code>eth2:0 $VIP broadcast $VIP netmask 255.255.255.255 up</code>

<code>  </code><code>/sbin/route</code> <code>add -host $VIP dev eth2:0</code>

<code>  </code><code>/sbin/ipvsadm</code> <code>-A -t $VIP:80 -s wlc</code>

<code>  </code><code>/sbin/ipvsadm</code> <code>-a -t $VIP:80 -r $RIP1 -g -w 1</code>

<code>  </code><code>/sbin/ipvsadm</code> <code>-a -t $VIP:80 -r $RIP2 -g -w 2</code>

<code>  </code><code>/bin/touch</code> <code>/var/lock/subsys/ipvsadm</code> <code>&amp;&gt; </code><code>/dev/null</code>

<code>  </code><code>/sbin/ifconfig</code> <code>eth2:0 down</code>

<code>  </code><code>/sbin/route</code> <code>del $VIP</code>

<code>  </code><code>/bin/rm</code> <code>-f </code><code>/var/lock/subsys/ipvsadm</code>

<code>  </code><code>echo</code> <code>"ipvs is stopped..."</code>

<code>  </code><code>if</code> <code>[ ! -e </code><code>/var/lock/subsys/ipvsadm</code> <code>]; </code><code>then</code>

<code>    </code><code>echo</code> <code>"ipvsadm is stopped ..."</code>

<code>  </code><code>else</code>

<code>    </code><code>echo</code> <code>"ipvs is running ..."</code>

<code>    </code><code>ipvsadm -L -n</code>

<code>  </code><code>fi</code>

<code>  </code><code>echo</code> <code>"Usage: $0 {start|stop|status}"</code>

RealServer腳本:

<code># Script to start LVS DR real server.</code>

<code># description: LVS DR real server</code>

<code>.  </code><code>/etc/rc</code><code>.d</code><code>/init</code><code>.d</code><code>/functions</code>

<code>host=`</code><code>/bin/hostname</code><code>`</code>

<code>       </code><code># Start LVS-DR real server on this machine.</code>

<code>        </code><code>/sbin/ifconfig</code> <code>lo down</code>

<code>        </code><code>/sbin/ifconfig</code> <code>lo up</code>

<code>        </code><code>echo</code> <code>1 &gt; </code><code>/proc/sys/net/ipv4/conf/lo/arp_ignore</code>

<code>        </code><code>echo</code> <code>2 &gt; </code><code>/proc/sys/net/ipv4/conf/lo/arp_announce</code>

<code>        </code><code>echo</code> <code>1 &gt; </code><code>/proc/sys/net/ipv4/conf/all/arp_ignore</code>

<code>        </code><code>echo</code> <code>2 &gt; </code><code>/proc/sys/net/ipv4/conf/all/arp_announce</code>

<code>        </code><code>/sbin/ifconfig</code> <code>lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up</code>

<code>        </code><code>/sbin/route</code> <code>add -host $VIP dev lo:0</code>

<code>        </code><code># Stop LVS-DR real server loopback device(s).</code>

<code>        </code><code>/sbin/ifconfig</code> <code>lo:0 down</code>

<code>        </code><code>echo</code> <code>0 &gt; </code><code>/proc/sys/net/ipv4/conf/lo/arp_ignore</code>

<code>        </code><code>echo</code> <code>0 &gt; </code><code>/proc/sys/net/ipv4/conf/lo/arp_announce</code>

<code>        </code><code>echo</code> <code>0 &gt; </code><code>/proc/sys/net/ipv4/conf/all/arp_ignore</code>

<code>        </code><code>echo</code> <code>0 &gt; </code><code>/proc/sys/net/ipv4/conf/all/arp_announce</code>

<code>        </code><code># Status of LVS-DR real server.</code>

<code>        </code><code>islothere=`</code><code>/sbin/ifconfig</code> <code>lo:0 | </code><code>grep</code> <code>$VIP`</code>

<code>        </code><code>isrothere=`</code><code>netstat</code> <code>-rn | </code><code>grep</code> <code>"lo:0"</code> <code>| </code><code>grep</code> <code>$VIP`</code>

<code>        </code><code>if</code> <code>[ ! </code><code>"$islothere"</code> <code>-o ! </code><code>"isrothere"</code> <code>];</code><code>then</code>

<code>            </code><code># Either the route or the lo:0 device</code>

<code>            </code><code># not found.</code>

<code>            </code><code>echo</code> <code>"LVS-DR real server Stopped."</code>

<code>        </code><code>else</code>

<code>            </code><code>echo</code> <code>"LVS-DR real server Running."</code>

<code>        </code><code>fi</code>

<code>            </code><code># Invalid entry.</code>

<code>            </code><code>echo</code> <code>"$0: Usage: $0 {start|status|stop}"</code>

<code>            </code><code>exit</code> <code>1</code>

LVS-TUN

TUN的工作機制跟DR一樣,隻不過在轉發的時候,它需要重新包裝IP封包。這裡的real server(圖中為RIP)離得都比較遠。使用者請求以後,到director上的VIP上,它跟DR模型一樣,每個realserver上既有RIP又有VIP,Director就挑選一個real server進行響應,但是director和real server并不在同一個網絡上,這時候就用到隧道了,director進行轉發的時候,一定要記得CIP和VIP不能動。我們轉發是這樣的,讓它的CIP和VIP不動,在它上面再加一個IP首部,再加的IP首部源位址是DIP,目标位址的RIP的IP位址。收到封包的RIP,拆掉封包以後發現了裡面還有一個封裝,它就知道了,這就是隧道。

其實資料轉發原理和DR是一樣的,不過這個我個人認為主要是位于不同位置(不同機房);LB是通過隧道進行了資訊傳輸,雖然增加了負載,可是因為地理位置不同的優勢,還是可以參考的一種方案;

優點:負載均衡器隻負責将請求包分發給實體伺服器,而實體伺服器将應答包直接發給使用者。是以,負載均衡器能處理很巨大的請求量,這種方式,一台負載均衡能為超過100台的實體伺服器服務,負載均衡器不再是系統的瓶頸。使用VS-TUN方式,如果你的負載均衡器擁有100M的全雙工網卡的話,就能使得整個Virtual Server能達到1G的吞吐量。

不足:但是,這種方式需要所有的伺服器支援"IP Tunneling"(IP Encapsulation)協定;

<a href="http://s3.51cto.com/wyfs02/M00/48/C2/wKioL1QLYJng9g4IAAC1EkyzQjk896.jpg" target="_blank"></a>

LVS的健康狀态檢查

在LVS模型中,director不負責檢查RS的健康狀況,這就使得當有的RS出故障了,director還會将服務請求派發至此伺服器,這種情況對使用者、企業都是很不爽的,哪個使用者倒黴說不定就遇到類似了,為了讓director更人性化、可靠還要給director提供健康檢查功能;如何實作?Director沒有自帶檢查工具,隻有手動編寫腳本給director實作健康狀态檢查功能!

<code>CPORT=80</code>

<code>FAIL_BACK=127.0.0.1</code>

<code>RS=(</code><code>"172.16.100.10"</code> <code>"172.16.100.11"</code><code>)</code>

<code>declare</code> <code>-a RSSTATUS</code>

<code>RW=(</code><code>"2"</code> <code>"1"</code><code>)</code>

<code>RPORT=80</code>

<code>TYPE=g</code>

<code>CHKLOOP=3</code>

<code>LOG=</code><code>/var/log/ipvsmonitor</code><code>.log</code>

<code>addrs() {</code>

<code>ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2</code>

<code>[ $? -</code><code>eq</code> <code>0 ] &amp;&amp; </code><code>return</code> <code>0 || </code><code>return</code> <code>1</code>

<code>}</code>

<code>delrs() {</code>

<code>ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT</code>

<code>checkrs() {</code>

<code>local</code> <code>I=1</code>

<code>while</code> <code>[ $I -</code><code>le</code> <code>$CHKLOOP ]; </code><code>do</code>

<code>if</code> <code>curl --connect-timeout 1 http:</code><code>//</code><code>$1 &amp;&gt; </code><code>/dev/null</code><code>; </code><code>then</code>

<code>return</code> <code>0</code>

<code>let</code> <code>I++</code>

<code>done</code>

<code>return</code> <code>1</code>

<code>initstatus() {</code>

<code>local</code> <code>I</code>

<code>local</code> <code>COUNT=0;</code>

<code>for</code> <code>I </code><code>in</code> <code>${RS[*]}; </code><code>do</code>

<code>if</code> <code>ipvsadm -L -n | </code><code>grep</code> <code>"$I:$RPORT"</code> <code>&amp;&amp; &gt; </code><code>/dev/null</code> <code>; </code><code>then</code>

<code>RSSTATUS[$COUNT]=1</code>

<code>else</code>

<code>RSSTATUS[$COUNT]=0</code>

<code>A++</code>

<code>Dir[0]=$A</code>

<code>let</code> <code>COUNT++</code>

<code>initstatus</code>

<code>while</code> <code>:; </code><code>do</code>

<code>let</code> <code>COUNT=0</code>

<code>if</code> <code>checkrs $I; </code><code>then</code>

<code>if</code> <code>[ ${RSSTATUS[$COUNT]} -</code><code>eq</code> <code>0 ]; </code><code>then</code>

<code>addrs $I ${RW[$COUNT]}</code>

<code>[ $? -</code><code>eq</code> <code>0 ] &amp;&amp; RSSTATUS[$COUNT]=1 &amp;&amp; </code><code>echo</code> <code>"`date +'%F %H:%M:%S'`, $I is back."</code> <code>&gt;&gt; $LOG</code>

<code>if</code> <code>[ ${RSSTATUS[$COUNT]} -</code><code>eq</code> <code>1 ]; </code><code>then</code>

<code>delrs $I</code>

<code>[ $? -</code><code>eq</code> <code>0 ] &amp;&amp; RSSTATUS[$COUNT]=0 &amp;&amp; </code><code>echo</code> <code>"`date +'%F %H:%M:%S'`, $I is gone."</code> <code>&gt;&gt; $LOG</code>

<code>sleep</code> <code>5</code>

LVS持久連接配接

一、定義

持久連接配接是指無論LVS使用什麼算法,LVS持久都能實作在一定時間内,将來自同一個用戶端請求派發至此前標明的RS

二、原理

    無論使用LVS任何排程算法,LVS持久連接配接都能實作在一定時間内,将來自同一個用戶端請求派發至此前標明的伺服器;當一個新的用戶端請求連接配接時,LVS就會在記憶體的緩沖區内記錄用戶端的IP以及所選的伺服器,在一定時間内使用者再次通路時,LVS會通過記憶體緩沖區來查找是否有此使用者記錄,如果有将直接連接配接到已標明的伺服器上,否則記錄IP及連接配接的伺服器;這個記憶體緩沖區稱之為持久連接配接模闆,它存儲了每一個用戶端,及配置設定給它的RS的映射關系。

    持久連接配接在一定環境下還是非常有用的,由于在SSL會話中,比如當使用者和伺服器好不容易建立了SSL會話,使用者一不小心重新整理了頁面,director有給使用者分發了一個新的伺服器,使用者還要從建立立SSL連接配接請求,這是很不爽的!這種連接配接方式稱為持久端口連接配接(PPC),将來自于同一個用戶端對同一個叢集服務的請求,始終定向至此前標明的RS。

    持久連接配接還會将同個使用者的其他服務請求連接配接到已建立連接配接的伺服器上,比如當使用者通路web服務時,還要能實作https認證,如果通路web時,配置設定了一個RS,要通過https認證則又配置設定了一個RS;這樣就産生了沖突,它認證的不是一個RS,使得通路無法安全進行;是以持久連接配接是必不可少的,這種稱為持久用戶端連接配接(PCC),将來自于同一個用戶端對所有端口的請求,始終定向至此前標明的RS;把所有端口統統定義為叢集服務,一律向RS轉發!

    持久防火牆标記連接配接(PNMPP):定義端口間的姻親關系,将特定端口定義在同一個RS上。這是通過在防火牆内部PREROUTING鍊上,将規定的端口打上标記;比如:80端口标記為10,23端口也标記為10;這樣在寫規則時隻需将端口該為10即可,80和23端口就會在同一個RS上響應了

三、持久連接配接的分類

1、PPC 将來自于同一個用戶端對同一個叢集服務的請求,始終定向至此前標明的RS;  持久端口連接配接

2、PCC 将來自于同一個用戶端對所有端口的請求始終定向至此前標明的RS            持久用戶端連接配接

把所有端口統統定義為叢集服務,一律向RS轉發:

定義所有的服務

3、PNMPP 持久防火牆标記連接配接

定義部分服務

四、持久連接配接的指令

ipvsadm -A|E ... -p timeout:

timeout:持久連接配接時長,預設300秒:機關是秒

五、額外的補充

<code>持久連接配接模闆(記憶體緩沖區)</code>

<code>持久連接配接模闆記錄了:每一個用戶端IP及配置設定給它的RS的映射關系</code>

<code>檢視持久連接配接模闆 </code>

<code>ipvsadm -L -c  </code><code>#顯示目前的每一個連接配接模闆</code>

<code>ipvsadm -L --persistent-conn </code><code>#顯示目前的持久連接配接數</code>

<code>{</code>

<code>[root@LVS ~]</code><code># ipvsadm -L -c</code>

<code>IPVS connection entries</code>

<code>pro expire state       </code><code>source</code>             <code>virtual            destination</code>

<code>TCP  172.16.100.100:80 wlc</code>

<code>  </code><code>-&gt; 172.16.100.10:80             Route   1      0          0         </code>

<code>  </code><code>-&gt; 172.16.100.11:80             Route   2      0          0   </code>

<code>PNMPP的文法</code>

<code>PREROUTING</code>

<code>    </code><code>80:标記10</code>

<code>    </code><code>23:标記10</code>

<code>文法:</code>

<code>/sbin/iptables</code> <code>-F -t mangle</code>

<code>/sbin/iptables</code> <code>-A PREROUTING -i eth0 -t mangle -p tcp -d 172.16.100.6 --dport 80 -j MARK -</code><code>set</code><code>-mark 1</code>

<code>/sbin/iptables</code> <code>-A PREROUTING -i eth0 -t mangle -p tcp -d 172.16.100.6 --dport 443 -j MARK -</code><code>set</code><code>-mark 1</code>

<code>        </code> 

<code>/sbin/ipvsadm</code> <code>-A -f 1 -s rr -p 3600</code>

<code>/sbin/ipvsadm</code> <code>-a -f 1 -r 172.16.100.10 -g -w 2</code>

<code>/sbin/ipvsadm</code> <code>-a -f 1 -r 172.16.100.11 -g -w 1</code>

六、部署

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

<code>假如後端有多台RS;同時定義了兩個叢集服務,web服務和telnet服務</code>

<code>目的:前端使用者通路80端口的時候會同時負載後端的多台RS上,并且23号端口的通路也會同時負載到多台RS上。</code>

<code>描述:後端有多台RS。每台RS上同時提供web服務和telnet服務。我們希望前端使用者通路的時候,對80端口發起的通路請求會分别負載到多台RS上。</code>

<code>同時對23号端口的通路也會負載到多台RS上。是以說,它們同時提供了兩類叢集服務,那麼就是Dirctor同時提供兩種叢集服務的負載均衡。</code>

<code>結論:</code>

<code>持久連接配接有這種功能</code>

<code>比如,user1通路80端口服務的時候,Director把封包轉發RS1上;當user1下次在通路23号端口的時候,Director還是會把封包轉發RS1上的。</code>

<code>1、ipvsadm輪詢算法rr</code>

<code>TCP  172.16.100.100:80 rr</code>

<code>  </code><code>-&gt; 172.16.100.11:80             Route   2      0          0 </code>

<code>結論:通過上面的輪詢算法rr;用浏覽器通路的結果是</code>

<code>第一次被定向到RS1上面</code>

<code>第二次被定向到RS2上面</code>

<code>第三次被定向到RS1上面</code>

<code>第四次被定向到RS2上面</code>

<code>......</code>

<code>2、ipvsadm的持久連接配接web服務(PPC)</code>

<code>[root@LVS ~]</code><code># ipvsadm -E -t 172.16.100.100:80 -s rr -p 600</code>

<code>TCP  172.16.100.100:80 rr persistent 600</code>

<code>  </code><code>-&gt; 172.16.100.11:80             Route   2      0          0  </code>

<code>結論:通過上面的持久連接配接;用浏覽器通路的結果是</code>

<code>如果此時定向到RS1上,那麼重新整理頁面之後被定向到RS2上,以後你無論怎麼重新整理都被定向到RS2上面。</code>

<code>[root@LVS ~]</code><code># ipvsadm -L --persistent-conn</code>

<code>Prot LocalAddress:Port            Weight    PersistConn ActiveConn InActConn </code>

<code>  </code><code>-&gt; RemoteAddress:Port</code>

<code>TCP  172.16.100.100:http rr persistent 600</code>

<code>  </code><code>-&gt; 172.16.100.10:http           1         0           0          0         </code>

<code>  </code><code>-&gt; 172.16.100.11:http           2         1           0          16        </code>

<code>TCP 00:00  FIN_WAIT    172.16.100.2:52083 172.16.100.100:http 172.16.100.11:http</code>

<code>TCP 00:10  FIN_WAIT    172.16.100.2:52086 172.16.100.100:http 172.16.100.11:http</code>

<code>TCP 00:00  FIN_WAIT    172.16.100.2:52071 172.16.100.100:http 172.16.100.11:http</code>

<code>TCP 00:00  FIN_WAIT    172.16.100.2:52085 172.16.100.100:http 172.16.100.11:http</code>

<code>TCP 08:00  NONE        172.16.100.2:0     172.16.100.100:http 172.16.100.11:http</code>

<code>TCP 00:00  FIN_WAIT    172.16.100.2:52084 172.16.100.100:http 172.16.100.11:http</code>

<code>3、ivpsadm的持久連接配接telnet服務(PPC)</code>

<code>注意:telnet是不允許超級管理者root直接遠端登陸的</code>

<code>#安裝、啟動telnet服務</code>

<code># yum -y install telnet-server</code>

<code># chkconfig --add telnet</code>

<code># chkconfig telnet on</code>

<code># useradd jerry</code>

<code># passwd jerry</code>

<code># netstat -tnlp |grep :23</code>

<code>#定義telnet叢集服務</code>

<code>ipvsadm -A -t 172.16.100.100:23 -s rr</code>

<code>ipvsadm -a -t 172.16.100.100:23 -r 172.16.100.10 -g -w 2</code>

<code>ipvsadm -a -t 172.16.100.100:23 -r 172.16.100.11 -g -w 1</code>

<code>測試1</code>

<code>Xshell:\&gt; telnet 172.16.100.100</code>

<code>login: jerry</code>

<code>Password: jerry</code>

<code>[jerry@web2 ~]$  </code><code>#RS2</code>

<code>看主機名稱可以辨識出連接配接的是哪一台RS,然後退出後在此登陸</code>

<code>[jerry@web1 ~]$  </code><code>#RS1</code>

<code>支援持久連接配接的telnet服務</code>

<code>[root@LVS ~]</code><code># ipvsadm -E -t 172.16.100.100:23 -s rr -p 3600</code>

<code>TCP  172.16.100.100:23 rr persistent 3600</code>

<code>  </code><code>-&gt; 172.16.100.10:23             Route   2      0          0         </code>

<code>  </code><code>-&gt; 172.16.100.11:23             Route   1      0          1  </code>

<code>測試2 </code>

<code>退出後再次登陸</code>

<code>結論:telnet叢集服務的持久連接配接成功</code>

<code>4、ipvsadm持久連接配接(PCC)</code>

<code>#把0端口定義成叢集服務,這意味所有的端口都是叢集服務</code>

<code>ipvsadm -A -t 172.16.100.100:0 -s rr -p 600</code>

<code>ipvsadm -a -t 172.16.100.100:0 -r 172.16.100.10 -g -w 2</code>

<code>ipvsadm -a -t 172.16.100.100:0 -r 172.16.100.11 -g -w 1</code>

<code>測試 浏覽器、telnet、</code><code>ssh</code>

<code>浏覽器通路被定向到比如RS2</code>

<code>telnet測試被定向到RS2</code>

<code>ssh</code> <code>172.16.100.100</code>

<code>[root@web2 ~]</code><code># </code>

<code>看下連接配接的模闆</code>

<code>TCP 14:32  ESTABLISHED 172.16.100.2:52735 172.16.100.100:</code><code>ssh</code> <code>172.16.100.11:</code><code>ssh</code>

<code>TCP 00:09  NONE        172.16.100.2:0     172.16.100.100:0   172.16.100.11:0</code>

<code>TCP 04:11  NONE        172.16.100.2:0     172.16.100.100:telnet 172.16.100.10:telnet</code>

<code>TCP 14:55  ESTABLISHED 172.16.100.2:52499 172.16.100.100:telnet 172.16.100.11:telnet</code>

<code>5、ivpsadm持久連接配接(PCC)</code>

<code>現在把23端口和80端口的定義成一個叢集服務</code>

<code>      </code><code>22端口的是另外一個叢集服務</code>

<code>service ipvsadm restart</code>

<code>ipvsadm -L -n</code>

<code>iptables -A PREROUTING -i eth2 -t mangle -p tcp -d 172.16.100.100 --dport 80 -j MARK --</code><code>set</code><code>-mark 8</code>

<code>iptables -A PREROUTING -i eth2 -t mangle -p tcp -d 172.16.100.100 --dport 23 -j MARK --</code><code>set</code><code>-mark 8  </code>

<code>    </code> 

<code>ipvsadm -A -f 8 -s rr [-p 600]</code>

<code>ipvsadm -a -f 8 -r 172.16.100.10 -g -w 2</code>

<code>ipvsadm -a -f 8 -r 172.16.100.11 -g -w 1   </code>

<code>由于22端口的</code><code>ssh</code><code>服務沒有被定義成叢集服務,是以在登陸的時候是Director來響應</code>

<code>Xshell:\&gt; </code><code>ssh</code> <code>172.16.100.100</code>

<code>[root@LVS ~]</code><code># </code>

<code>由于80服務和23服務都被定義叢集服務,是以在通路的時候應該是排程算法輪詢來響應的</code>

<code>Password: </code>

<code>[jerry@web2 ~]$ </code>

<code>退出再次通路</code>

<code>[jerry@web1 ~]$ </code>

<code>浏覽器通路也是一樣的,輪詢這響應請求</code>

<code>第一次響應的是RS1</code>

<code>第二次響應的是RS2</code>

<code>第三次響應的是RS1</code>

<code>第四次響應的是RS2</code>

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

繼續閱讀