本篇内容主要用三个脚本来实现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 > </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>&> </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 > </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 > </code><code>/proc/sys/net/ipv4/conf/lo/arp_ignore</code>
<code> </code><code>echo</code> <code>2 > </code><code>/proc/sys/net/ipv4/conf/lo/arp_announce</code>
<code> </code><code>echo</code> <code>1 > </code><code>/proc/sys/net/ipv4/conf/all/arp_ignore</code>
<code> </code><code>echo</code> <code>2 > </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 > </code><code>/proc/sys/net/ipv4/conf/lo/arp_ignore</code>
<code> </code><code>echo</code> <code>0 > </code><code>/proc/sys/net/ipv4/conf/lo/arp_announce</code>
<code> </code><code>echo</code> <code>0 > </code><code>/proc/sys/net/ipv4/conf/all/arp_ignore</code>
<code> </code><code>echo</code> <code>0 > </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>&> </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 ] && </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>&> </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>>> $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>>> $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>&> </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 &> </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>&& > </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 ] && RSSTATUS[$COUNT]=1 && </code><code>echo</code> <code>"`date '+%F %T'`, $I is back."</code> <code>>> $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 ] && RSSTATUS[$COUNT]=0 && </code><code>echo</code> <code>"`date '+%F %T'`, $I is gone."</code> <code>>> $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