内容:
我们使用的开放[url=http://www.pccode.net].net" class="wordstyle"源码软件
有关 LDAp 的一些背景知识
群集软件和配置
一般 Heartbeat 准备
服务脚本
测试
故障转移后的恢复
Apache 的 LDAp 配置
结束语
参考资料
在 Linux 专区还有:
教程
工具与产品
代码与组件
文章
关于作者
Jay D. Allen 和 Cliff White 在 IBM Linux Competency Center 工作。白天,Jay D. Allen 为 IBM 从事 IT 的前沿工作,主要是关于 Linux 的。晚间,Jay 就摆弄一些过时的 IT 产品,主要是 DEC pDp-11 和其它一些“古董”。可以通过 allen5@us.ibm.com 与他联系。Clifford White 是 IBM 的解决方案工程师,为 IBM Linux Competency Center 工作。可以通过 ctwhite@us.ibm.com 与他联系。
当某个组织添加应用程序和服务时,集中进行认证和密码服务可以提高安全性,并减少管理和开发人员的难题。但是,将所有服务合并到一台服务器会导致可靠性问题。高可用性对于企业认证服务尤为重要,因为在许多情况下,当认证停止工作时,整个企业将陷于停顿。本文描述了我们该如何使用开放[url=http://www.pccode.net].net" class="wordstyle"源码软件创建可靠的、高度可用的认证服务器。
我们使用的开放[url=http://www.pccode.net].net" class="wordstyle"源码软件
我们使用 LDAp(轻量级目录访问协议(Lightweight Directory Access protocol))服务器来提供各种应用程序都可以订阅的认证服务。为了提供高度可用的 LDAp 服务器,我们使用了 Linux-HA 倡议(www.linux-ha.org)的 heartbeat 软件包。我们还提供了一个设置 Apache web 服务器以使用 LDAp 认证的示例。
有关 LDAp 的一些背景知识
我们使用 OpenLDAp 软件包(www.openldap.org),几个 Linux 分发版(distribution)都包含该软件包。它同 RedHat 7.1 一起提供,目前可下载的版本是 2.0.11。
RFC 2251 和 2253 定义了 LDAp 标准。现有的几个 LDAp 商业实现包括密歇根大学和 Netscape 实现。创建 OpenLDAp 基金会是要“共同致力于开发健壮的、商业级别的、功能完善的和开放[url=http://www.pccode.net].net" class="wordstyle"源码的 LDAp 应用程序和开发工具套件”(请参阅 www.openldap.org)。OpenLDAp 版本 1.0 发布于 1998 年 8 月。目前的主要版本是 2.0,发布于 2000 年 8 月 31 日,并且添加了 LDApv3 支持。
象任何优秀的网络服务一样,LDAp 被设计成可以跨多个服务器运行。本文使用了 LDAp 的两个功能 — 复制和参照。
参照机制允许您跨多个服务器分割 LDAp 名称空间,并且以层次结构的方式安排 LDAp 服务器。对于特定的目录名称空间,LDAp 只允许有一个主服务器。
复制是由 OpenLDAp 复制守护程序 slurpd 驱动的。Slurpd 会定期运行,检查主服务器的日志文件以获知任何更新。然后将更新推送到从服务器。读取请求可以由任一服务器应答,而更新只能由主服务器执行。对从服务器的更新请求会生成一个参照消息,该消息将提供主服务器的地址。跟踪参照及重新尝试更新是客户机的职责。OpenLDAp 无内置的方法来分发跨复制服务器的查询,因此您必须使用 Ip 喷射器(sprayer)/扇出(fanout)程序,例如 balance。
为了实现可靠性目标,我们将两台服务器连在一起形成群集。我们可以使用服务器之间共享的存储器和一份可维护的数据副本。但是为了简单起见,我们选择执行非共享实现。LDAp 数据库通常很小,且更新频率很低(提示:如果您的 LDAp 数据集是大型的,请考虑利用参照将名称空间划分成多个较小的部分)。当重新启动故障节点时,非共享设置确实需要多费心一些:在重新启动之前,任何新的更改都必须添加到发生故障的节点的数据库中。稍后我们将显示一个示例。
群集软件和配置
首先,让我们澄清一个小小的混淆。大多数 HA(高可用性)群集都带有称为“心跳(heartbeat)”的系统持活功能。HA 软件使用心跳来监控群集中节点的“健康”状况。Linux-HA(www.linux-ha.org)小组提供了开放[url=http://www.pccode.net].net" class="wordstyle"源码群集软件。他们的软件包称为 Heartbeat(目前是 Heartbeat-0.4.9)。这会导致一些可以理解的混淆(是的,它有时就令我困惑)。本文将 Linux-HA 软件包称为“Heartbeat”,而将一般的概念称为“心跳”。
Linux-HA 项目开始于 1998 年,是 Linux-HA HOWTO(Haranld Milz 著)的产物。该项目目前由 Alan Robertson 领导,许多其他代码提供者也参与其中。版本 0.4.9 于 2001 年初发布。
Heartbeat 通过通信介质(通常是串行设备和以太网)监控节点的“健康”状况。最好有多个冗余介质,以便我们既可以使用串行线又可以使用以太网链接。每个节点运行一个守护程序进程(称为“心跳”)。主守护程序派生出读和写每个心跳介质的子进程,以及状态进程。当检测到某个节点发生故障时,Heartbeat 运行 shell 脚本来启动(或停止)辅助节点上的服务。按照设计,这些脚本使用与系统 init 脚本(通常位于 /etc/init.d 中)相同的语法。缺省脚本是为文件系统、Web 服务器和虚拟 Ip 故障转移提供的。
假定有两个匹配的 LDAp 服务器,我们可以使用几个配置。首先,我们可以进行“冷备用(cold standby)”。主节点拥有一个虚拟 Ip 和一个运行的服务器。辅助节点将处于空闲状态。一旦主节点发生故障,服务器实例和 Ip 将转移到“冷”节点。这实现起来很简单,但是主服务器和辅助服务器之间的数据同步可能是个问题。为了解决这个问题,我们可以利用两个节点上的活动服务器配置群集。主节点运行主 LDAp 服务器,辅助节点运行从实例。对主服务器的更新会立即通过 slurpd 推送到从服务器。
主节点发生故障后,由辅助节点响应查询,但是现在我们还不能更新。为了能够进行更新,在故障转移时,我们将重新启动辅助服务器,并将它提升为主服务器。
这为我们提供了完整的 LDAp 服务,但是增加了 gotcha 问题 — 如果更新是对辅助服务器进行的,则在允许主服务器重新启动之前,我们将不得不对其进行修正。Heartbeat 支持“良好的故障回复”选项,它可以禁止故障节点在故障转移后重新获取资源,我们可以将其设为首选项。本文将演示用手工进行的重新启动。我们的样本配置将使用 Heartbeat 提供的虚拟 Ip 工具。如果需要支持繁重的查询负载,则利用 Ip 喷射器代替虚拟 Ip,将查询分摊给主和从服务器。在这样的情况下,对从服务器的更新请求将产生一个参照。对参照的后继操作不是自动的;该功能必须内置到客户机应用程序中。除了复制伪指令外,主节点和从节点的其余配置是相同的。主配置文件指明复制日志文件的位置(第 16 行)并包含从服务器的清单,这些服务器是带有凭证信息的复制对象。(第 34-36 行)。
34 replica host=slave5:389
35 binddn="cn=Manager,dc=lcc,dc=ibm,dc=com";
36 bindmethod=simple credentials=secret
从配置文件未指明主服务器;而是列出了复制所需的凭证。(第 33 行)
33 updatedn "cn=Manager,dc=lcc,dc=ibm,dc=com"
一般 Heartbeat 准备
可用的基本 Heartbeat 配置有几个很好的示例(请参阅本文结尾处的参考资料)。下面是我们配置中的一些相关内容。我们的配置非常简单,所以内容也不多。缺省情况下,所有配置文件都保存在 /etc/ha.d/ 中。
ha.cf 包含群集的全局定义。对于所有超时,我们都使用缺省值。
# Timeout intervals
keepalive 2
# keepalive could be set to 1 second here
deadtime 10
initdead 120
# define our communications
# serial serialportname ...
serial /dev/ttyS0
baud 19200
# Ethernet information
udpport 694
udp eth1
# and finally, our node id's
# node nodename ... -- must match uname -n
node slave5
node slave6
haresources 这是配置故障转移的地方。令人感兴趣的内容位于该文件的底部。
slave6 192.168.10.51 slapd
这里我们表明了三件事。资源的主要所有者是节点“slave6”(该名称必须与您打算将其作为主节点的机器的“uname -n”输出相符)。服务地址(虚拟 Ip)是“192.168.10.51”(该示例是在专用实验室网络上完成的,因此使用 192.168 这样的地址)。服务脚本称为“slapd”。Hearbeat 将在 /etc/ha.d/resource.d 和 /etc/init.d 中查找脚本。
服务脚本
对于简单的冷备用案例,我们可以使用标准的 /etc/init.d/slapd 脚本而无需做更改。但是我们希望执行特别的功能,所以我们创建了自己的 slapd 脚本,该脚本存储在 /etc/ha.d/resource.d/ 中。Heartbeat 将该目录作为它搜索路径中的第一个,因此我们无需担心会运行 /etc/init.d/slapd 脚本。但是,您应当检查以确定在引导时不再启动 slapd(从您的 /etc/rc.d 树除去任何 S*slapd 文件)。首先,在第 17 和 18 行我们指明 slapd 服务器的启动配置文件。
该脚本遵循标准 init.d 语法,因此启动信息包含在从第 21 行开始的 test_start() 函数中。首先我们停止所有当前正在运行的 slapd 实例。在第 39 行我们利用主配置文件启动主服务器。我们的设计将遵循这样的规则:如果主节点和辅助节点都在运行,则在主节点上启动 slapd 作为主服务器,在辅助节点上启动 slapd 作为从服务器,并启动复制守护程序。如果仅有一个节点在运行,则启动 slapd 作为主服务器。虚拟 Ip 依赖于 slapd 主服务器。为了完成该操作,我们必须知道哪个节点正在执行脚本,并且如果我们位于主节点,那么我们需要知道辅助节点的状态。重要的内容位于脚本的“start”分支。因为我们已经在 Heartbeat 配置中指明了主节点,所以我们知道,当 test_start() 函数运行时,它是在 Heartbeat 的主节点上运行的(因为 Heartbeat 使用了 /etc/init.d/ 脚本,所以所有脚本都是利用参数“start|stop|restart”调用的)。当调用脚本时,Heartbeat 会设置许多环境变量。下面是一个我们感兴趣的环境变量:
HA_CURHOST=slave6
我们可以使用“HA_CURHOST”值来告诉我们,何时正在主节点(slave6)上执行,何时正在进行故障转移(此时 HA_CURHOST 的值为“slave5”)。现在我们需要知道另一个节点的状态。为了得到结果,我们可以询问 Heartbeat。我们将使用 Heartbeat 提供的 api_test.c 文件,并创建一个简单客户机来询问节点状态(api_test.c 文件对客户机还有很多操作,我们只除去了不需要的部分,并添加了一条输出语句)。请注意程序中执行查询的第 31 行。
Heartbeat 查询[url=http://www.pccode.net].net" class="wordstyle"源码清单
编译之后,我们将文件安装在 /etc/ha.d/resource.d/ 中。该程序名为“other_state”。下面是至完整的故障转移脚本的链接,我们再次从 Heartbeat 提供的示例脚本开始着手,然后添加少许修改:
启动脚本
测试
现在,我们可以启动两台服务器上的 Heartbeat。Heartbeat 文档包含有关测试基本设置的一些信息,因此本文就不再赘述了。在两个心跳介质连接之后,您可以看到六个心跳进程在运行。为了验证故障转移,我们进行几项测试。为了提供测试用的客户机,我们创建一个简单的 KDE 应用程序,它将查询服务器并显示连接状态。在该实例中,实际的客户机只查询虚拟 Ip,但为了说明问题,我们将查询所有三个 Ip。在本测试中,我们每小时将发送一万个查询。
S6 是主 LDAp 服务器,S5 是活动的备用服务器。下面的框是 Virtual Ip。通常状态下,S5 和 S6 都显示绿色,表明成功的查询。
首先,我们停止主节点上的心跳进程。在这种情况下,从机器在节点超时的 10 秒过后获得资源,如日志摘要所示:接管工作还包括启动脚本的额外 2 秒延迟。
Sep 7 10:28:21 slave5 heartbeat: info: Running
/etc/ha.d/rc.d/shutdone shutdone
Sep 7 10:28:32 slave5 heartbeat[3381]: WARN: node slave6: is dead
Sep 7 10:28:32 slave5 heartbeat[3381]: info: Link slave6:/dev/ttyS0 dead.
Sep 7 10:28:32 slave5 heartbeat[3381]: info: Link slave6:eth1
dead.
Sep 7 10:28:32 slave5 heartbeat: info: Running /etc/ha.d/rc.d/status status
Sep 7 10:28:32 slave5 heartbeat: info: Running /etc/ha.d/rc.d/ifstat ifstat
Sep 7 10:28:32 slave5 heartbeat: info: Running /etc/ha.d/rc.d/ifstat ifstat
Sep 7 10:28:32 slave5 heartbeat: info: Taking over resource group 192.168.10.51
Sep 7 10:28:32 slave5 heartbeat: info: Acquiring resource group: slave6 192.168.10.51 slapd
Sep 7 10:28:32 slave5 heartbeat: info: Running /etc/ha.d/resource.d/Ipaddr 192.168.10.51 start
Sep 7 10:28:32 slave5 heartbeat: info: ifconfig eth0:0 192.168.10.51 netmask 255.255.255.0 \
broadcast 192.168.10.255
Sep 7 10:28:32 slave5 heartbeat: info: Sending Gratuitous Arp for 192.168.10.51 on eth0:0 [eth0]
Sep 7 10:28:32 slave5 heartbeat: info: Running /etc/ha.d/resource.d/slapd start
Sep 7 10:28:32 slave5 heartbeat: info: /etc/ha.d/resource.d/slapd: Starting
这里是从我们的应用程序中所看到的查询流:
主节点处于当机状态,虚拟 Ip 现在由辅助节点提供服务。S5 和虚拟 Ip 显示绿色,服务器 S6 不可用,所以指示器为红色。
重新启动群集之后,通过切断主节点的电源,我们制造了一个故障。辅助节点在 10 秒超时过后再次获得资源。最后,通过拔掉两端的串行接口和以太网接口,我们模拟两个节点之间完整的互连性故障。这种节点间通信的失败导致两台机器都试图充当主节点。这种情形就是所谓的“裂脑(split-brain)”。这种情形下 Heartbeat 的缺省行为说明了为什么 Heartbeat 需要多个使用不同介质的互连介质。在共享存储器设置中,存储器互连也可以用作心跳介质,这样可以减小“裂脑”的概率。下面是一个取自 ha-log 的显示关机的样本:
heartbeat: 2001/09/07_14:49:46 info: mach_down takeover complete.
heartbeat: 2001/09/07_14:50:36 ERROR: TTY write timeout on [/dev/ttyS0] (no connection?)
heartbeat: 2001/09/07_14:52:53 WARN: Cluster node slave6 returning after partition
heartbeat: 2001/09/07_14:52:53 info: Heartb