使用 Linux Virtual Server 和 Linux-HA.org 的 Heartbeat 进行构建和运行Web服务器集群(二)

步骤 4:使用 ipvsadm 命令创建 LVS 规则

下一步是获取浮动资源 IP 地址并在其上进行构建。因为 LVS 要求对远端 Web 浏览器客户机透明,所以所有的 Web 请求都必须经过控制器过滤并传给一个 realserver。然后,所有结果都需要传回控制器,后者向发出 Web 页面请求的客户机返回响应。

为了完成上述的请求和响应流程,首先配置每个 LVS 控制器,从而发出以下命令启用 IP 转发(因此允许将请求传给 realserver):

# echo "1" >/proc/sys/net/ipv4/ip_forward

# cat /proc/sys/net/ipv4/ip_forward

如果所有的操作都成功,那么第二个命令将返回一个 “1” 作为终端输出。要永久性地添加此选项,请添加:

'' IP_FORWARD="yes"

到 /etc/sysconfig/sysctl 中。

接下来,要通知控制器将引入的 HTTP 请求传递给 HA 浮动 IP 地址,接着再传给 realserver,使用 ipvsadm 命令。

首先,清除旧的 ipvsadm 表:

# /sbin/ipvsadm -C

在配置新表之前,您需要决定希望 LVS 控制器使用何种工作负载分配。收到来自客户机的连接请求后,控制器根据一个 “进度表” 将 realserver 指派给客户机,然后使用 ipvsadm 命令设置调度程序类型。可用的调度程序包括:

  • Round Robin (RR):新的引入连接被依次指派给每个 realserver。
  • Weighted Round Robin (WRR):使用附加的权重因子进行 RR 调度以补偿各种 realserver 功能(如附加 CPU、更多内存等)的差异。
  • Least Connected (LC):新连接指向具有最少连接数量的 realserver。不要求是最空闲的 realserver,但是以此为方向。
  • Weighted Least Connection (WLC):带权重的 LC。

使用 RR 调度进行测试是个不错的方法,因为易于确认。您可能希望将 WRR 和 LC 添加到测试例程中以确认它们能够按预期运作。此处给出的示例使用 RR 调度及类似调度。

接下来,创建脚本以启用转发至 realserver 的 ipvsadm 服务,并且在每个 LVS 控制器中放置一个副本。当完成 mon 的后续配置以自动监控活动的 realserver 后,就不需要再使用这个脚本,但在此之前它会有助于测试 ipvsadm 组件。请记住在执行此脚本之前重新检查网络和 http/https 与每个 realserver 之间的连接是否正常。

清单 5. HA_CONFIG.sh 文件

#!/bin/sh

# The virtual address on the director which acts as a cluster address

VIRTUAL_CLUSTER_ADDRESS=192.168.71.205

REAL_SERVER_IP_1=192.168.71.220

REAL_SERVER_IP_2=192.168.71.150

REAL_SERVER_IP_3=192.168.71.121

REAL_SERVER_IP_4=192.168.71.145

REAL_SERVER_IP_5=192.168.71.185

REAL_SERVER_IP_6=192.168.71.186

# set ip_forward ON for vs-nat director (1 on, 0 off).

cat /proc/sys/net/ipv4/ip_forward

echo "1" >/proc/sys/net/ipv4/ip_forward

# director acts as the gw for realservers

# Turn OFF icmp redirects (1 on, 0 off), if not the realservers might be clever and

# not use the director as the gateway!

echo "0" >/proc/sys/net/ipv4/conf/all/send_redirects

echo "0" >/proc/sys/net/ipv4/conf/default/send_redirects

echo "0" >/proc/sys/net/ipv4/conf/eth0/send_redirects

# Clear ipvsadm tables (better safe than sorry)

/sbin/ipvsadm -C

# We install LVS services with ipvsadm for HTTP and HTTPS connections with RR

# scheduling

/sbin/ipvsadm -A -t $VIRTUAL_CLUSTER_ADDRESS:http -s rr

/sbin/ipvsadm -A -t $VIRTUAL_CLUSTER_ADDRESS:https -s rr

# First realserver

# Forward HTTP to REAL_SERVER_IP_1 using LVS-NAT (-m), with weight=1

/sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:http -r $REAL_SERVER_IP_1:http -m -w 1

/sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:https -r $REAL_SERVER_IP_1:https -m -w 1

# Second realserver

# Forward HTTP to REAL_SERVER_IP_2 using LVS-NAT (-m), with weight=1

/sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:http -r $REAL_SERVER_IP_2:http -m -w 1

/sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:https -r $REAL_SERVER_IP_2:https -m -w 1

# Third realserver

# Forward HTTP to REAL_SERVER_IP_3 using LVS-NAT (-m), with weight=1

/sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:http -r $REAL_SERVER_IP_3:http -m -w 1

/sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:https -r $REAL_SERVER_IP_3:https -m -w 1

# Fourth realserver

# Forward HTTP to REAL_SERVER_IP_4 using LVS-NAT (-m), with weight=1

/sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:http -r $REAL_SERVER_IP_4:http -m -w 1

/sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:https -r $REAL_SERVER_IP_4:https -m -w 1

# Fifth realserver

# Forward HTTP to REAL_SERVER_IP_5 using LVS-NAT (-m), with weight=1

/sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:http -r $REAL_SERVER_IP_5:http -m -w 1

/sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:https -r $REAL_SERVER_IP_5:https -m -w 1

# Sixth realserver

# Forward HTTP to REAL_SERVER_IP_6 using LVS-NAT (-m), with weight=1

/sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:http -r $REAL_SERVER_IP_6:http -m -w 1

/sbin/ipvsadm -a -t $VIRTUAL_CLUSTER_ADDRESS:https -r $REAL_SERVER_IP_6:https -m -w 1

# We print the new ipvsadm table for inspection

echo "NEW IPVSADM TABLE:"

/sbin/ipvsadm

如清单 5 中所示,脚本只是启用了 ipvsadm 服务,然后实际上使用了相同的代码节以便将 Web 和 SSL 请求转发给每个单个的 realserver。我们使用了 -m 选项指定 NAT,并给每个 realserver 赋以权重 1(-w 1)。使用正常的轮循调度时,指定的权重会出现冗余(因为默认的权重总是 1)。显示此选项的惟一目的是让您倾向于选择加权的轮循。 为此,在关于使用轮循的注释下的 2 个连续的行中将 rr 改为 wrr,当然不要忘了相应地调整权重。有关各种调度程序的更多信息,请查询 ipvsadm 手册。

您 现在已经配置了每个控制器,可以处理引入的对浮动服务 IP 的 Web 和 SSL 请求,方法是重写这些请求并连续地将工作传递给 realserver。但是为了从 realserver 收回通信量,并且为了在将请求返回给发出请求的客户机之前执行相反的过程,您需要对控制器更改几个连网设置。其原因是需要在平面网络拓扑结构中实现 LVS 控制器和 realserver(即,同一子网上的所有组件)。我们需要执行以下步骤以强制 Apache 通过控制器返回响应通信量,而不是自己直接应答:

echo "0" > /proc/sys/net/ipv4/conf/all/send_redirects
echo "0" > /proc/sys/net/ipv4/conf/default/send_redirects
echo "0" > /proc/sys/net/ipv4/conf/eth0/send_redirects

执行此操作的目的是为了防止活动的 LVS 控制器通知 realserver 和浮动服务 IP 直接相互通信,从而获取 TCP/IP 捷径(因为它们位于同一个子网中)。一般情况下,重定向是有用的,因为它们通过清除网络连接中不必要的中间件提高了性能。但是此时,它可能阻碍了响应通信 量的重写,而这又是对客户机透明所必需的。实际上,如果在 LVS 控制器上没有禁用重定向,那么从 realserver 直接发往客户机的通信量将被客户机视为未被请求的网络响应而被丢弃。

此时,可将每个 realserver 的默认路由设为指向服务的浮动 IP 地址,从而确保所有的响应都被传回控制器以进行包重写,然后再传回最初发出请求的客户机。

一旦在控制器上禁用重定向,并且 realserver 被配置为通过浮动服务 IP 发送所有的通信量,那么您可能需要测试 HA LVS 环境。要测试迄今为止所做的工作,可让一个远端客户机上的 Web 浏览器指向 LVS 控制器的浮动服务地址。

为了在实验室进行测试,我们使用的是基于 Gecko 的浏览器(Mozilla),但是任何其他浏览器也可以满足要求。为了确保部署成功,在浏览器中禁用缓存,并多次单击刷新按钮。在每次刷新时,您应看见显 示的 Web 页面是 realserver 上配置的一个自识别页面。如果您要使用 RR 调度,您应可以看到连续通过每个 realserver 的页面循环。

您是否正在思考确保 LVS 配置在引导时自动启动?现在千万别这样做!还有一个步骤尚未完成(步骤 5),此步骤将执行 realserver 的活动监控(因此保留一个动态 Apache 节点列表,其中的节点可以为工作请求提供服务)。



回页首

步骤 5:在 LVS 控制器上安装和配置 mon

迄今为止,您已经建立了一个高度可用的服务 IP 地址,并将其绑定到 realserver 实例池。但是在任何给定时间您决不能信任任何单个的 Apache 服务器是正常运作的。通过选择 RR 调度,如果任何给定的 realserver 被禁用,或者以一种即时的方式停止响应网络通信量,那么 1/6 的 HTTP 请求将会失败!

因此有必要实施 realserver 对每个 LVS 控制器的监控,以便动态地将其添加到服务池中或从中删除。另一个著名的称为 mon 的开源包很适合这项任务。

mon 解决方案一般用于监控 LVS 真实节点。Mon 的配置相对容易,并且对于熟悉 shell 脚本编程的人而言可扩展性很好。让所有组件正常运作大致分以下三个主要步骤:安装、服务监控配置和警报创建。使用包管理工具处理 mon 的安装。完成安装后,您只需要调整监控配置,并创建一些警报脚本。当监视器确定 realserver 已经脱机或恢复联机时,将触发警报脚本。

注意,安装 heartbeat v2 后,监控 realserver 可通过构建所有的 realserver 服务资源来完成。 或者,您可以使用 Heartbeat ldirectord 包。

默认情况下,mon 附带了几个可以直接使用的监视器机制。我们修改了 /etc/mon.cf 中的样例配置文件以使用 HTTP 服务。

在 mon 配置文件中,确保标题可以反映正确的路径。SLES10 是一个 64 位的 Linux 图像,但是随附的样例配置用于默认的(31 位或 32 位)位置。配置文件样例假定警报和监视器位于 /usr/lib 中,这对于我们的特定安装而言并不正确。我们修改的参数如下:

alertdir = /usr/lib64/mon/alert.d
mondir = /usr/lib64/mon/mon.d

如您所见,我们只是将 lib 更改为 lib64。对于您所使用的版本可能不需要这种更改。

对配置文件的下一个更改是指定要监控的 realserver 列表。这可以通过以下 6 个指令完成:

清单 6. 指定要监控的 realserver

hostgroup litstat1 192.168.71.220 # realserver 1

hostgroup litstat2 192.168.71.150

hostgroup litstat3 192.168.71.121

hostgroup litstat4 192.168.71.145

hostgroup litstat5 192.168.71.185

hostgroup litstat6 192.168.71.186 # realserver 6

如果您希望添加额外的 realserver,直接在此添加额外的条目即可。

一旦您处理好所有的定义,就需要告知 mon 如何查看故障,以及如何处理故障。为此,添加以下的监视器段(分别针对每个 realserver)。完成后,您需要将 mon 配置文件和警报置于每个 LVS heartbeat 节点之上,启用每个 heartbeat 集群节点以独立地监控所有的 realserver。

清单 7. /etc/mon/mon.cf 文件

#
# global options
#
cfbasedir = /etc/mon
alertdir = /usr/lib64/mon/alert.d
mondir = /usr/lib64/mon/mon.d
statedir = /var/lib/mon
logdir = /var/log
maxprocs = 20
histlength = 100
historicfile = mon_history.log
randstart = 60s
#
# authentication types:
# getpwnam standard Unix passwd, NOT for shadow passwords
# shadow Unix shadow passwords (not implemented)
# userfile "mon" user file
#
authtype = getpwnam
#
# downtime logging, uncomment to enable
# if the server is running, don’t forget to send a reset command
# when you change this
#
#dtlogfile = downtime.log
dtlogging = yes
#
# NB: hostgroup and watch entries are terminated with a blank line (or
# end of file). Don’t forget the blank lines between them or you lose.
#
#
# group definitions (hostnames or IP addresses)
# example:
#
# hostgroup servers www mail pop server4 server5
#
# For simplicity we monitor each individual server as if it were a "group"
# so we add only the hostname and the ip address of an individual node for each.
hostgroup litstat1 192.168.71.220
hostgroup litstat2 192.168.71.150
hostgroup litstat3 192.168.71.121
hostgroup litstat4 192.168.71.145
hostgroup litstat5 192.168.71.185
hostgroup litstat6 192.168.71.186
#
# Now we set identical watch definitions on each of our groups. They could be
# customized to treat individual servers differently, but we have made the
# configurations homogeneous here to match our homogeneous LVS configuration.
#
watch litstat1
service http
description http check servers
interval 6s
monitor http.monitor -p 80 -u /index.html
allow_empty_group
period wd {Mon-Sun}
alert dowem.down.alert -h
upalert dowem.up.alert -h
alertevery 600s
alertafter 1
watch litstat2
service http
description http check servers
interval 6s
monitor http.monitor -p 80 -u /index.html
allow_empty_group
period wd {Mon-Sun}
alert dowem.down.alert -h
upalert dowem.up.alert -h
alertevery 600s
alertafter 1
watch litstat3
service http
description http check servers
interval 6s
monitor http.monitor -p 80 -u /index.html
allow_empty_group
period wd {Mon-Sun}
alert dowem.down.alert -h
upalert dowem.up.alert -h
alertevery 600s
alertafter 1
watch litstat4
service http
description http check servers
interval 6s
monitor http.monitor -p 80 -u /index.html
allow_empty_group
period wd {Mon-Sun}
alert dowem.down.alert -h
upalert dowem.up.alert -h
alertevery 600s
alertafter 1
watch litstat5
service http
description http check servers
interval 6s
monitor http.monitor -p 80 -u /index.html
allow_empty_group
period wd {Mon-Sun}
alert dowem.down.alert -h
upalert dowem.up.alert -h
alertevery 600s
alertafter 1
watch litstat6
service http
description http check servers
interval 6s
monitor http.monitor -p 80 -u /index.html
allow_empty_group
period wd {Mon-Sun}
alert dowem.down.alert -h
upalert dowem.up.alert -h
alertevery 600s
alertafter 1

清单 7 告知 mon 使用 http.monitor,默认情况下它由 mon 附带。另外,指定使用端口 80。清单 7 还提供了要请求的特殊页面;您可能会选择为 Web 服务器传输一小段更有效率的 html 作为操作成功的证明,而不是传输一个复杂的默认 html 页面。

alertupalert 行调用的脚本必须置于配置文件顶部指定的 alertdir 中。其目录通常是发行版所默认的目录,比如 “/usr/lib64/mon/alert.d”。警报负责告知 LVS 将 Apache 服务器添加到合格的列表中或从中删除(方法是调用 ipvsadm 命令,我们很快就要介绍到)。

当一个 realserver 的 http 测试失败时,dowem.down.alert 将由 mon 使用几个参数自动执行。同样地,当监视器确定 realserver 已经恢复联机时,mon 进程使用大量的参数自动执行 dowem.up.alert。您可以随意地修改警报脚本的名称以适应您的部署。

保存此文件,在 alertdir 中创建警报(使用简单的 bash 脚本编程)。清单 8 展示了一个 bash 脚本警报,重新建立 realserver 连接时由 mon 调用。

清单 8. 简单警报:已连接上

#! /bin/bash

# The h arg is followed by the hostname we are interested in acting on

# So we skip ahead to get the -h option since we don’t care about the others

REALSERVER=192.168.71.205

while [ $1 != "-h" ] ;

do

shift

done

ADDHOST=$2

# For the HTTP service

/sbin/ipvsadm -a -t $REALSERVER:http -r $ADDHOST:http -m -w 1

# For the HTTPS service

/sbin/ipvsadm -a -t $REALSERVER:https -r $ADDHOST:https -m -w 1

清单 9 展示了一个 bash 脚本警报,当 realserver 连接丢失时由 mon 调用。

清单 9. 简单警报:连接已丢失

#! /bin/bash

# The h arg is followed by the hostname we are interested in acting on

# So we skip ahead to get the -h option since we dont care about the others

REALSERVER=192.168.71.205

while [ $1 != "-h" ] ;

do

shift

done

BADHOST=$2

# For the HTTP service

/sbin/ipvsadm -d -t $REALSERVER:http -r $BADHOST

# For the HTTPS service

/sbin/ipvsadm -d -t $REALSERVER:https -r $BADHOST

这两组脚本都使用 ipvsadm 命令行工具动态地将 realserver 添加到 LVS 表中或从中删除。注意,这些脚本远谈不上完美。mon 只对于简单的 Web 请求监控 http 端口,此处阐述的架构在下述情形中容易受到攻击:给定的 realserver 对于 http 请求可能正常运作,但对于 SSL 请求却不行。在这些情况下,我们将无法从 https 备选列表中删除有问题的 realserver。当然,除了为 mon 配置文件中的每个 realserver 启用另一个 https 监视器外,构建更多专门针对每种类型的 Web 请求的高级警报也可以轻松地解决这个问题。这可以留给读者作为练习。

为确保监视器已被激活,依次为每个 realserver 启用并禁用 Apache 进程,观察每个控制器对事件的反应。只有当您确认每个控制器正常地监控每个 realserver 后,您才可以使用 chkconfig 命令确保 mon 进程可以在引导时自动启动。使用的特定命令为 chkconfig mon on,但是这可能随发行版的不同而有所区别。

完成这个最后的部分后,您就已完成构建跨系统的高度可用的 Web 服务器基础设施的任务。当然,您现在可能想要执行一些更高级的工作。例如,您可能已经注意到,mon 守护程序本身没有被监控(heartbeat 项目可以为您监控 mon),但是最后的步骤已为此打下基础。



回页首