文章来源:http://www.ibm.com/developerworks/cn/linux/l-linux-ha/index.html

使用简单的 5 个步骤设置 Web 服务器集群

使用 Linux Virtual Server 和 Linux-HA.org 的 Heartbeat 进行构建和运行

文档选项

将此页作为电子邮件发送

级别: 中级

Eli Dow (emdow@us.ibm.com), 软件工程师, IBM Linux Test and Integration Center
Frank LeFevre (lefevre@us.ibm.com), 高级软件工程师, IBM

2007 年 9 月 17 日

使用 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

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

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

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


回页首

步骤 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),但是最后的步骤已为此打下基础。


回页首

故障诊断

活动节点在一个 HA 集群中不能正常运作有多种原因,自愿的或非自愿的。节点可能丢失与其他节点的网络连接,heartbeat 进程可能被停止,可能出现任何环境事件等等。要故意地让活动节点失效,您可以要求该节点暂停,或将其设为备用模式,方法是使用 hb_gui(完全关闭)命令。如果您希望测试环境的健壮性,您可能需要一些更激进的方式。

指示器和故障恢复

系统管理员可以使用两种日志文件指示器配置 Linux HA heartbeat 系统。日志文件与系统是否为浮动资源 IP 地址的接收方有关。没有接收浮动资源 IP 地址的集群成员的日志结果类似于:

清单 10. 落选者的日志结果

litsha21:~ # cat  /var/log/messages
Jan 16 12:00:20 litsha21 heartbeat: [3057]: WARN: node litsha23: is dead
Jan 16 12:00:21 litsha21 cib: [3065]: info: mem_handle_event: Got an event
OC_EV_MS_NOT_PRIMARY from ccm
Jan 16 12:00:21 litsha21 cib: [3065]: info: mem_handle_event: instance=13, nodes=3,
new=1, lost=0, n_idx=0, new_idx=3, old_idx=6
Jan 16 12:00:21 litsha21 crmd: [3069]: info: mem_handle_event: Got an event
OC_EV_MS_NOT_PRIMARY from ccm
Jan 16 12:00:21 litsha21 crmd: [3069]: info: mem_handle_event: instance=13, nodes=3,
new=1, lost=0, n_idx=0, new_idx=3, old_idx=6
Jan 16 12:00:21 litsha21 crmd: [3069]: info: crmd_ccm_msg_callback:callbacks.c Quorum
lost after event=NOT PRIMARY (id=13)
Jan 16 12:00:21 litsha21 heartbeat: [3057]: info: Link litsha23:eth1 dead.
Jan 16 12:00:38 litsha21 ccm: [3064]: debug: quorum plugin: majority
Jan 16 12:00:38 litsha21 ccm: [3064]: debug: cluster:linux-ha, member_count=2,
member_quorum_votes=200
Jan 16 12:00:38 litsha21 ccm: [3064]: debug: total_node_count=3,
total_quorum_votes=300
.................. Truncated For Brevity ..................
Jan 16 12:00:40 litsha21 crmd: [3069]: info: update_dc:utils.c Set DC to litsha21
(1.0.6)
Jan 16 12:00:41 litsha21 crmd: [3069]: info: do_state_transition:fsa.c litsha21:
State transition S_INTEGRATION ->
S_FINALIZE_JOIN [ input=I_INTEGRATED cause=C_FSA_INTERNAL
origin=check_join_state ]
Jan 16 12:00:41 litsha21 crmd: [3069]: info: do_state_transition:fsa.c All 2 cluster
nodes responded to the join offer.
Jan 16 12:00:41 litsha21 crmd: [3069]: info: update_attrd:join_dc.c Connecting to
attrd...
Jan 16 12:00:41 litsha21 cib: [3065]: info: sync_our_cib:messages.c Syncing CIB to
all peers
Jan 16 12:00:41 litsha21 attrd: [3068]: info: attrd_local_callback:attrd.c Sending
full refresh
.................. Truncated For Brevity ..................
Jan 16 12:00:43 litsha21 pengine: [3112]: info: unpack_nodes:unpack.c Node litsha21
is in standby-mode
Jan 16 12:00:43 litsha21 pengine: [3112]: info: determine_online_status:unpack.c Node
litsha21 is online
Jan 16 12:00:43 litsha21 pengine: [3112]: info: determine_online_status:unpack.c Node
litsha22 is online
Jan 16 12:00:43 litsha21 pengine: [3112]: info: IPaddr_1
(heartbeat::ocf:IPaddr): Stopped
Jan 16 12:00:43 litsha21 pengine: [3112]: notice: StartRsc:native.c  litsha22
Start IPaddr_1
Jan 16 12:00:43 litsha21 pengine: [3112]: notice: Recurring:native.c litsha22
IPaddr_1_monitor_5000
Jan 16 12:00:43 litsha21 pengine: [3112]: notice: stage8:stages.c Created transition
graph 0.
.................. Truncated For Brevity ..................
Jan 16 12:00:46 litsha21 mgmtd: [3070]: debug: update cib finished
Jan 16 12:00:46 litsha21 crmd: [3069]: info: do_state_transition:fsa.c litsha21:
State transition S_TRANSITION_ENGINE ->
S_IDLE [ input=I_TE_SUCCESS cause=C_IPC_MESSAGE origin=do_msg_route ]
Jan 16 12:00:46 litsha21 cib: [3118]: info: write_cib_contents:io.c Wrote version
0.53.593 of the CIB to disk (digest: 83b00c386e8b67c42d033a4141aaef90)

如清单 10 所示,获取了一份名单,有足够的 quorum 成员可以投票。获取投票,不需要执行其他操作即可恢复正常运作。

相反,接收了浮动资源 IP 地址的集群成员的日志结果如下:

清单 11. 资源持有者的日志文件

litsha22:~ # cat  /var/log/messages
Jan 16 12:00:06 litsha22 syslog-ng[1276]: STATS: dropped 0
Jan 16 12:01:51 litsha22 heartbeat: [3892]: WARN: node litsha23: is dead
Jan 16 12:01:51 litsha22 heartbeat: [3892]: info: Link litsha23:eth1 dead.
Jan 16 12:01:51 litsha22 cib: [3900]: info: mem_handle_event: Got an event
OC_EV_MS_NOT_PRIMARY from ccm
Jan 16 12:01:51 litsha22 cib: [3900]: info: mem_handle_event: instance=13, nodes=3,
new=3, lost=0, n_idx=0, new_idx=0, old_idx=6
Jan 16 12:01:51 litsha22 crmd: [3904]: info: mem_handle_event: Got an event
OC_EV_MS_NOT_PRIMARY from ccm
Jan 16 12:01:51 litsha22 crmd: [3904]: info: mem_handle_event: instance=13, nodes=3,
new=3, lost=0, n_idx=0, new_idx=0, old_idx=6
Jan 16 12:01:51 litsha22 crmd: [3904]: info: crmd_ccm_msg_callback:callbacks.c Quorum
lost after event=NOT PRIMARY (id=13)
Jan 16 12:02:09 litsha22 ccm: [3899]: debug: quorum plugin: majority
Jan 16 12:02:09 litsha22 crmd: [3904]: info: do_election_count_vote:election.c
Election check: vote from litsha21
Jan 16 12:02:09 litsha22 ccm: [3899]: debug: cluster:linux-ha, member_count=2,
member_quorum_votes=200
Jan 16 12:02:09 litsha22 ccm: [3899]: debug: total_node_count=3,
total_quorum_votes=300
Jan 16 12:02:09 litsha22 cib: [3900]: info: mem_handle_event: Got an event
OC_EV_MS_INVALID from ccm
Jan 16 12:02:09 litsha22 cib: [3900]: info: mem_handle_event: no mbr_track info
Jan 16 12:02:09 litsha22 cib: [3900]: info: mem_handle_event: Got an event
OC_EV_MS_NEW_MEMBERSHIP from ccm
Jan 16 12:02:09 litsha22 cib: [3900]: info: mem_handle_event: instance=14, nodes=2,
new=0, lost=1, n_idx=0, new_idx=2, old_idx=5
Jan 16 12:02:09 litsha22 cib: [3900]: info: cib_ccm_msg_callback:callbacks.c
LOST: litsha23
Jan 16 12:02:09 litsha22 cib: [3900]: info: cib_ccm_msg_callback:callbacks.c
PEER: litsha21
Jan 16 12:02:09 litsha22 cib: [3900]: info: cib_ccm_msg_callback:callbacks.c
PEER: litsha22
.................. Truncated For Brevity ..................
Jan 16 12:02:12 litsha22 crmd: [3904]: info: update_dc:utils.c Set DC to litsha21
(1.0.6)
Jan 16 12:02:12 litsha22 crmd: [3904]: info: do_state_transition:fsa.c litsha22:
State transition S_PENDING -> S_NOT_DC [ input=I_NOT_DC cause=C_HA_MESSAGE
origin=do_cl_join_finalize_respond ]
Jan 16 12:02:12 litsha22 cib: [3900]: info: cib_diff_notify:notify.c Update (client:
3069, call:25): 0.52.585 ->
0.52.586 (ok)
.................. Truncated For Brevity ..................
Jan 16 12:02:14 litsha22 IPaddr[3998]: INFO: /sbin/ifconfig eth0:0 192.168.71.205
netmask 255.255.255.0 broadcast 192.168.71.255
Jan 16 12:02:14 litsha22 IPaddr[3998]: INFO: Sending Gratuitous Arp for
192.168.71.205 on eth0:0 [eth0]
Jan 16 12:02:14 litsha22 IPaddr[3998]: INFO: /usr/lib64/heartbeat/send_arp -i 500 -r
10 -p
/var/run/heartbeat/rsctmp/send_arp/send_arp-192.168.71.205 eth0 192.168.71.205 auto
192.168.71.205 ffffffffffff
Jan 16 12:02:14 litsha22 crmd: [3904]: info: process_lrm_event:lrm.c LRM operation
(3) start_0 on IPaddr_1 complete
Jan 16 12:02:14 litsha22 kernel: send_arp uses obsolete (PF_INET,SOCK_PACKET)
Jan 16 12:02:14 litsha22 kernel: klogd 1.4.1, ---------- state change ----------
Jan 16 12:02:14 litsha22 kernel: NET: Registered protocol family 17
Jan 16 12:02:15 litsha22 crmd: [3904]: info: do_lrm_rsc_op:lrm.c Performing op
monitor on IPaddr_1 (interval=5000ms, key=0:f9d962f0-4ed6-462d-a28d-e27b6532884c)
Jan 16 12:02:15 litsha22 cib: [3900]: info: cib_diff_notify:notify.c Update (client:
3904, call:18): 0.53.591 ->
0.53.592
(ok)
Jan 16 12:02:15 litsha22 mgmtd: [3905]: debug: update cib finished

如清单 11 所示,/var/log/messages 文件展示了此节点已经获得了浮动资源。ifconfig 行显示将动态创建 eth0:0 设备以维持服务。

如清单 11 所示,获取了一份名单,有足够的 quorum 成员可以投票。获取投票后,发出的 ifconfig 命令索要浮动资源 IP 地址。

另外一种指示何时发生故障的方法是,您可以登录到任何一个集群成员并执行 hb_gui 命令。使用这种方法,您可以通过亲自查找拥有浮动资源的系统来确定故障发生时间。

最后,如果我们不展示一个非 quorum 情形的样例日志文件似乎有些说不过去。如果某个单一节点无法与任何一个其他节点进行通信,那么它就丢失了 quorum(因为在 3 个成员的投票中 2/3 是多数)。在这种情况下,节点获悉已丢失 quorum,然后调用 no quorum policy 处理程序。清单 12 展示了一个来自这类事件的日志文件示例。丢失 quorum 时,日志条目将会有所显示。显示此日志条目的集群节点认为自己不具有浮动资源。ifconfig down 语句将释放资源。

清单 12. 显示丢失 quorum 的日志条目

litsha22:~ # cat /var/log/messages
....................
Jan 16 12:06:12 litsha22 ccm: [3899]: debug: quorum plugin: majority
Jan 16 12:06:12 litsha22 ccm: [3899]: debug: cluster:linux-ha, member_count=1,
member_quorum_votes=100
Jan 16 12:06:12 litsha22 ccm: [3899]: debug: total_node_count=3,
total_quorum_votes=300
.................. Truncated For Brevity ..................
Jan 16 12:06:12 litsha22 crmd: [3904]: info: crmd_ccm_msg_callback:callbacks.c Quorum
lost after event=INVALID (id=15)
Jan 16 12:06:12 litsha22 crmd: [3904]: WARN: check_dead_member:ccm.c Our DC node
(litsha21) left the cluster
.................. Truncated For Brevity ..................
Jan 16 12:06:14 litsha22 IPaddr[5145]: INFO: /sbin/route -n del -host 192.168.71.205
Jan 16 12:06:15 litsha22 lrmd: [1619]: info: RA output: (IPaddr_1:stop:stderr)
SIOCDELRT: No such process
Jan 16 12:06:15 litsha22 IPaddr[5145]: INFO: /sbin/ifconfig eth0:0 192.168.71.205
down
Jan 16 12:06:15 litsha22 IPaddr[5145]: INFO: IP Address 192.168.71.205 released
Jan 16 12:06:15 litsha22 crmd: [3904]: info: process_lrm_event:lrm.c LRM operation
(6) stop_0 on IPaddr_1 complete
Jan 16 12:06:15 litsha22 cib: [3900]: info: cib_diff_notify:notify.c Update (client:
3904, call:32): 0.54.599 ->
0.54.600 (ok)
Jan 16 12:06:15 litsha22 mgmtd: [3905]: debug: update cib finished

如清单 12 所示,当某个给定节点丢失 quorum 时,它将放弃所有资源,因为选择了 no quorum policy 配置。是否选择 no quorum policy 完全取决于您自己。

Fail-back 动作和消息

正确配置的 Linux HA 系统的一个更有趣的含义是,您不需要执行任何操作就可重新实例化集群成员。只需要激活 Linux 实例即可让节点自动地重新加入其他节点。如果您配置了一个主节点(即,一个可以优先于其他节点获得浮动资源的节点),它将自动重新获得浮动资源。非优先的系统将只是加入合格节点池并正常运作。

将其他的 Linux 实例往回添加到池中将使每个节点获得通知,并且如果可能的话,重新建立 quorum。如果可以重新建立 quorum,那么将在某个节点上重新建立浮动资源。

清单 13. 重新建立 Quorum

litsha22:~ # tail -f /var/log/messages
Jan 16 12:09:02 litsha22 heartbeat: [3892]: info: Heartbeat restart on node litsha21
Jan 16 12:09:02 litsha22 heartbeat: [3892]: info: Link litsha21:eth1 up.
Jan 16 12:09:02 litsha22 heartbeat: [3892]: info: Status update for node litsha21:
status init
Jan 16 12:09:02 litsha22 heartbeat: [3892]: info: Status update for node litsha21:
status up
Jan 16 12:09:22 litsha22 heartbeat: [3892]: debug: get_delnodelist: delnodelist=
Jan 16 12:09:22 litsha22 heartbeat: [3892]: info: Status update for node litsha21:
status active
Jan 16 12:09:22 litsha22 cib: [3900]: info: cib_client_status_callback:callbacks.c
Status update: Client litsha21/cib now has status [join]
Jan 16 12:09:23 litsha22 heartbeat: [3892]: WARN: 1 lost packet(s) for [litsha21]
[36:38]
Jan 16 12:09:23 litsha22 heartbeat: [3892]: info: No pkts missing from litsha21!
Jan 16 12:09:23 litsha22 crmd: [3904]: notice:
crmd_client_status_callback:callbacks.c Status update: Client litsha21/crmd now has
status [online]
....................
Jan 16 12:09:31 litsha22 crmd: [3904]: info: crmd_ccm_msg_callback:callbacks.c Quorum
(re)attained after event=NEW MEMBERSHIP (id=16)
Jan 16 12:09:31 litsha22 crmd: [3904]: info: ccm_event_detail:ccm.c NEW MEMBERSHIP:
trans=16, nodes=2, new=1, lost=0 n_idx=0, new_idx=2, old_idx=5
Jan 16 12:09:31 litsha22 crmd: [3904]: info: ccm_event_detail:ccm.c     CURRENT:
litsha22 [nodeid=1, born=13]
Jan 16 12:09:31 litsha22 crmd: [3904]: info: ccm_event_detail:ccm.c     CURRENT:
litsha21 [nodeid=0, born=16]
Jan 16 12:09:31 litsha22 crmd: [3904]: info: ccm_event_detail:ccm.c     NEW:
litsha21 [nodeid=0, born=16]
Jan 16 12:09:31 litsha22 cib: [3900]: info: cib_diff_notify:notify.c Local-only
Change (client:3904, call: 35):
0.54.600 (ok)
Jan 16 12:09:31 litsha22 mgmtd: [3905]: debug: update cib finished
....................
Jan 16 12:09:34 litsha22 crmd: [3904]: info: update_dc:utils.c Set DC to litsha22
(1.0.6)
Jan 16 12:09:35 litsha22 cib: [3900]: info: sync_our_cib:messages.c Syncing CIB to
litsha21
Jan 16 12:09:35 litsha22 crmd: [3904]: info: do_state_transition:fsa.c litsha22:
State transition S_INTEGRATION ->
S_FINALIZE_JOIN [ input=I_INTEGRATED cause=C_FSA_INTERNAL origin=check_join_state ]
Jan 16 12:09:35 litsha22 crmd: [3904]: info: do_state_transition:fsa.c All 2 cluster
nodes responded to the join offer.
Jan 16 12:09:35 litsha22 attrd: [3903]: info: attrd_local_callback:attrd.c Sending
full refresh
Jan 16 12:09:35 litsha22 cib: [3900]: info: sync_our_cib:messages.c Syncing CIB to
all peers
.........................
Jan 16 12:09:37 litsha22 tengine: [5119]: info: send_rsc_command:actions.c Initiating
action 4: IPaddr_1_start_0 on litsha22
Jan 16 12:09:37 litsha22 tengine: [5119]: info: send_rsc_command:actions.c Initiating
action 2: probe_complete on litsha21
Jan 16 12:09:37 litsha22 crmd: [3904]: info: do_lrm_rsc_op:lrm.c Performing op start
on IPaddr_1 (interval=0ms,
key=2:c5131d14-a9d9-400c-a4b1-60d8f5fbbcce)
Jan 16 12:09:37 litsha22 pengine: [5120]: info: process_pe_message:pengine.c
Transition 2: PEngine Input stored in: /var/lib/heartbeat/pengine/pe-input-72.bz2
Jan 16 12:09:37 litsha22 IPaddr[5196]: INFO: /sbin/ifconfig eth0:0 192.168.71.205
netmask 255.255.255.0 broadcast 192.168.71.255
Jan 16 12:09:37 litsha22 IPaddr[5196]: INFO: Sending Gratuitous Arp for
192.168.71.205 on eth0:0 [eth0]
Jan 16 12:09:37 litsha22 IPaddr[5196]: INFO: /usr/lib64/heartbeat/send_arp -i 500 -r
10 -p
/var/run/heartbeat/rsctmp/send_arp/send_arp-192.168.71.205 eth0 192.168.71.205 auto
192.168.71.205 ffffffffffff
Jan 16 12:09:37 litsha22 crmd: [3904]: info: process_lrm_event:lrm.c LRM operation
(7) start_0 on IPaddr_1 complete
Jan 16 12:09:37 litsha22 cib: [3900]: info: cib_diff_notify:notify.c Update (client:
3904, call:46): 0.55.607 -> 0.55.608 (ok)
Jan 16 12:09:37 litsha22 mgmtd: [3905]: debug: update cib finished
Jan 16 12:09:37 litsha22 tengine: [5119]: info: te_update_diff:callbacks.c Processing
diff (cib_update): 0.55.607 -> 0.55.608
Jan 16 12:09:37 litsha22 tengine: [5119]: info: match_graph_event:events.c Action
IPaddr_1_start_0 (4) confirmed
Jan 16 12:09:37 litsha22 tengine: [5119]: info: send_rsc_command:actions.c Initiating
action 5: IPaddr_1_monitor_5000 on litsha22
Jan 16 12:09:37 litsha22 crmd: [3904]: info: do_lrm_rsc_op:lrm.c Performing op
monitor on IPaddr_1 (interval=5000ms, key=2:c5131d14-a9d9-400c-a4b1-60d8f5fbbcce)
Jan 16 12:09:37 litsha22 cib: [5268]: info: write_cib_contents:io.c Wrote version
0.55.608 of the CIB to disk (digest: 98cb6685c25d14131c49a998dbbd0c35)
Jan 16 12:09:37 litsha22 crmd: [3904]: info: process_lrm_event:lrm.c LRM operation
(8) monitor_5000 on IPaddr_1 complete
Jan 16 12:09:38 litsha22 cib: [3900]: info: cib_diff_notify:notify.c Update (client:
3904, call:47): 0.55.608 -> 0.55.609 (ok)
Jan 16 12:09:38 litsha22 mgmtd: [3905]: debug: update cib finished

在清单 13 中,您可以看见 quorum 已被重新建立。重新建立 quorum 后,执行投票,而 litsha22 将变为具有浮动资源的活动节点。


回页首

结束语

分享这篇文章……

提交到 Digg
发布到 el.icio.us

[转]使用简单的 5 个步骤设置 Web 服务器集群相关推荐

  1. 使用简单的5个步骤设置 Web服务器集群

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

  2. 开源OA:手把手教你搭建OA办公系统(19)-系统上线之服务器集群设置

    O2OA是一款全开源的企业信息化开发平台,作为OA系统开发平台,O2OA着力于帮助企业降低信息化系统开发成本,帮助企业提升信息化能力.本系列主要以实战形式向大家介绍使用开源OA平台搭建一套协同办公系统 ...

  3. 如何在CentOS 7上使用HAproxy Loadbalancer设置Percona XtraDB集群(负载均衡)

    翻译&转载来源:https://linoxide.com/cluster/setup-percona-cluster-haproxy-centos-7/ 如何在CentOS 7上使用HApro ...

  4. keepalived架设简单高可用的nginx的web服务器   ----那些你不知道的秘密

    keepalived架设简单高可用的nginx的web服务器----那些你不知道的秘密 如果負載均衡軟件不使用LVS的話,那麼keepalived的配置是相當的簡單的,只需要配置好MASTER和SLA ...

  5. ActiveMQ此例简单介绍基于docker的activemq安装与集群搭建

    ActiveMQ拓展连接 此例简单介绍基于Docker的activemq安装与集群搭建 一 :安装 1.获取activemq镜像 docker pull webcenter/activemq 2.启动 ...

  6. 如何设置 Web 服务器的权限之iis

    来源:http://www.study-code.com/server/maintain/75655.htm 如何设置 Web 服务器的权限?如果Web服务器的权限没有设置好,那么网站就会出现漏洞并且 ...

  7. ES安装的详细步骤、ES的集群搭建以及ElasticSearch安装时可能出现的问题

    目录 什么是es? 正排索引和倒排索引 安装 ElasticSearch的简单步骤 环境需求 安装ES 下载 设置虚拟机内存 创建用户 安装 ES的目录结构及其作用 配置文件以及作用 修改配置文件el ...

  8. 利用自己的电脑设置web服务器建网站_win7系统篇,win7系统利用iis搭建web服务器实现信息浏览资源共享的操作方法...

    很多小伙伴都遇到过对win7系统利用iis搭建web服务器实现信息浏览资源共享进行设置的困惑吧,一些朋友看过网上对win7系统利用iis搭建web服务器实现信息浏览资源共享设置的零散处理方法,并没有完 ...

  9. kafka的简单介绍以及docker-compose部署单主机Kafka集群

    Kafka简单介绍 Kafka是由Apache软件基金会开发的一个分布式.分区的.多副本的.多订阅者的开源流处理平台,由Scala和Java编写.Kafka是一种高吞吐量的分布式发布订阅消息系统,它可 ...

最新文章

  1. 深度学习的数学 (6)误差反向传播法必需的链式法则
  2. subline text 快捷键
  3. Linux设置ssh免密码登录
  4. MD5Init-MD5Update-MD5Final
  5. python源码中的学习笔记_第7章_字符串
  6. visualbox 安装 ubuntu 18.04 后续操作:设置ip、换源、安装LAMP、phpmyadmin
  7. loadrunner中定义数组
  8. STM32个人笔记-电源管理
  9. html显示空间图片,qq空间显示不出来 为什么QQ空间有些图片显示不了
  10. 百变鹏仔缤纷彩色文字广告位代码美化版
  11. 物联网挑战赛【从零到一】
  12. 渐近线(泪滴)能改善信号质量吗?
  13. cad引出线段lisp_利用lisp给CAD直线取整?
  14. MVG读书笔记——几何变换续
  15. xctf攻防世界 MISC高手进阶区 Ditf
  16. GeoServer 图层访问控制身份验证
  17. GT工具中用到的英文词解释
  18. 比例导引律Matlab程序,是否有关于比例导引方面的仿真程序?
  19. 网络安全——TCP/IP协议簇中的安全协议
  20. 微信电脑版如何修改聊天记录等文件存放位置 电脑版微信在哪里修改存储地址

热门文章

  1. 跟大家分享下团队协作工具leangoo
  2. AirServer最新mac版投屏安装许可证
  3. 我好像很久没安利软件给大家啦,今天给大家种草一款OmniFocus for Mac(GTD时间管理工具)标准版
  4. 网易新闻app 喜马拉雅app数据接口
  5. 仿喜马拉雅app底部导航栏五个按钮-clipChildren属性
  6. 华夏相机/臻识相机车牌识别器同LED屏幕语音对接以及javaDemo
  7. Springsecurity使用浏览器登录失败返回302(跨域问题),前后端分离
  8. 基于python3.6+tensorflow2.2的讽刺数据集的词条化和序列化
  9. 【C语言】数组——矩阵对换
  10. 线性代数---全排列和对换