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


使用 Linux Virtual Server 和 Heartbeat v2,分 5 个步骤跨越多个物理或虚拟 Linux® 服务器轻松构建高度可用的 Apache Web 服务器集群。

通过在多个处理器之间分担工作负载并采用多种软件恢复技术,能够提供高度可用的环境并提高环境的总体 RAS(可靠性、可用性和可服务性)。可以得到的好处包括:更快地从意外中断中恢复运行,以及将意外中断对终端用户的影响降至最低。

为 了更好地理解这篇文章,您需要熟悉 Linux 和连网的基本知识,还需要配置好 Apache 服务器。本文的示例基于标准的 SUSE Linux Enterprise Server 10 (SLES10) 安装,但是使用其他版本的明智用户也应该可以采用文中展示的方法。

本 文展示了健壮的 Apache Web 服务器堆栈,它拥有 6 个 Apache 服务器节点(虽然 3 个节点就足以支持文中阐述的步骤),以及 3 个 Linux Virtual Server (LVS) 控制器。我们使用 6 个 Apache 服务器节点,可以在测试时实现更高的工作负载吞吐量,从而模拟更大型的部署。文中展示的架构应该可以支持更多的控制器和后端 Apache 服务器(在资源允许的情况下),但是我们并未进行更深入的尝试。图 1 展示了使用 Linux Virtual Server 和 linux-ha.org 组件的实现。

图 1. Linux Virtual Servers 和 Apache
Linux Virtual Servers 和 Apache

如图 1 所示,外部客户机向单个 IP 地址发送通信量,而该 IP 地址可能存在于某个 LVS 控制器机器上。控制器机器积极地监控接收其发送工作的 Web 服务器池。

注意,图 1 左侧的工作负载进程指向右侧。此集群的浮动资源地址在一个给定时间将位于某个 LVS 控制器实例上。可以使用一个图形化的配置工具手动地移动服务地址,或者(这种方法更常见)自行管理服务地址,视 LVS 控制器的状态而定。如果某个控制器变得不合格(由于连接丢失、软件故障或类似原因),那么服务地址将自动地被重新分配给一个合格的控制器。

浮动服务地址必须跨越两个或多个离散的硬件实例,以便在一个物理机器连接丢失的情况下继续操作。使用本文展示的配置决策,每个 LVS 控制器都可以将包转发给任何的实际 Apache Web 服务器,并且与服务器的物理位置或服务器与提供浮动服务地址的活动控制器的接近程度无关。本文展示了每个 LVS 控制器如何积极地监控 Apache 服务器,以确保只向正常运作的后端服务器发送请求。

使用这种配置,技术人员可以成功地让整个 Linux 实例失效,而且不会中断在浮动服务地址上启用的用户服务(通常是 http 和 https Web 请求)。

Linux Virtual Server 术语新手必读

LVS 控制器:Linux Virtual Server 控制器是一种系统,该系统接受任意的引入通信量并将其传递给任意数量的 realserver。然后接受来自 realserver 的响应并将其传回发出请求的客户机。控制器需要以一种透明的方式执行任务,使客户机永远不会知道执行实际工作负载处理的是 realserver。

LVS 控制器本身需要能够实现资源(具体而言,指的是用于侦听引入通信量的虚拟 IP 地址)之间的浮动,从而避免单点故障。LVS 控制器实现浮动 IP 地址的方法是利用 LVS 的 Heartbeat 组件。这允许每个配置好的、运行 Heartbeat 的控制器确保有且只有一个控制器声明处理引入请求的虚拟 IP 地址。

除了能够浮动服务 IP 地址外,控制器还需要能够监控执行实际工作负载处理的 realserver 的状态。控制器必须要了解哪些 realserver 可以一直用于工作负载处理。为监控 realserver 使用了 mon 包。继续阅读,了解关于 配置 Heartbeat配置 mon 的细节。

Realserver:这 些系统是提供 HA 服务的真正的 Web 服务器实例。使用多个 realserver 提供 HA 所需的服务。在本文的环境中,实现了 6 个 realserver,但是一旦 LVS 基础设施的其余部分就绪后,添加更多的 realserver 就是小事一桩了。

在本文中,假定 realserver 运行的都是 Apache Web Server,但是其他服务实现起来也同样容易(实际上,作为文中展示的方法的附加测试,受支持的 SSH 服务也很容易实现)。

使 用的 realserver 是常用的 Apache Web 服务器,只有一个明显的区别,即它们被配置为以类似 LVS 控制器的浮动 IP 地址的形式进行响应,或以控制器使用的浮动 IP 地址所对应的虚拟主机名的形式响应。更改 Apache 配置文件中的一行即可完成这一操作。

您 可以使用一个完全开源的软件组合复制这些配置,该软件组合包括,linux-ha.org 所提供的 Heartbeat 技术组件,以及通过 mon 和 Apache 进行监控的服务器。正如前面提到的,我们将使用 SUSE Linux Enterprise Server 测试配置。

LVS 场景中使用的所有机器都位于同一个子网中,使用的是 Network Address Translation (NAT) 配置。在 Linux Virtual Server Web 站点(请参阅 参考资料)上描述了很多其他网络结构;为简便起见我们使用 NAT。为了更加安全,您应该限制穿过防火墙的通信量,只允许浮动 IP 地址在 LVS 控制器之间传递。

Linux Virtual Server 套件提供了几种不同的方法以完成透明的 HA 后端基础设施。每种方法都各有利弊。LVS-NAT 操作控制器服务器的方式是,获取发往特定配置的端口的引入包,并动态地在包的头部重写目的地址。控制器本身并不处理包的数据内容,而是将其传给 realserver。包中的目的地址被重写为指向集群中的一个给定的 realserver。然后将包放回网络中以传递给 realserver,而 realserver 并没有意识到发生了什么情况。对于 realserver,它只是直接从外部接收请求。接着,realserver 的回复被发回控制器,在控制器中重写回复,使其具有客户机所指向的浮动 IP 地址的源地址,然后再发往原始客户机。

使用 LVS-NAT 方法意味着 realserver 需要简单的 TCP/IP 功能。LVS 操作的其他模式,即 LVS-DR 和 LVS-Tun,需要更加复杂的连网概念。选择 LVS-NAT 的最主要的好处是只需对 realserver 配置做很少量的更改。实际上,最难的部分是牢记适当地设置路由语句。

步骤 1:构建 realserver 图像

以构建 Linux 服务器实例池开始,每个实例运行 Apache Web 服务器,并确保服务器按预想的情况运作,将 Web 浏览器指向每个 realserver 的 IP 地址。通常,标准安装被配置为在自己的 IP 地址上侦听 80 端口(换言之,为每个 realserver 使用不同的 IP)。

接下来,在每个服务器上配置默认的 Web 页面以显示一个静态页面,其中包含了为页面提供服务的机器的主机名。这确保了您可以一直了解测试期间您所连接的机器。

为防万一,检查在这些系统上转发的 IP 是否为 OFF,方法是发出以下命令:

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

如果不是 OFF 并且您需要禁用它,请发出以下命令:

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

确保每个 realserver 都正常地侦听 http 端口 (80) 的一个简单方法是,使用外部系统并执行扫描。在一些与您的服务器连网的其他系统中,可以使用 nmap 工具以确保服务器执行侦听操作。

清单 1. 使用 nmap 确保服务器执行侦听操作

# nmap -P0 192.168.71.92

Starting nmap 3.70 ( http://www.insecure.org/nmap/ ) at 2006-01-13 16:58 EST
Interesting ports on 192.168.71.92:
(The 1656 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
22/tcp open ssh
80/tcp filtered http
111/tcp open rpcbind
631/tcp open ipp

要注意的是,某些组织不赞成使用端口扫描工具,如 nmap:在使用工具之前请获取组织的批准。

接下来,将 Web 浏览器指向每个 realserver 的实际 IP 地址,从而确保每个 realserver 按照预期为相应页面提供服务。完成此操作后请转到步骤 2。



回页首

步骤 2:安装和配置 LVS 控制器

现在,您可以构建所需的 3 个 LVS 控制器实例。如果您第一次为每个 LVS 控制器安装 SUSE Linux Enterprise Server 10,在初始安装时,请确保选择与 heartbeat、ipvsadm 和 mon 相关的高可用性包。如果您拥有现有的安装,您就可以一直使用包管理工具,如 YAST,在完成基础安装之后添加这些包。强烈建议您将每个 realserver 添加到 /etc/hosts 文件中。这将确保为引入请求提供服务时,不会产生 DNS 相关的延迟。

此时,再次检查每个目录是否都能对每个 realserver 执行即时的 ping 操作:

清单 2. 对 realserver 执行 Ping 操作

# ping -c 1 $REAL_SERVER_IP_1

# ping -c 1 $REAL_SERVER_IP_2

# ping -c 1 $REAL_SERVER_IP_3

# ping -c 1 $REAL_SERVER_IP_4

# ping -c 1 $REAL_SERVER_IP_5

# ping -c 1 $REAL_SERVER_IP_6

完成此操作后,从服务器中的本地包管理工具中安装 ipvsadm、Heartbeat 和 mon。回想一下,Heartbeat 将被用于控制器内部通信,而 mon 将被每个控制器用于维护关于每个 realserver 的状态信息。



回页首

步骤 3:在控制器上安装和配置 Heartbeat

如果您以前使用过 LVS,请记住,在 SLES10 上配置 Heartbeat Version 2 与在 SLES9 上配置 Heartbeat Version 1 截然不同。其中,Heartbeat Version 1 使用的文件(haresource、ha.cf 和 authkey)存储在 /etc/ha.d/ 目录中,而 Version 2 使用新的基于 XML 的 Cluster Information Base (CIB)。推荐的升级方法是使用 haresource 文件生成新的 cib.xml 文件。典型的 ha.cf 文件的内容如清单 3 所示。

我们从 SLES9 系统中获取 ha.cf 文件,并且为 Version 2 添加底部的 3 行(respawnpingdcrm)。如果您拥有现有的 version 1 配置,您也可以选择执行同样的操作。如果您要使用这些指令执行新安装,您可以复制清单 3 并进行修改以适应您的生产环境。

清单 3. /etc/ha.d/ha.cf config 文件样例

# Log to syslog as facility "daemon"
use_logd on
logfacility daemon

# List our cluster members (the realservers)
node litsha22
node litsha23
node litsha21

# Send one heartbeat each second
keepalive 3

# Warn when heartbeats are late
warntime 5

# Declare nodes dead after 10 seconds
deadtime 10

# Keep resources on their "preferred" hosts – needed for active/active
#auto_failback on

# The cluster nodes communicate on their heartbeat lan (.68.*) interfaces
ucast eth1 192.168.68.201
ucast eth1 192.168.68.202
ucast eth1 192.168.68.203

# Failover on network failures
# Make the default gateway on the public interface a node to ping
# (-m) -> For every connected node, add <integer> to the value set
# in the CIB, * Default=1
# (-d) -> How long to wait for no further changes to occur before
# updating the CIB with a changed attribute
# (-a) -> Name of the node attribute to set, * Default=pingd
respawn hacluster /usr/lib/heartbeat/pingd -m 100 -d 5s

# Ping our router to monitor ethernet connectivity
ping litrout71_vip

#Enable version 2 functionality supporting clusters with > 2 nodes
crm yes

respawn 指令在运行时指定某个程序的运行和监控。如果此程序退出时的退出码不是 100,程序将自动重启。第一个参数是运行程序的用户 id,第二个参数是要运行的程序。-m 参数将 pingd 属性设为从当前机器可获得的 ping 节点数的 100 倍,而 –d 参数在修改 CIB 中的 pingd 属性之前将延迟 5 秒。ping 指令用于声明 Heartbeat 的 PingNode,而 crm 指令指定了 Heartbeat 应运行 1.x-style 集群管理器或 2.x-style 集群管理器,后者支持 2 个以上的节点。

对于所有的控制器这个文件都应该相同。适当地设置权限使 hacluster 守护程序可以读取文件也绝对重要。否则将导致日志文件中出现大量难于调试的警告。

对于某个版本的 1-style Heartbeat 集群,haresources 文件指定了节点名和连网信息(浮动 IP、关联接口和广播)。对我们而言,此文件仍然没有变化:

litsha21 192.168.71.205/24/eth0/192.168.71.255

此文件将只用于生成 cib.xml 文件。

authkeys 文件指定了一个共享的密匙以允许控制器之间进行通信。共享密钥就是一个密码,所有的 heartbeat 节点都知道这个密码并使用它进行相互通信。密钥的使用避免了无关方对 heartbeat 服务器节点的影响。此文件也没有变化:

auth 1

1 sha1 ca0e08148801f55794b23461eb4106db

接下来的几步将向您展示如何将 version 1 的 haresources 文件转换为 version 2 的基于 XML 的配置格式 (cib.xml)。虽然可以直接复制并使用清单 4 中的配置文件作为起点,但是强烈建议您针对自己的部署进行配置调整。

为了将文件格式转换为部署中使用的基于 XML 的 CIB (Cluster Information Base) 文件,请发出以下命令:

python /usr/lib64/heartbeat/haresources2cib.py /etc/ha.d/haresources > /var/lib/heartbeat/crm/test.xml

将会生成一个类似清单 4 所示的配置文件,并置于 /var/lib/heartbeat/crm/test.xml 中。

清单 4. CIB.xml 样例文件

<cib admin_epoch="0" have_quorum="true" num_peers="3" cib_feature_revision="1.3"
generated="true" ccm_transition="7" dc_uuid="114f3ad1-f18a-4bec-9f01-7ecc4d820f6c"
epoch="280" num_updates="5205" cib-last-written="Tue Apr 3 16:03:33 2007">
<configuration>
<crm_config>
<cluster_property_set id="cib-bootstrap-options">
<attributes>
<nvpair id="cib-bootstrap-options-symmetric_cluster"
name="symmetric_cluster" value="true"/>
<nvpair id="cib-bootstrap-options-no_quorum_policy"
name="no_quorum_policy" value="stop"/>
<nvpair id="cib-bootstrap-options-default_resource_stickiness"
name="default_resource_stickiness" value="0"/>
<nvpair id="cib-bootstrap-options-stonith_enabled"
name="stonith_enabled" value="false"/>
<nvpair id="cib-bootstrap-options-stop_orphan_resources"
name="stop_orphan_resources" value="true"/>
<nvpair id="cib-bootstrap-options-stop_orphan_actions"
name="stop_orphan_actions" value="true"/>
<nvpair id="cib-bootstrap-options-remove_after_stop"
name="remove_after_stop" value="false"/>
<nvpair id="cib-bootstrap-options-transition_idle_timeout"
name="transition_idle_timeout" value="5min"/>
<nvpair id="cib-bootstrap-options-is_managed_default"
name="is_managed_default" value="true"/>
<attributes>
<cluster_property_set>
<crm_config>
<nodes>
<node uname="litsha21" type="normal" id="01ca9c3e-8876-4db5-ba33-a25cd46b72b3">
<instance_attributes id="standby-01ca9c3e-8876-4db5-ba33-a25cd46b72b3">
<attributes>
<nvpair name="standby" id="standby-01ca9c3e-8876-4db5-ba33-a25cd46b72b3"
value="off"/>
<attributes>
<instance_attributes>
<node>
<node uname="litsha23" type="normal" id="dc9a784f-3325-4268-93af-96d2ab651eac">
<instance_attributes id="standby-dc9a784f-3325-4268-93af-96d2ab651eac">
<attributes>
<nvpair name="standby" id="standby-dc9a784f-3325-4268-93af-96d2ab651eac"
value="off"/>
<attributes>
<instance_attributes>
<node>
<node uname="litsha22" type="normal" id="114f3ad1-f18a-4bec-9f01-7ecc4d820f6c">
<instance_attributes id="standby-114f3ad1-f18a-4bec-9f01-7ecc4d820f6c">
<attributes>
<nvpair name="standby" id="standby-114f3ad1-f18a-4bec-9f01-7ecc4d820f6c"
value="off"/>
<attributes>
<instance_attributes>
<node>
<nodes>
<resources>
<primitive class="ocf" provider="heartbeat" type="IPaddr" id="IPaddr_1">
<operations>
<op id="IPaddr_1_mon" interval="5s" name="monitor" timeout="5s"/>
<operations>
<instance_attributes id="IPaddr_1_inst_attr">
<attributes>
<nvpair id="IPaddr_1_attr_0" name="ip" value="192.168.71.205"/>
<nvpair id="IPaddr_1_attr_1" name="netmask" value="24"/>
<nvpair id="IPaddr_1_attr_2" name="nic" value="eth0"/>
<nvpair id="IPaddr_1_attr_3" name="broadcast" value="192.168.71.255"/>
<attributes>
<instance_attributes>
<primitive>
<resources>
<constraints>
<rsc_location id="rsc_location_IPaddr_1" rsc="IPaddr_1">
<rule id="prefered_location_IPaddr_1" score="200">
<expression attribute="#uname" id="prefered_location_IPaddr_1_expr"
operation="eq" value="litsha21"/>
<rule>
<rsc_location>
<rsc_location id="my_resource:connected" rsc="IPaddr_1">
<rule id="my_resource:connected:rule" score_attribute="pingd">
<expression id="my_resource:connected:expr:defined" attribute="pingd"
operation="defined"/>
<rule>
<rsc_location>
<constraints>
<configuration>
<cib>

一旦生成配置文件后,将 test.xml 移到 cib.xml 中,将所有者改为 hacluster,将组改为 haclient,然后重启 heartbeat 进程。

现已完成 heartbeat 配置,对 heartbeat 进行设置,使其在每个控制器的引导阶段启动。为此,在每个控制器上发出以下命令(或相对您的发行版的等效命令):

# chkconfig heartbeat on

重启每个 LVS 控制器以确保 heartbeat 服务在引导阶段正常启动。通过首先暂停保存浮动资源 IP 地址的机器,您可以等候其他 LVS Director 映像建立 quorum,然后在几秒钟内实例化最新选择的主节点上的服务地址。当您将暂停的控制器映像重新联机时,机器将在所有的节点间重新建立 quorum,此时浮动资源 IP 可能传输回来。整个过程只会耗费几秒钟。

另外,此时,您可能希望使用图形化工具处理 heartbeat 进程 hb_gui(如图 2 所示),手动地将 IP 地址在集群中移动,方法是将各种节点设置为备用或活动状态。多次重试这些步骤,禁用并重新启用活动的或不活动的各种机器。因为先前选中了配置策略,只要可 以建立 quorum,并且至少有一个节点合格,那么浮动资源 IP 地址就保持正常运作。在测试期间,您可以使用简单的 ping 确保不会发生丢失包的情况。当您完成试验后,应该对配置的健壮性有一个深刻的体会。在继续操作之前请确保浮动资源 IP 的 HA 配置适当。

图 2. 用于 heartbeat 进程的图形化配置工具 hb_gui
图 2. 用于 heartbeat 进程的图形化配置工具 hb_gui

图 2 展示了登录后的图形控制台的外观,上面显示了托管资源和相关的配置选项。注意,当您首次启动应用程序时,必须登录到 hb_gui 控制台;使用何种凭证将取决于您的部署。

注意,图 2 中 litsha2* 系统集群中的每个节点都处于运行状态。标记为 litsha21 的系统目前是活动节点,如 (IPaddr_1) 正下方锯齿状的附加资源所示。

另外要注意标记为 “No Quorum Policy” 的选项的值为 “stop”。这指的是任何单独的节点将释放它所拥有的资源。这个决策的含义是,在任何给定时间,必须有 2 个 heartbeat 节点是活动状态,以便建立 quorum(换言之,一种 “少数服从多数” 的投票规则)。即使只有一个节点是活动的,完全运行的节点也会由于网络故障丢失它与同级系统之间的连接,或者,如果两个非活动的同级系统同时暂停,资源将 被自动释放。



回页首