内容:
我们使用的开放源码软件
有关 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 与他联系。
当某个组织添加应用程序和服务时,集中进行认证和密码服务可以提高安全性,并减少管理和开发人员的难题。但是,将所有服务合并到一台服务器会导致可靠性问题。高可用性对于企业认证服务尤为重要,因为在许多情况下,当认证停止工作时,整个企业将陷于停顿。本文描述了我们该如何使用开放源码软件创建可靠的、高度可用的认证服务器。
我们使用的开放源码软件
我们使用 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 基金会是要“共同致力于开发健壮的、商业级别的、功能完善的和开放源码的 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)小组提供了开放源码群集软件。他们的软件包称为 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
# ethe.net 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/ 脚本,所以所有脚本都是利用参数“startstoprestart”调用的)。当调用脚本时,heartbeat 会设置许多环境变量。下面是一个我们感兴趣的环境变量:
ha_curhost=slave6
我们可以使用“ha_curhost”值来告诉我们,何时正在主节点(slave6)上执行,何时正在进行故障转移(此时 ha_curhost 的值为“slave5”)。现在我们需要知道另一个节点的状态。为了得到结果,我们可以询问 heartbeat。我们将使用 heartbeat 提供的 api_test.c 文件,并创建一个简单客户机来询问节点状态(api_test.c 文件对客户机还有很多操作,我们只除去了不需要的部分,并添加了一条输出语句)。请注意程序中执行查询的第 31 行。
heartbeat 查询源码清单
编译之后,我们将文件安装在 /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: heartbeat shutdown in progress.
heartbeat: 2001/09/07_14:52:53 error: 105 lost packet(s) for [slave6] [191:297]
heartbeat: 2001/09/07_14:52:53 error: lost a lot of packets!
heartbeat: 2001/09/07_14:52:53 info: link slave6:eth1 up.
heartbeat: 2001/09/07_14:52:53 warn: late heartbeat: node slave6: interval 211920 ms
heartbeat: 2001/09/07_14:52:53 info: node slave6: status active
heartbeat: 2001/09/07_14:52:53 info: giving up all ha resources.
heartbeat: 2001/09/07_14:52:53 info: running /etc/ha.d/rc.d/status status
heartbeat: 2001/09/07_14:52:53 info: running /etc/ha.d/rc.d/ifstat ifstat
heartbeat: 2001/09/07_14:52:53 info: running /etc/ha.d/rc.d/shutdone shutdone
heartbeat: 2001/09/07_14:52:53 info: releasing resource group: slave6 192.168.10.51 slapd
heartbeat: 2001/09/07_14:52:53 info: running /etc/ha.d/resource.d/slapd stop
heartbeat: 2001/09/07_14:52:53 info: /etc/ha.d/resource.d/slapd: shutting down
heartbeat: 2001/09/07_14:52:53 info: running /etc/ha.d/resource.d/ipaddr 192.168.10.51 stop
heartbeat: 2001/09/07_14:52:53 info: ip address 192.168.10.51 released
heartbeat: 2001/09/07_14:52:54 info: all ha resources relinquished.
heartbeat: 2001/09/07_14:52:54 info: heartbeat shutdown in progress.
heartbeat: 2001/09/07_14:52:54 info: giving up all ha resources.
heartbeat: 2001/09/07_14:52:54 info: all ha resources relinquished.
heartbeat: 2001/09/07_14:52:55 info: heartbeat shutdown complete.
当选择超时值时需要考虑这个问题。如果超时太短,重负载的系统可能会错误地触发接管,这会导致明显的“裂脑”关机。有关该问题的更多信息,请参阅 linux-ha faq 文档。
故障转移后的恢复
如果主 ldap 服务器处于当机时,对 ldap 名称空间进行了更新,则在重新启动主服务器之前必须使 ldap 数据库重新同步。完成该操作有两种方法。如果可以使服务中断,那么在 ldap 服务器停止后可以手工复制数据库(缺省情况下数据文件保存在 /usr/local/var 中)。不使服务中断,您也可以使用 openldap 复制来恢复数据库。首先,启动以前主节点上的 ldap 服务器作为从服务器。然后启动当前主服务器上的 slurpd 守护程序。新的主节点会把以前主节点出故障时所接收到的更改推送到后者。最后,停止以前主节点上的从 ldap 服务器,并且启动 heartbeat。这将导致原始配置的故障回复。
apache 的 ldap 配置
这里是一个订阅 ldap 服务器的应用程序示例。该应用程序是使用 mod_auth_ldap 软件包的 apache web 服务器。
结束语
本文是使用开放源码软件创建一些高度可用的基本网络服务的简单示例。网络服务(包括 ldap)很少需要巨型服务器。由服务器和数据文件的集群和复制提供的额外可靠性可以提高服务的可用性。该系统经过了所有的测试,在所有的情形中,故障转移时间都不超过 15 秒。假如对系统负载和利用有很好的理解,可以将故障转移时间降低到这个阈值以下。
参考资料
openldap 主页 — http://www.openldap.org
linux ha 主页 — http://www.linux-ha.org
有关 heartbeat 设置的指导说明 — http://www.linux-ha.org/download/gettingstarted.html
sysadmin 有关使用 heartbeat 提供服务的 ha 文件的期刊文章
linux ultramonkey ha — http://ultramonkey.sourceforge.net
linux 虚拟服务器项目 — http://www.linuxvirtualserver.org
免责声明
免责声明:上述文章是基于实验室环境中所进行的实验室测试。因而,出于众多因素(包括每个特定安装中的工作负载和配置),特定用户的安装结果可能会有所差异。所以上述信息是以“按现状”的基础提供的。特此声明不承担有关适销性和适用于某特定用途的保证。使用该信息的风险由用户自负。
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器