适用于 SUSE Linux Enterprise High Availability Extension 12

17 储存保护

高可用性群集堆栈的首要任务是保护数据的完整性。这是通过避免未经协调而并发访问数据储存来实现的:例如,Ext3 文件系统只在群集中装入一次;只有在与其他群集节点协调后才会装入 OCFS2 卷。在功能良好的群集中,Pacemaker 会检测资源活动是否超出其并发限制,并启动恢复。此外,其策略引擎绝不会超出这些限制。

但是,网络分区或软件故障可能导致选出若干协调程序的情况。如果允许出现这种所谓的“节点分裂”情况,则可能会发生数据损坏。因此,在群集堆栈中增加了若干保护层,以缓解这种情况。

为实现此目标,起作用的主要组件是 IO 屏蔽/STONITH,它可确保在储存激活之前终止所有其他访问。其他机制有 cLVM2 排它激活或 OCFS2 文件锁定支持,以保护系统免受管理或应用程序错误的影响。有了这些机制,再配合进行设置后,就能可靠地避免节点分裂情况所造成的危害。

本章介绍利用储存区本身的 IO 屏蔽机制,后面是对附加保护层(用于确保对储存区的排它访问)的描述。这两套机制可以结合起来使用,以提供更高的保护级别。

17.1 基于储存区的屏蔽

您可以使用一个或多个 STONITH 块设备 (SBD)、watchdog 支持和 external/sbd STONITH 代理来可靠地避免节点分裂状况。

17.1.1 概述

在所有节点都可访问共享储存的环境中,设备的某个小分区会格式化,以用于 SBD。该分区的大小取决于所用磁盘的块大小(对于块大小为 512 字节的标准 SCSI 磁盘,该分区大小为 1 MB;块大小为 4 KB 的 DASD 磁盘需要 4 MB)。配置完相应的守护程序后,它在其余群集堆栈启动之前将在每个节点上都处于联机状态。它在所有其他群集组件都关闭之后才终止,从而确保了群集资源绝不会在没有 SBD 监督的情况下被激活。

此守护程序会自动将分区上的消息槽之一分配给其自身,并持续监视其中有无发送给它自己的消息。收到消息后,守护程序会立即执行请求,如启动关闭电源或重引导循环以进行屏蔽。

此守护程序会持续监视与储存设备的连接性,并在无法连接分区时自行终止。这就保证了它不会从屏蔽消息断开连接。如果群集数据驻留在不同分区中的同一逻辑单元上,这不是额外的故障点:如果与储存区的连接已丢失,工作负载总是要终止的。

额外的保护是通过 watchdog 支持提供的。新式系统支持硬件检查包,此功能需由软件组件来激发馈送数据。软件组件(通常是守护程序)会定期将服务脉冲写入检查包 - 如果守护程序停止供给检查包,则硬件会强制执行系统重启动。这可防止出现 SBD 进程本身的故障,如失去响应或由于 IO 错误而卡住。

如果 Pacemaker 集成已激活,则当设备大多数节点丢失时,SBD 将不会进行自我屏蔽。例如,您的群集包含 3 个节点:A、B 和 C。由于网络分隔,A 只能看到它自己,而 B 和 C 仍可相互通讯。在此案例中,有两个群集分区,一个因节点占多数(B 和 C)而具有法定票数,而另一个则不具有 (A)。如果发生此情况,当无法访问屏蔽设备的大多数节点时,则节点 A 会立即自我关闭,而节点 B 和 C 将会继续运行。

17.1.2 SBD 设备的数量

SBD 支持使用 1 到 3 个设备:

一个设备

最简单的实施。适用于所有数据位于同一个共享储存的群集。

两个设备

此配置主要用于使用基于主机的镜像但未提供第三个存储设备的环境。SBD 在丢失对某个镜像分支的访问权后将自我终止,以允许群集继续运行。但是,由于 SBD 不具备足够的知识可以检测到存储区的不对称分裂,因此在只有一个镜像分支可用时它不会屏蔽另一个分支。如此一来,就无法在存储阵列中的一个关闭时对第二个故障自动容错。

三个设备

最可靠的配置。它具有从一个设备中断(可能是因为故障或维护)的情况中恢复的能力。在有一个以上设备丢失时 SBD 才会自我终止。当至少有两个设备仍可访问时,可成功传送屏蔽消息。

此配置适用于存储未限制为单个阵列的更为复杂的环境。基于主机的镜像解决方案可以每个镜像分支拥有一个 SBD(不自我镜像),并在 iSCSI 上有一个额外的决定项。

17.1.3 设置基于储存区的保护

以下步骤是设置基于储存区的保护所必需的:

以下所有过程都必须以 root 身份来执行。开始前应确保满足以下要求:

重要
重要:要求
  • 环境中必须有所有节点均可到达的共享储存区。

  • 该共享储存段不得使用基于主机的 RAID、cLVM2 或 DRBD*。

  • 但是,建议使用基于储存区的 RAID 和多路径,以提高可靠性。

17.1.3.1 创建 SBD 分区

建议在设备启动时创建一个 1MB 的分区。如果 SBD 设备驻留在多路径组上,则需要调整 SBD 所用的超时,因为 MPIO 的沿路径检测可能导致一些等待时间。msgwait 超时后,将假定此消息已传递到节点。对于多路径,这应是 MPIO 检测路径故障并切换到下一个路径所需的时间。您可能需要在自己的环境中对此进行测试。如果节点上运行的 SBD 守护程序未足够快速地更新检查包计时器,则节点会自行终止。在特定的环境中测试选择的超时。如果只对一个 SBD 设备使用多路径储存,请密切关注发生的故障转移延迟。

注意
注意:SBD 分区的设备名称

在下文中,此 SBD 分区由 /dev/SBD 引用。将它替换为实际路径名,例如 /dev/sdc1

重要
重要:覆盖现有数据

确保要用于 SBD 的设备未保存任何数据。sdb 命令不再进一步请求确认就覆盖设备。

  1. 使用以下命令初始化 SBD 设备:

    root # sbd -d /dev/SBD create

    此操作会将报头写入设备,并创建最多可供 255 个节点以默认时序共享此设备的槽。

    如果要为 SBD 使用一个以上的设备,请多次指定 -d 选项来提供设备,例如:

    root # sbd -d /dev/SBD1 -d /dev/SBD2 -d /dev/SBD3 create
  2. 如果 SBD 设备驻留在多路径组中,请调整 SBD 所用的超时。这可以在初始化 SBD 设备时指定(所有超时的单位都是秒):

    root # /usr/sbin/sbd -d /dev/SBD -4 1801 -1 902 create

    1

    -4 选项用于指定 msgwait 超时。 在以上示例中,超时设置为 180 秒。

    2

    -1 选项用于指定 watchdog 超时。在以上示例中,超时设置为 90 秒。

  3. 使用以下命令检查已写入设备的内容:

    root # sbd -d /dev/SBD dump 
    Header version     : 2
    Number of slots    : 255
    Sector size        : 512
    Timeout (watchdog) : 5
    Timeout (allocate) : 2
    Timeout (loop)     : 1
    Timeout (msgwait)  : 10

正如您看到的,超时数也储存在报头中,以确保所有参与的节点在这方面都一致。

17.1.3.2 设置软件检查包

在未被其他软件使用的情况下,检查包可以在出现 SBD 故障时保护系统。

重要
重要:访问检查包计时器

不能有其他任何软件在访问检查包计时器。有些硬件供应商交付的系统管理软件(例如 HP ASR 守护程序)会使用检查包来进行系统重设置。如果 SBD 使用了检查包,请禁用此类软件。

SUSE Linux Enterprise High Availability Extension 中,默认会启用内核中的检查包支持:本产品随附了多个不同的内核模块,可提供特定于硬件的检查包驱动程序。High Availability Extension 使用 SBD 守护程序作为供给检查包的软件组件。如果根据第 17.1.3.3 节 “启动 SBD 守护程序”中所述配置了 SBD 守护程序,它会在您使用 systemctl start pacemaker.service 将相应节点联机时自动启动。

在系统引导过程中,一般会自动装载适用于您硬件的检查包驱动程序。softdog 是最通用的驱动程序,但建议使用带有实际硬件集成的驱动程序。例如:

  • 在 HP 硬件上,这是 hpwdt 驱动程序。

  • 对于使用 Intel TCO 的系统,可使用 iTCO_wdt 驱动程序。

有关选项列表,请参见 /usr/src/内核版本/drivers/watchdog。也可以使用以下命令列出与您的内核版本一起安装的驱动程序:

root # rpm -ql kernel-VERSION | grep watchdog

大多数检查包驱动程序名称都包含 wdwdtdog 等字符串,所以可使用以下命令检查当前装载的驱动程序:

root # lsmod | egrep "(wd|dog)" 

要自动装载检查包驱动程序,请创建文件 /etc/modules-load.d/watchdog.conf,并在其中包含含有驱动程序名称的一行。有关详细信息,请参见 modules-load.d 手册页。

如果更改检查包的超时,则必须也要更改另外两个值(msgwaitstonith-timeout)。检查包超时主要取决于您的储存延迟。此值指定大多数设备必须在此时间范围内成功完成其读操作。否则,节点会自我屏蔽。

以下公式大致表达了这三个值之间的关系:

例 17.1 使用 SBD 作为 STONITH 设备的群集计时
Timeout (msgwait) = (Timeout (watchdog) * 2)
stonith-timeout = Timeout (msgwait) + 20%

例如,如果将超时检查包设置为 120,则需要将 msgwait 设置为 240,将 stonith-timeout 设置为 288。您可以使用 cs_make_sbd_devices 检查输出:

root # cs_make_sbd_devices --dump
==Dumping header on disk /dev/sdb
Header version     : 2.1
UUID               : 619127f4-0e06-434c-84a0-ea82036e144c
Number of slots    : 255
Sector size        : 512
Timeout (watchdog) : 20
Timeout (allocate) : 2
Timeout (loop)     : 1
Timeout (msgwait)  : 40
==Header on disk /dev/sdb is dumped

如果您要设置新群集,ha-cluster-init 命令会考虑上述因素。

17.1.3.3 启动 SBD 守护程序

SBD 守护程序是群集堆栈的关键部分。只要群集堆栈正在运行,此守护程序就必须运行,即使群集堆栈的一部分已崩溃时也是如此,这样才能将这部分屏蔽。

  1. 使用以下命令让 SBD 守护程序在引导时启动:

    root # systemctl enable sbd.service
  2. 运行 ha-cluster-init。此脚本可确保正确配置 SBD,并将配置文件 /etc/sysconfig/sbd 添加到需要与 Csync2 同步的文件列表。

    如果要手动配置 SBD,请执行以下步骤:

    要启动 Corosync init 脚本和停止 SBD,请编辑 /etc/sysconfig/sbd 文件,搜索以下行,搜索时将 SBD 替换为您的 SBD 设备:

    SBD_DEVICE="/dev/SBD"

    如果您需要在第一行指定多个设备,请使用分号分隔设备(设备顺序无关紧要):

    SBD_DEVICE="/dev/SBD1; /dev/SBD2; /dev/SBD3"

    如果无法访问 SBD 设备,守护程序将无法启动,并会禁止 Corosync 启动。

    注意
    注意:引导时启动服务

    如果 SBD 设备变得从某个节点无法访问,这会导致此节点进入无限的重引导循环。从技术上来看,此行为是正确的,但根据您的具体管理策略,很可能是令人讨厌的。在这种情况下,最好不要让 Corosync 和 Pacemaker 在引导时自动启动。

  3. 在继续下一步之前,请通过执行 systemctl restart pacemaker.service 确保所有节点上都启动了 SBD。

17.1.3.4 测试 SBD

  1. 以下命令会将节点槽及其当前消息从 SBD 设备进行转储:

    root # sbd -d /dev/SBD list

    现在,您应该看到此处列出了使用 SBD 启动过的所有群集节点,并且消息槽应显示 clear

  2. 尝试将测试消息发送到节点之一:

    root # sbd -d /dev/SBD message nodea test
  3. 此节点将在系统日志文件中确认收到了该讯息:

    Aug 29 14:10:00 nodea sbd: [13412]: info: Received command test from nodeb

    这就确认了 SBD 确实在节点上正常运行,并已准备好接收消息。

17.1.3.5 配置屏蔽资源

  1. 要完成 SBD 设置,请按如下方式将 SBD 激活为 CIB 中的 STONITH/屏蔽机制:

    root # crm configure
    crm(live)configure# property stonith-enabled="true"
    crm(live)configure# property stonith-timeout="40s"
    crm(live)configure# primitive stonith_sbd stonith:external/sbd \
       op start interval="0" timeout="15" start-delay="10"
    crm(live)configure# commit
    crm(live)configure# quit

    无需克隆该资源,因为在发生问题时无论如何都会关闭相应节点。

    stonith-timeout 设置哪个值取决于 msgwait 超时。msgwait 超时应大于底层 IO 系统的最大允许超时。例如,普通 SCSI 磁盘的最大允许超时为 30 秒。如果您将 msgwait 超时设置为 30 秒,则将 stonith-timeout 设置为 40 秒比较合适。

    由于节点槽是自动分配的,因此无需定义手动主机列表。

  2. 禁用以前可能配置过的任何其他屏蔽设备,因为现在用于此功能的是 SBD 机制。

资源启动后,群集的共享储存屏蔽配置即告成功,群集将在需要屏蔽节点时使用此方法。

17.1.3.6 配置 sg_persist 资源

  1. root 身份登录并启动外壳。

  2. 创建配置文件 /etc/sg_persist.conf

    sg_persist_resource_MDRAID1() {
          devs="/dev/sdd /dev/sde"
          required_devs_nof=2
    }
  3. 运行以下命令创建基元资源 sg_persist

    root # crm configure
    crm(live)configure# primitive sg ocf:heartbeat:sg_persist \
        params config_file=/etc/sg_persist.conf \
               sg_persist_resource=MDRAID1 \
               reservation_type=1 \
        op monitor interval=60 timeout=60
  4. sg_persist 基元添加到主-从组:

    crm(live)configure# ms ms-sg sg \
        meta master-max=1 notify=true
  5. 在 alice 服务器上设置主资源,在 bob 节点上设置从资源:

    crm(live)configure# location ms-sg-alice-loc ms-sg inf: alice
    crm(live)configure# location ms-sg-bob-loc ms-sg 100: bob
  6. 执行一些测试。当资源处于主/从状态时,在主服务器上,您可以在 /dev/sdc1 中执行装入和写入,而在从服务器上,则无法写入。

通常,您可能希望将上述资源与文件系统资源(例如 OCFS2)结合使用。在这种情况下,您需要执行以下步骤:

  1. 添加 OCFS2 基元:

    crm(live)configure# primitive ocfs2 ocf:heartbeat:Filesystem \
        params device="/dev/sdc1" directory="/mnt/ocfs2" fstype=ocfs2
  2. 从基本组创建克隆:

    crm(live)configure# clone cl-group basegroup
  3. ms-sgcl-group 之间添加关系:

    crm(live)configure# colocation ocfs2-group-on-ms-sg inf: cl-group ms-sg:Master
    crm(live)configure# order ms-sg-before-ocfs2-group inf: ms-sg:promote cl-group
  4. 使用 edit 命令检查所有更改。

  5. 提交更改。

17.2 确保储存区的排它激活

此部分将介绍另一种低级别机制:sfex,可将对共享储存区的访问以排它的方式锁定于一个节点。请注意,sfex 不会替代 STONITH。由于 sfex 需要共享储存区,因此建议将上述 external/sbd 屏蔽机制用于储存区的另一个分区。

根据设计意图,sfex 不能用于需要执行并发操作的工作负载(如 OCFS2),而是用作传统故障转移式工作负载的保护层。这实际上与 SCSI-2 保留相类似,但更具一般性。

17.2.1 概述

在共享储存环境中,储存区的一个小分区专门设置为储存一个或多个锁。

在获取受保护资源之前,节点必须先获取保护锁。此顺序由 Pacemaker 强制实施,sfex 组件可确保即使 Pacemaker 遇到了节点分裂的情况,也不会多次授予锁。

这些锁必须定期刷新,这样某个节点的终止才不会永久性地阻止此锁,其他节点仍可继续操作。

17.2.2 设置

以下内容可帮助您了解如何创建用于 sfex 的共享分区以及如何为 CIB 中的 sfex 锁配置资源。单个 sfex 分区可保存任意数量的锁,默认值为 1,需要为每个锁分配 1 KB 的储存空间。

重要
重要:要求
  • sfex 的共享分区应和要保护的数据位于同一逻辑单元上。

  • 共享的 sfex 分区不得使用基于主机的 RAID 或 DRBD。

  • 可以使用 cLVM2 逻辑卷。

过程 17.1 创建 sfex 分区
  1. 创建用于 sfex 的共享分区。注意此分区的名称,并用它替代下面的 /dev/sfex

  2. 使用以下命令创建 sfex 元数据:

    root # sfex_init -n 1 /dev/sfex
  3. 校验元数据已正确创建:

    root # sfex_stat -i 1 /dev/sfex ; echo $?

    此操作应返回 2,因为当前未保存锁。

过程 17.2 为 sfex 锁配置资源
  1. sfex 锁通过 CIB 中的资源表示,其配置如下:

    crm(live)configure# primitive sfex_1 ocf:heartbeat:sfex \
    #	params device="/dev/sfex" index="1" collision_timeout="1" \
          lock_timeout="70" monitor_interval="10" \
    #	op monitor interval="10s" timeout="30s" on_fail="fence"
  2. 要通过 sfex 锁保护资源,请在保护对象和 sfex 资源之间创建强制顺序和放置约束。如果受保护资源的 ID 是 filesystem1

    crm(live)configure# order order-sfex-1 inf: sfex_1 filesystem1
    crm(live)configure# colocation colo-sfex-1 inf: filesystem1 sfex_1
  3. 如果使用组语法,请将 sfex 资源添加为组内的第一个资源:

    crm(live)configure# group LAMP sfex_1 filesystem1 apache ipaddr

17.3 更多信息

请参见 http://www.linux-ha.org/wiki/SBD_Fencingman sbd

打印此页