DRBD 与 Heartbeat

作者:Pedro Pla

大约三年前,我正在计划一个新的服务器设置,该设置将运行我们的新门户网站以及电子邮件、数据库、DNS 等。最重要的目标之一是创建一个冗余解决方案,这样如果其中一台服务器发生故障,也不会影响公司运营。

当时我研究了许多可用于 Linux 的冗余解决方案,但对于大多数解决方案,我都难以让我们需要的所有服务以冗余方式运行。毕竟,Sendmail 守护程序和 PostgreSQL 守护程序之间的功能差异非常大。

不过,最终我确实找到了一种非常适合我们需求的解决方案。它涉及到使用 DRBD 软件在机器之间设置磁盘镜像,并在这些机器上使用 Heartbeat 高可用性监视器。

DRBD 在两台机器之间镜像一个分区,只允许其中一台机器在同一时间挂载它。然后,Heartbeat 监视这些机器,如果检测到其中一台机器已死机,它会通过挂载镜像磁盘并启动另一台机器正在运行的所有服务来接管控制权。

我已经运行这套设置大约三年了,它使得不可避免的硬件故障对公司来说变得不引人注意。

在本教程中,我将向您展示如何设置冗余的 Sendmail 系统,因为一旦您完成此操作,您将能够设置几乎任何您需要的服务。我们假设您的主服务器名为 server1,IP 地址为 192.168.1.1,而您的从服务器名为 server2,IP 地址为 192.168.1.2。

而且,由于您不希望在这些地址中的任何一个地址宕机的情况下访问您的邮件服务器,我们将为其提供一个虚拟地址 192.168.1.5。当然,您可以将此地址更改为您在本文末尾讨论的 Heartbeat 配置中所需的任何地址。

工作原理

这种高可用性解决方案通过在主/从模式下复制磁盘分区来工作。作为主服务器运行的服务器对该分区具有完全的读/写访问权限;而作为从服务器运行的服务器绝对无法访问该分区,但会静默地复制主服务器所做的所有更改。

因此,所有需要访问复制分区的进程都必须在主服务器上运行。如果主服务器发生故障,在从服务器上运行的 Heartbeat 守护程序将告诉 DRBD 它现在是主服务器,挂载复制分区,然后启动所有数据存储在复制分区上的进程。

如何运行

运行冗余系统的第一步是准备好两台机器进行试用。它们不需要具有相同的规格,但应满足以下要求

  • 两台机器上都有足够的可用空间,以便在每台机器上创建一个大小相等的分区。

  • 您要在两台机器上运行的守护程序版本相同。

  • 带有交叉电缆或集线器/交换机的网卡。

  • 可选的串行端口和串行端口交叉电缆,用于额外的监控。

您还应该仔细考虑要在两台机器上运行哪些服务,因为这将影响您需要专用于跨机器复制的硬盘空间量,以及您将如何存储这些服务的配置和数据文件。

非常重要的是,您在这个共享分区上要有足够的空间,因为它将是所有这些服务的主要数据存储位置。因此,如果您要存储大型 Sendmail 假脱机或数据库,您应该确保它有足够的空间运行很长时间,然后再重新分区并为更大的磁盘大小重新配置 DRBD。

在服务器上设置基本配置

一旦您确保您的机器已准备就绪,您就可以继续在两台机器上创建一个大小相等的分区。在此阶段,您无需在该分区上创建文件系统,因为您只需在它通过 DRBD 镜像运行时执行此操作一次。

对于我的服务器,我有一个 DRBD 复制驱动器,它在我的分区表上看起来像这样

/dev/sda5      7916    8853   7534453+  83  Linux

注意:类型fdisk -l在您的命令提示符下,查看与此处显示的格式类似的分区列表。另外,在我的例子中,冗余机器上的分区表是相同的。

分区后的下一步是获取 Heartbeat 版本 1.2+ 和 DRBD 版本 0.8+ 的软件包,并编译 DRBD 内核模块。如果您的发行版可以预先打包这些软件包,可能会更容易,但如果不是,您可以从 www.linux-ha.org/DownloadSoftwarewww.drbd.org/download.html 下载它们。

现在,转到您的 /etc/hosts 文件并添加几行,一行用于您的主冗余服务器,另一行用于您的辅助冗余服务器。将一台服务器称为 server1,另一台服务器称为 server2,最后,将一台称为 mail,并适当地设置 IP 地址。它应该看起来像这样

192.168.1.1    server1
192.168.1.2    server2
192.168.1.5    mail

最后,在您的主服务器和从服务器上,创建一个名为 /replicated 的文件夹,并将以下行添加到 /etc/fstab 文件中

/dev/drbd0    /replicated   ext3   noauto    0   0
配置 DRBD

完成此操作后,您必须先设置 DRBD,然后再继续进行 Heartbeat。在我的设置中,配置文件是 /etc/drbd.conf,但这可能会因发行版和编译时选项而异,因此请尝试找到该文件并立即打开它,以便您可以继续操作。如果您找不到它,只需创建一个名为 /etc/drbd.conf 的文件即可。

清单 1 是我的配置文件。我逐行浏览它,并添加以 # 字符开头的注释作为解释。

清单 1. /etc/drbd.conf

# Each resource is a configuration section for a
# mirrored disk.
# The drbd0 is the name we will use to refer
# to this disk when starting or stopping it.

resource drbd0 {
  protocol C;
  handlers {
    pri-on-incon-degr "echo 'DRBD: primary requested but inconsistent!'
    ↪| wall; /etc/init.d/heartbeat stop"; #"halt -f";
    pri-lost-after-sb "echo 'DRBD: primary requested but lost!'
    ↪| wall; /etc/init.d/heartbeat stop"; #"halt -f";
  }

  startup {
    degr-wfc-timeout 120;    # 2 minutes.
  }

  disk {
    on-io-error   detach;
  }
# These are the network settings that worked best for me.
# If you want to play around with them, go
# ahead, but take a look in the man pages of drbd.conf
# and drbdadm to see what each does.

  net {
    timeout 120;
    connect-int 20;
    ping-int 20;
    max-buffers     2048;
    max-epoch-size  2048;
    ko-count 30;

# Remember to change this shared-secret on both the master
# and slave machines.

    cram-hmac-alg "sha1";
    shared-secret "FooFunFactory";
  }

  syncer {
    rate 10M;
    al-extents 257;
  }

# This next block defines the settings for the server
# labeled as server1.  This label should be in your
# /etc/hosts file and point to a valid host.

  on server1 {

# The following device will be created automatically by
# the drbd kernel module when the DRBD
# partition is in master mode and ready to write.
# If you have more than one DRBD resource, name
# this device drbd1, drbd2 and so forth.

    device     /dev/drbd0

# Put the partition device name you've prepared here.

    disk	     /dev/sda5;

# Now put the IP address of the primary server here.
# Note: you will need to use a unique port number for
# each resource.

    address   192.168.1.3:7788;
    meta-disk  internal;
  }

# This next block is identical to that of server1 but with
# the appropriate settings of the server called
# server2 in our /etc/hosts file.

  on server2 {
    device    /dev/drbd0;
    disk      /dev/sda5;
    address   192.168.1.2:7788;
    meta-disk internal;
  }
}

现在,让我们通过启动 DRBD 驱动程序来测试它,看看一切是否正常工作。在两台服务器的命令行上键入

drbdadm create-md drbd0; /etc/init.d/drbd restart; cat /proc/drbd

如果一切顺利,最后一个命令的输出应该如下所示

0: cs:Connected st:Secondary/Secondary ds:Inconsistent/Inconsistent r---
   ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0
       resync: used:0/7 hits:0 misses:0 starving:0 dirty:0 changed:0
       act_log: used:0/257 hits:0 misses:0 starving:0 dirty:0 changed:0

注意:您始终可以通过键入以下命令找到有关 DRBD 状态的信息

cat /proc/drbd

现在,在主系统上键入以下命令

drbdadm -- --overwrite-data-of-peer primary drbd0; cat /proc/drbd

输出应如下所示

0: cs:SyncSource st:Primary/Secondary ds:UpToDate/Inconsistent r---
   ns:65216 nr:0 dw:0 dr:65408 al:0 bm:3 lo:0 pe:7 ua:6 ap:0
       [>...................] sync'ed:  2.3% (3083548/3148572)K
       finish: 0:04:43 speed: 10,836 (10,836) K/sec
       resync: used:1/7 hits:4072 misses:4 starving:0 dirty:0 changed:4
       act_log: used:0/257 hits:0 misses:0 starving:0 dirty:0 changed:0

这意味着它正在从设置为主计算机的主计算机同步您的磁盘到设置为辅助计算机的从计算机。

接下来,通过在主系统上键入以下命令来创建文件系统

mkfs.ext3 /dev/drbd0

完成此操作后,在主计算机上,继续并将驱动器 /dev/drbd0 挂载到我们为其创建的 /replicated 目录中。现在我们必须手动挂载它,直到我们设置好 Heartbeat。

准备您的服务

任何冗余解决方案的重要组成部分是正确准备您的服务,以便当主机器发生故障时,从机器可以接管并无缝运行这些服务。为此,您不仅必须将数据移动到复制的 DRBD 磁盘,还必须移动配置文件。

让我向您展示我是如何设置 Sendmail 来处理邮件并将邮件存储在复制驱动器上的。我以 Sendmail 为例,因为它比其他服务稍微复杂一步,因为即使机器以从模式运行,它也可能需要从内部应用程序发送电子邮件通知,如果 Sendmail 无法访问配置文件,它将无法执行此操作。

在主机器上,首先确保已安装但已停止 Sendmail。然后在您的 /replicated 驱动器上创建一个 etc 目录。之后,将您的 /etc/mail 目录复制到 /replicated/etc 中,并从 /replicated/etc/mail 创建一个符号链接到 /etc/mail。

接下来,在 /replicated 驱动器上创建一个 var 目录,并将 /var/mail、/var/spool/mqueue 和任何其他邮件数据文件夹复制到该目录中。然后,当然,创建适当的符号链接,以便可以从以前的位置访问新文件夹。

您的 /replicated 目录结构现在应如下所示

/replicated/etc/mail
/replicated/var/mail
/replicated/var/spool/mqueue
/replicated/var/spool/mqueue-client
/replicated/var/spool/mail

在您的主驱动器上,这些文件夹应该是符号链接,并且看起来像这样

/etc/mail -> /replicated/etc/mail
/var/mail -> /replicated/var/mail
/var/spool/mqueue -> /replicated/var/spool/mqueue
/var/spool/mqueue-client -> /replicated/var/spool/mqueue-client
/var/spool/mail -> /replicated/var/spool/mail

现在,再次启动 Sendmail 并试用一下。如果一切正常,您已成功完成设置的第一部分。

下一部分是确保它甚至在从服务器上也能运行。我们使用的技巧是将 Sendmail 二进制文件复制到挂载的 /replicated 驱动器上,并在未挂载的 /replicated 文件夹上放置一个指向二进制文件 ssmtp 的符号链接。

首先,确保您的系统上已安装并配置了 ssmtp。接下来,创建一个目录 /replicated/usr/sbin,并将 /usr/sbin/sendmail 复制到该目录。然后,从 /usr/sbin/sendmail 符号链接回 /replicated/usr/sbin/sendmail。

完成后,关闭 Sendmail 并卸载 /replicated 驱动器。然后,在主计算机和从计算机上,创建一个文件夹 /replicated/usr/sbin,并从 /usr/sbin/ssmtp 符号链接到 /replicated/usr/sbin/sendmail。

在设置 Sendmail 后,设置 Apache 和 PostgreSQL 等其他服务似乎会变得轻而易举。只需记住将它们的所有数据和配置文件放在 /replicated 驱动器上,并创建适当的符号链接即可。

配置 Heartbeat

Heartbeat 旨在监控您的服务器,如果您的主服务器发生故障,它将在从服务器上启动所有服务,将其变成主服务器。要配置它,我们需要指定它应该监控哪些服务器以及当一台服务器发生故障时它应该启动哪些服务。

让我们首先配置服务。我们将看一下我们之前配置的 Sendmail,因为其他服务的配置方式相同。首先,转到目录 /etc/heartbeat/resource.d。此目录包含 Heartbeat 将启动的服务的所有启动脚本。

现在,从 /etc/init.d/sendmail 添加一个符号链接到 /etc/heartbeat/resource.d。

注意:请记住,这些路径可能会因您的 Linux 发行版而异。

完成此操作后,将 Heartbeat 设置为在主计算机上自动启动服务,并在主计算机发生故障时将从计算机转换为主计算机。清单 2 显示了执行此操作的文件,在其中您可以看到我们只有一行,其中包含要在给定服务器上启动的不同资源,以空格分隔。

清单 2. /etc/heartbeat/haresources

server1 IPaddr::192.168.1.5/24 datadisk::drbd0 sendmail

第一个命令,server1,定义了哪个服务器应该是这些服务的默认主服务器;第二个命令,IPaddr::192.168.1.5/24,告诉 Heartbeat 将其配置为具有给定网络掩码的主服务器上的附加 IP 地址。接下来,使用datadisk::drbd0我们告诉 Heartbeat 在主服务器上自动挂载此驱动器,在此之后,我们可以输入我们要启动的所有服务的名称——在本例中,我们输入sendmail.

注意:这些名称应与其启动脚本在 /etc/heartbeat/resource.d 中的文件名相同。

接下来,让我们配置 /etc/heartbeat/ha.cf 文件(清单 3)。您可能想要在其中更改的主要内容是底部的master/slave 机器的主机名,以及 deadtime 和 initdead。这些指定在假定另一台机器已死机并接管控制权之前,应允许来自另一台机器的静默时间(以秒为单位)。

如果您将此设置得太低,您可能会出现误报,除非您已安装名为 STONITH 的系统,如果它认为另一台机器已经死机,它会杀死另一台机器,否则您可能会遇到各种问题。我将我的设置为两分钟;这是最适合我的,但请随意尝试。

另请记住以下两点:为了使串行连接工作,您需要在机器之间插入交叉串行电缆,如果您不在机器之间使用交叉网络电缆,而是通过您有其他 Heartbeat 节点的集线器,您必须更改每个主/从节点集的 udpport,否则您的日志文件将被警告消息填满。

清单 3. /etc/heartbeat/ha.cf

debugfile /var/log/ha-debug
logfile /var/log/ha-log
logfacility     local0
keepalive 2
deadtime 120
initdead 120
serial  /dev/ttyS1
baud 9600
udpport 694
udp     eth0
nice_failback on
node server1
node server2

现在,剩下的就是通过键入以下命令在主服务器和从服务器上启动 Heartbeat

/etc/init.d/heartbeat start

一旦您启动并运行了它,就该对其进行测试了。您可以通过停止主服务器上的 Heartbeat 并观察从服务器是否成为主服务器来执行此操作。然后,当然,您可能想通过完全关闭主服务器电源或任何其他断开连接测试来尝试它。

恭喜您设置了冗余服务器系统!请记住,Heartbeat 和 DRBD 相当灵活,您可以组合一些复杂的解决方案,包括让一台服务器成为一个 DRBD 分区的主服务器,而成为另一个分区从服务器。花一些时间,玩玩它们,看看您能发现什么。

Pedro Pla (pedropla@pedropla.com) 是 Holiday Marketing International 公司集团的首席技术官,他拥有超过十年的 Linux 经验。

加载 Disqus 评论