天天看點

負載均衡之LVS--Shell腳本配置LVS

  本篇内容主要用三個腳本來實作LVS的配置。腳本1:lvs.sh 是配置在負載均衡端,腳本2:realserver.sh 是配置後端Real Server伺服器上的。腳本3:check_lvs.sh 是用在負載均衡端上來測試後端伺服器的健康狀态的腳本,如有一個Real Server 當機就會自動清除,如果恢複了就再加上,後端所有伺服器都當機了,會把負載均衡端提供的錯誤頁面加到叢集中來。

規劃:

  負載均衡:

    DIP:192.168.1.11

    VIP:192.168.1.10

  背景Real Server有兩個分别為:

    rs1:192.168.1.9 

    rs2:192.168.1.8

在192.168.1.11上安裝ipvsadm和httpd服務,當在後端伺服器都當機時提供錯誤頁面。

  yum install ipvsadm -y

在rs1,rs2上分别安裝httpd服務,并啟動服務,提供網頁。

  yum install httpd -y

在192.168.1.11伺服器上編寫腳本lvs.sh

cd /opt/scripts

vim lvs.sh

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

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

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

<code>#</code>

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

<code># chkconfig: - 90 10</code>

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

<code> </code> 

<code>VIP=192.168.1.10</code>

<code>DIP=192.168.1.11</code>

<code>RIP1=192.168.1.9</code>

<code>RIP2=192.168.1.8</code>

<code>PORT=80</code>

<code>RSWEIGHT1=2</code>

<code>RSWEIGHT2=5</code>

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

<code>    </code><code>start)</code>

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

<code>        </code><code>#啟用eth0:0來配置VIP</code>

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

<code>        </code><code>#添加VIP路由資訊</code>

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

<code>        </code><code>#打開ip轉發功能</code>

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

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

<code>        </code><code>#清空iptables規則</code>

<code>        </code> 

<code>        </code><code>/sbin/ipvsadm</code> <code>-C</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:$PORT -r $RIP1:$PORT -g -w $RSWEIGHT1</code>

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

<code>        </code><code>#添加ipvs規則</code>

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

<code>        </code><code>#建立鎖檔案</code>

<code>    </code><code>;;</code>

<code>    </code><code>stop)</code>

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

<code>        </code><code>/sbin/ifconfig</code> <code>eth0: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>status)</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>*)</code>

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

<code>esac</code>

此腳本可以加到系統服務清單中,并可以設定開機自動啟動。

在後端伺服器rs1和rs2中編寫腳本realserver.sh如下:

<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>/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>/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>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>echo</code> <code>"LVS-DR real server Running."</code>

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

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

完成後可以啟動腳本了。

LVS自身沒有對後端伺服器的健康狀态檢測功能,下面在192.168.1.11伺服器上來使用腳本來每5s種檢測下背景伺服器健康狀态,并實作自動清除當機的伺服器,恢複後可以自動添加。

vim check_lvs.sh

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

99

100

101

102

103

104

<code>VIP=192.168.19.211</code>

<code>CPORT=80</code>

<code>FAIL_BACK=127.0.0.1</code>

<code>RS=(</code><code>"192.168.19.245"</code> <code>"192.168.19.219"</code><code>) </code><code>#定義一個數組并指派</code>

<code>declare</code> <code>-a RSSTATUS </code><code>#定義一個空數組</code>

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

<code>RPORT=80</code>

<code>TYPE=g </code><code>#定義為DR模型</code>

<code>CHKLOOP=3</code>

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

<code> </code><code>#定義一個添加規則的函數 </code>

<code>addrs() {</code>

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

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

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

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

<code>        </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>fi</code>

<code>}</code>

<code>#定義删除規則的函數 </code>

<code>delrs() {</code>

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

<code>#定義是否要添加錯誤頁面的規則的函數 </code>

<code>ifaddls() {</code>

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

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

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

<code>                </code><code>echo</code> <code>"`date '+%F %T'` All RS is Down and Local web is up"</code> <code>&gt;&gt; $LOG</code>

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

<code>                </code><code>ipvsadm -a -t $VIP:$CPORT -r 127.0.0.1:80 -$TYPE</code>

<code>                </code><code>[ $? -</code><code>eq</code> <code>0 ]; </code><code>echo</code> <code>"`date '+%F %T'` All RS is Down! Local 127.0.0.1:80 is up!!!"</code> <code>&gt;&gt; $LOG</code>

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

<code>                </code><code>ipvsadm -d -t $VIP:$CPORT -r 127.0.0.1:80</code>

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

<code>            </code><code>ipvsadm -d -t $VIP:$CPORT -r 127.0.0.1:80</code>

<code>#定義檢測後端伺服器服務健康狀态的函數  </code>

<code>checkrs() {</code>

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

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

<code>        </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>            </code><code>return</code> <code>0</code>

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

<code>    </code><code>done</code>

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

<code>#檢測腳本初始化函數  </code>

<code>initstatus() {</code>

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

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

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

<code>        </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>            </code><code>RSSTATUS[$COUNT]=1</code>

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

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

<code>#腳本開始執行: </code>

<code>initstatus</code>

<code>ifaddls</code>

<code>while</code> <code>:; </code><code>do</code> <code>#無限循環</code>

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

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

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

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

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

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

<code>                </code><code>delrs $I</code>

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

<code>    </code><code>ifaddls</code>

<code>    </code><code>sleep</code> <code>5 </code><code>#睡眠5s再循環</code>

<code>done</code>

本文轉自 ZhouLS 51CTO部落格,原文連結:http://blog.51cto.com/zhou123/1683975