排查 SAP 的高可用性配置问题

在 SAP on Google Cloud的高可用性配置中,导致出现问题的根本原因可能在于集群软件、SAP 软件、 Google Cloud 基础设施或这些因素的一些组合。

在 Cloud Logging 中分析 Pacemaker 日志

以下视频展示了如何开始使用 Cloud Logging 排查 SAP on Google Cloud的高可用性配置问题。

故障切换后,Linux 集群中的故障节点无法正确重启

如果您的 Linux 高可用性集群使用 fence_gce 防护代理,并且经过防护的虚拟机在故障切换后无法重新加入集群,则您可能需要在防护后的虚拟机重启时延迟 Corosync 软件的启动。

问题

在故障切换期间,fence_gce 代理会防护发生故障的 Compute Engine 虚拟机,该虚拟机会在 Pacemaker 将防护操作注册为完成之前重启并重新加入集群。由于防护操作尚未注册为完成,因此重启后的虚拟机会关闭其 Pacemaker 和 Corosync 服务并退出集群。

诊断

如需确认这就是您的问题所在,请执行以下操作:

  • 确保您的集群使用的是 fence_gce 代理:

    RHEL

    pcs config

    SLES

    crm config show

    防护代理定义包含 fence_gce

    RHEL

    Stonith Devices:
    Resource: STONITH-example-ha-vm1 (class=stonith type=fence_gce)
    Attributes: port=example-ha-vm1 project=example-project-123456 zone=us-central1-a
    Operations: monitor interval=300s timeout=120s (STONITH-example-ha-vm1-monitor-interval-60s)
    Resource: STONITH-example-ha-vm2 (class=stonith type=fence_gce)
    Attributes: port=example-ha-vm2 project=example-project-123456 zone=us-central1-c
    Operations: monitor interval=300s timeout=120s (STONITH-example-ha-vm2-monitor-interval-60s)
    

    SLES

    primitive fence-example-ha-vm1 stonith:fence_gce \
     op monitor interval=300s timeout=120s \
     op start interval=0 timeout=60s \
     params port=example-ha-vm1 zone=us-central1-a project=example-project-123456
    primitive fence-example-ha-vm2 stonith:fence_gce \
     op monitor interval=300s timeout=120s \
     op start interval=0 timeout=60s \
     params port=example-ha-vm2 zone=us-central1-c project=example-project-123456
  • 检查系统日志中是否出现以下消息:

    DATESTAMP> node2 stonith-ng[1106]:  notice: Operation reboot of node2 by node1 for stonith_admin.1366@node1.c3382af8: OK
    DATESTAMP> node2 stonith-ng[1106]:   error: stonith_construct_reply: Triggered assert at commands.c:2343 : request != NULL
    DATESTAMP> node2 stonith-ng[1106]: warning: Can't create a sane reply
    DATESTAMP> node2 crmd[1110]:    crit: We were allegedly just fenced by node1 for node1!
    DATESTAMP> node2 pacemakerd[1055]: warning: Shutting cluster down because crmd[1110] had fatal failure

解决方案

在两个集群节点中配置操作系统以延迟 Corosync 的启动,从而确保防护操作有时间向新的主节点上的 Pacemaker 注册为完成。此外,还需设置 Pacemaker 的重启超时值,以将该延迟考虑在内。

如需配置 Corosync 的延迟启动,请执行以下操作:

  1. 将集群置于维护模式:

    RHEL

    pcs property set maintenance-mode=true

    SLES

    crm configure property maintenance-mode="true"
  2. 在每个集群节点上,以根用户身份为 Corosync 设置启动延迟:

    1. 创建 systemd 普适性文件:

      systemctl edit corosync.service
    2. 将以下代码行添加到文件中:

      [Service]
      ExecStartPre=/bin/sleep 60
    3. 保存文件并退出编辑器。

    4. 重新加载 systemd 管理器配置。

      systemctl daemon-reload
  3. 在任一集群节点上,以 root 身份验证 Pacemaker 的重启超时值是否已针对这两个防护代理进行设置:

    1. 检查 pcmk_reboot_timeout 值:

      crm_resource --resource FENCE_AGENT_NAME --get-parameter=pcmk_reboot_timeout

      FENCE_AGENT_NAME 替换为防护代理的名称。

    2. 如果找不到 pcmk_reboot_timeout 参数或将其设置为小于 300 的值,请在两个防护代理上设置该值:

      crm_resource --resource FENCE_AGENT_NAME --set-parameter=pcmk_reboot_timeout --parameter-value=300

      FENCE_AGENT_NAME 替换为防护代理的名称。

      pcmk_reboot_timeout 值应大于以下各项之和:

      • Corosync token 超时
      • Corosync 共识超时,默认情况下为 token * 1.2 的乘积
      • 重启操作完成所需的时长,包括任何延迟特性。

      在 Google Cloud上,对于大多数集群来说,300 秒就足够了。

    3. 确认新的 pcmk_reboot_timeout 值:

      crm_resource --resource FENCE_AGENT_NAME --get-parameter=pcmk_reboot_timeout

      FENCE_AGENT_NAME 替换为防护代理的名称。

  4. 让集群退出维护模式:

    RHEL

    pcs property set maintenance-mode=false

    SLES

    crm configure property maintenance-mode="false"

无意中偏向特定节点的节点亲和性

当您使用集群命令手动移动高可用性集群中的资源时,会发现自动亲和性或客户端偏好设置已设置为优先考虑特定节点。

问题

在适用于 SAP HANA 或 SAP NetWeaver 的 Linux Pacemaker 高可用性集群中,SAP HANA 系统或 SAP NetWeaver 中央服务等资源仅在一个特定的集群节点上运行,并且在节点故障事件期间不会按预期进行故障切换。

因此,您可能会遇到以下问题:

  • 当您通过发出 Pacemaker 命令将资源 move 到集群节点来触发 SAP NetWeaver ASCS 服务故障切换时,资源不会启动并显示 stopped 状态。

  • 当您向一个集群节点发出 standby 命令以强制将所有资源移至另一个节点时,资源不会启动。

诊断

  • 检查您的 Pacemaker 日志,查找是否有消息提及特定资源无法在任何位置运行。例如:

    2021-05-24 21:39:58 node_1 pacemaker-schedulerd (native_color) info:
     Resource NW1-ASCS01 cannot run anywhere
  • 检查您的 Pacemaker 位置限制条件配置,以找出可能阻止资源在特定集群节点上运行的任何限制条件。

    如需检查 Pacemaker 位置限制条件配置,请按以下步骤操作:

    1. 显示位置限制条件:

      cibadmin --query --scope constraints | grep rsc_location
    2. 验证位置限制条件:

      • 显式位置限制条件:您可以找到得分为 INFINITY(优先考虑节点)或 -INFINITY(避免节点)的位置限制条件。例如:

        <rsc_location id="loc-constraint" rsc="NW1-ASCS01" score="INFINITY" node="nw-ha-1"/>

        除了防护代理之外,不得有任何得分为 INFINITY-INFINITY 的位置限制条件。在所有高可用性集群中,防护代理都定义在具有得分 -INFINITY 的位置限制条件中,以防止它们在作为防护目标的节点上运行。

      • 隐式位置限制条件:当您发出 Pacemaker 命令以将资源移动到集群节点或禁止资源在集群节点上运行时,前缀为 cli-bancli-prefer 的隐式位置限制条件会添加到限制条件 ID 中。例如:

        <rsc_location id="cli-prefer-NW1-ASCS01" rsc="NW1-ASCS01" role="Started" node="nw-ha-2" score="INFINITY"/>

解决方案

防护代理遇到了操作错误

防护代理已报告集群状态错误。

问题

在适用于 SAP HANA 或 SAP NetWeaver 的 Linux Pacemaker 高可用性集群中,防护代理已报告一个集群状态错误。例如:

Failed Resource Actions:
   STONITH-ha-node-01_monitor_300000 on ha-node-02 'unknown error' (1): call=153, status=Timed Out, exitreason='',  last-rc-change='Mon Dec 21 23:40:47 2023', queued=0ms, exec=60003ms

诊断

部署在 SAP HANA 或 SAP NetWeaver 高可用性集群中的防护代理会定期访问 Compute Engine API 服务器,以检查防护目标实例的状态。如果 API 调用响应出现暂时延迟,或者网络中断,则防护代理监控操作可能会失败或超时。

如需检查防护代理状态,请运行以下命令:

RHEL

pcs status

SLES

crm status

如果防护代理状态为 stopped,请使用以下任一解决方案来解决错误。

防护代理操作错误可能会导致防护代理停止,但 Pacemaker 仍会在防护事件中使用停止指令调用防护代理。

解决方案

如果防护代理状态为 stopped,请执行以下操作之一:

  • 如需手动重置失败计数并重启防护代理,请运行以下命令:

    RHEL

    pcs resource cleanup FENCE_AGENT_NAME

    SLES

    crm resource cleanup FENCE_AGENT_NAME

    FENCE_AGENT_NAME 替换为防护代理的名称。

  • 如需自动移除防护代理操作错误,请配置 failure-timeout 参数。

    failure-timeout 参数会在指定时长后重置失败计数并清除所有操作错误。应用此参数不需要您重启集群或将集群置于维护模式。

    如需配置 failure-timeout 参数,请运行以下命令:

    crm_resource --meta --resource FENCE_AGENT_NAME --set-parameter failure-timeout --parameter-value DURATION

    请替换以下内容:

    • FENCE_AGENT_NAME:防护代理的名称。
    • DURATION:上次操作失败后的时长,在此之后,会重置失败计数并重启防护代理。

防护代理 gcpstonith 已弃用

防护代理 gcpstonith 在您的配置中处于活动状态。此代理已弃用,客户服务部门已告知您必须改用 fence_gce

问题

在 SUSE Linux 上的适用于 SAP HANA 的 Linux Pacemaker 高可用性集群中,使用防护代理 gcpstonith。例如:

 # crm status | grep gcpstonith
   * STONITH-hana-vm1   (stonith:external/gcpstonith):   Started hana-vm2
   * STONITH-hana-vm2   (stonith:external/gcpstonith):   Started hana-vm1

诊断

您需要更新在 SAP HANA 高可用性集群中部署的栅格代理,以改用操作系统捆绑的 fence_gce 栅格代理。gcpstonith 代理脚本在旧版系统中提供,已被 fence_gce 取代。fence_gce 是作为 fence-agents SUSE Linux 软件包的一部分提供的。gcpstonith 仅在 SUSE Linux HANA 部署中提供。

解决方案

如需从 SUSE Linux 上的 gcpstonith 迁移,请完成以下步骤:

  1. 安装适用于您的操作系统的以下其他软件包:

    • 对于 SLES 15:python3-oauth2clientpython3-google-api-python-client

    • 对于 SLES 12:python-google-api-python-clientpython-oauth2clientpython-oauth2client-gce

    如需在您的操作系统上安装这些软件包,请使用以下命令:

    SLES 15

    zypper in -y python3-oauth2client python3-google-api-python-client

    SLES 12

    zypper in -y python-google-api-python-client python-oauth2client python-oauth2client-gce
  2. 更新 fence-agents 软件包,确保您安装的是最新版本:

    zypper update -y fence-agents
  3. 将集群置于维护模式:

    crm configure property maintenance-mode=true
  4. 从集群中删除所有防护设备。在删除最后一个防护设备时,系统可能会提示您确认集群中未定义任何 STONITH 资源。

    crm configure delete FENCING_RESOURCE_PRIMARY
    crm configure delete FENCING_RESOURCE_SECONDARY
  5. 为主实例重新创建防护设备:

    crm configure primitive FENCING_RESOURCE_PRIMARY stonith:fence_gce \
     op monitor interval="300s" timeout="120s" \
     op start interval="0" timeout="60s" \
     params port="PRIMARY_INSTANCE_NAME" zone="PRIMARY_ZONE" \
     project="PROJECT_ID" \
     pcmk_reboot_timeout=300 pcmk_monitor_retries=4 pcmk_delay_max=30
  6. 为辅助实例重新创建防护设备:

    crm configure primitive FENCING_RESOURCE_SECONDARY stonith:fence_gce \
     op monitor interval="300s" timeout="120s" \
     op start interval="0" timeout="60s" \
     params port="SECONDARY_INSTANCE_NAME" zone="SECONDARY_ZONE" \
     project="PROJECT_ID" \
     pcmk_reboot_timeout=300 pcmk_monitor_retries=4
  7. 设置位置限制条件:

    crm configure location FENCING_LOCATION_NAME_PRIMARY \
     FENCING_RESOURCE_PRIMARY -inf: "PRIMARY_INSTANCE_NAME"
    
    crm configure location FENCING_LOCATION_NAME_SECONDARY \
     FENCING_RESOURCE_SECONDARY -inf: "SECONDARY_INSTANCE_NAME"
    
  8. 让集群退出维护模式:

    crm configure property maintenance-mode=false

  9. 检查配置:

    crm config show related:FENCING_RESOURCE_PRIMARY
    
  10. 检查集群状态:

    # crm status | grep fence_gce
      STONITH-hana-vm1   (stonith:fence_gce):   Started hana-vm2
      STONITH-hana-vm2   (stonith:fence_gce):   Started hana-vm1
    

资源代理已停止

资源代理未能启动并保持 Stopped 状态。

问题

在适用于 SAP HANA 或 SAP NetWeaver 的 Linux Pacemaker 高可用性集群中,资源代理已报告一个集群状态错误。例如:

Failed Resource Actions:
   rsc_SAPHana_DV0_HDB00_start_0 on ha-node-02 'error' (1): call=91, status='complete', last-rc-change='Wed Oct 18 18:00:31 2023', queued=0ms, exec=19010ms

诊断

如果正在运行的资源代理失败,则 Pacemaker 会尝试停止并重启代理。如果启动操作因任何原因失败,则 Pacemaker 会将资源失败计数设置为 INFINITY,并尝试在其他节点上启动代理。如果资源代理无法在任何节点上启动,则该资源代理将保持 Stopped 状态。

如需检查资源代理状态,请运行以下命令:

RHEL

pcs status

SLES

crm status

对于 SAP HANA,以下示例展示了节点 hana-b 上处于 Stopped 状态的资源代理:

Full List of Resources:
  * STONITH-hana-a        (stonith:fence_gce):   Started hana-b
  * STONITH-hana-b        (stonith:fence_gce):   Started hana-a
  * Resource Group: g-primary:
    * rsc_vip_int-primary       (ocf::heartbeat:IPaddr2):        Started hana-a
    * rsc_vip_hc-primary        (ocf::heartbeat:anything):       Started hana-a
  * Clone Set: cln_SAPHanaTopology_DV0_HDB00 [rsc_SAPHanaTopology_DV0_HDB00]:
    * Started: [ hana-a hana-b ]
  * Clone Set: msl_SAPHana_DV0_HDB00 [rsc_SAPHana_DV0_HDB00] (promotable):
    * Masters: [ hana-a ]
    * Stopped: [ hana-b ]
  * STONITH-scaleup-majority    (stonith:fence_gce):   Started hana-b

解决方案

如果资源代理处于 Stopped 状态,请执行以下操作:

  1. 通过重置失败计数手动启动资源代理:

    RHEL

    pcs resource cleanup RESOURCE_AGENT_NAME

    SLES

    crm resource cleanup RESOURCE_AGENT_NAME

    RESOURCE_AGENT_NAME 替换为资源代理的名称。例如 rsc_SAPHana_DV0_HDB00

  2. 确保资源代理的状态处于 Started 状态:

    crm_mon

    如果资源代理仍无法启动,请收集相关诊断信息并与支持团队联系。

虚拟 IP 的本地网络路由导致虚拟机之间的通信失败

由于虚拟 IP 的本地网络路由,从一个后端虚拟机到另一个虚拟机的网络流量失败。

问题

当虚拟机是内部直通式网络负载均衡器的一部分时,后端网络通信会将 ILB 虚拟 IP (VIP) 路由视为本地路由,并由环回设备进行处理。

这种环回行为会阻止后端虚拟机成功使用 ILB 的 VIP 访问可能使用 ILB 托管在其他后端虚拟机上的服务,从而导致通信失败。

例如:配置为负载均衡器后端的 SAP Netweaver 高可用性集群中的 ASCS 和 ERS 之间的通信失败。

telnet 测试会导致 Connection Refused 错误,因为此本地路由不允许流量到达预期的虚拟机:

   [root@test-server-ha ~]# telnet IP_ADDRESS_OF_ILB PORT_NUMBER
   Trying IP_ADDRESS_OF_ILB...
   telnet: connect to address IP_ADDRESS_OF_ILB: Connection refused

诊断

前提条件:

受影响的虚拟机列为非托管式实例组的成员,并配置为负载均衡器后端。

当内部负载均衡器 (ILB) 中的后端虚拟机发起与 ILB 虚拟 IP (VIP) 的通信时,会发生特定的路由行为。

虽然 VIP 是在标准网络接口(如 eth0)上配置的,并且在本地路由表中列出,但内核会使用环回接口 lo 路由发往此本地 VIP 的数据包。这种内部环回意味着数据包永远不会离开发起虚拟机,以便由 ILB 进行处理。

虽然后端虚拟机之间使用各自的 IP 进行直接通信是可行的,但这种环回行为会阻止后端虚拟机成功使用 ILB 的 VIP 访问可能通过内部直通式网络负载均衡器托管在其他后端虚拟机上的服务。

   [root@test-server-ha ~]# ip route show table local
   local IP_ADDRESS_OF_ILB dev eth0 proto 66 kernel scope host src IP_ADDRESS_OF_ILB
   local IP_ADDRESS_OF_THE_CURRENT_NODE dev eth0 proto kernel scope host src IP_ADDRESS_OF_THE_CURRENT_NODE
   local IP_ADDRESS_OF_THE_OTHER_NODE dev eth0 proto kernel scope host src IP_ADDRESS_OF_THE_OTHER_NODE
   broadcast IP_ADDRESS dev lo proto kernel scope link src IP_ADDRESS
   local IP_ADDRESS dev lo proto kernel scope host src IP_ADDRESS
   broadcast IP_ADDRESS dev lo proto kernel scope link src IP_ADDRESS
   ip route get IP_ADDRESS_OF_ILB

此命令的输出会显示一个环回接口 lo

   [root@test-server-ha ~]# ip route get IP_ADDRESS_OF_ILB
   local IP_ADDRESS_OF_ILB dev lo src IP_ADDRESS_OF_ILB uid 0
   cache <local>

解决方案

您可以通过修改 google-guest-agent 的配置来启用虚拟机之间的后端通信,该配置包含在 Google Cloud提供的所有 Linux 公共映像的 Linux 客机环境中。

如需启用负载均衡器后端通信,请在集群中的每个虚拟机上执行以下步骤:

  1. 停止代理:

    sudo service google-guest-agent stop
    
  2. 打开或创建 /etc/default/instance_configs.cfg 文件进行修改。

    sudo vi /etc/default/instance_configs.cfg
    
  3. /etc/default/instance_configs.cfg 文件中,指定以下配置属性,如下所示。如果这些部分不存在,请创建它们。尤其要确保 target_instance_ipsip_forwarding 属性设置为 false:

    [IpForwarding]
    ethernet_proto_id = 66
    ip_aliases = true
    target_instance_ips = false
    
    [NetworkInterfaces]
    dhclient_script = /sbin/google-dhclient-script
    dhcp_command =
    ip_forwarding = false
    setup = true
    
  4. 启动访客代理服务:

    sudo service google-guest-agent start
    

如需应用更改,请执行虚拟机重启或以下步骤以删除本地路由

  1. 删除发送回流量的本地路由:

    sudo ip route del table local $(ip route show table local | grep "proto 66" | awk '{print $2}') dev eth0
    

    上述命令是一系列通过竖线连接在一起的 Linux 命令,用于从本地路由表中删除 VIP。详细说明上述每个命令:

    我们使用以下命令来识别 IP 地址,

    ip route show table local | grep "proto 66" | awk '{print $2}'
    

    然后将其传输到实际的删除命令中:

    ip route del table local
    
  2. 重启 Google 客机代理:

    systemctl google-guest-agent restart
    

此项更改不会造成中断。重启 google-guest-agent 会重新创建新的网络路由,以指示网络流量使用 eth0(而不是环回设备)将流量发送到 VIP。

如需验证更改,请运行以下命令:

   ip route get IP_ADDRESS_OF_ILB

此命令的输出必须显示网络接口(例如 eth0),而非环回接口 lo

   [root@test-server-ha ~]# ip route get IP_ADDRESS_OF_ILB
   IP_ADDRESS_OF_ILB via IP_ADDRESS_OF_ILB dev eth0 src IP_ADDRESS_OF_ILB uid 0
   cache

尝试 telnet 测试:

   [root@test-server-ha ~]# telnet IP_ADDRESS_OF_ILB PORT_NUMBER
   Trying IP_ADDRESS_OF_ILB...
   Connected to IP_ADDRESS_OF_ILB.
   Escape character is '^]'.