部署后使用 marathon-api 自动关闭 Akka 集群中的节点

Automatically down nodes in Akka cluster with marathon-api after deployment

我有一个使用 marathon-api 和 ClusterBootstrap

部署 Akka 集群的应用程序

当部署运行时,它会执行以下操作:

我们有一个包含 4 个节点的集群

部署后集群看起来像这样(假设本例中有 2 个实例):

{
  "leader": "akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655",
  "members": [
    {
      "node": "akka.tcp://app@ip-10-0-4-8.eu-central-1.compute.internal:15724",
      "nodeUid": "-1598489963",
      "roles": [
        "dc-default"
      ],
      "status": "Up"
    },
    {
      "node": "akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655",
      "nodeUid": "-1604243482",
      "roles": [
        "dc-default"
      ],
      "status": "Up"
    }
  ],
  "oldest": "akka.tcp://app@ip-10-0-4-8.eu-central-1.compute.internal:15724",
  "oldestPerRole": {
    "dc-default": "akka.tcp://app@ip-10-0-4-8.eu-central-1.compute.internal:15724"
  },
  "selfNode": "akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655",
  "unreachable": [
    {
      "node": "akka.tcp://app@ip-10-0-4-8.eu-central-1.compute.internal:15724",
      "observedBy": [
        "akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655"
      ]
    }
  ]
}

有时 leader 仍然是 WeaklyUp 但想法是一样的,而 gone 节点可以是 up 或 Leaving。

然后日志开始显示此消息:

Cluster Node [akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655] - Leader can currently not perform its duties, reachability status: [akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655 -> akka.tcp://app@ip-10-0-4-8.eu-central-1.compute.internal:15724: Unreachable [Unreachable] (1)], member status: [
akka.tcp://app@ip-10-0-4-8.eu-central-1.compute.internal:15724 Up seen=false, 
akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655 Up seen=true]

并且部署更多次会使情况变得更糟

我想当一个节点被杀死时会改变集群的状态,因为那时它实际上是不可访问的,但我希望有某种功能可以解决这个问题

到目前为止,唯一能解决这个问题的方法是使用 Akka Cluster HTTP ManagementPUT /cluster/members/{address} operation:Down

我知道有一个名为 Auto-downing 的功能已被删除,因为它弊大于利。

我也尝试 Split Brain Resolver 使用那里提供的策略,但最后这些策略最终导致整个集群崩溃,日志如下:

> Cluster Node [akka://app@ip-10-0-5-215.eu-central-1.compute.internal:43211] - Leader can currently not perform its duties, reachability status: [akka://app@ip-10-0-5-215.eu-central-1.compute.internal:43211 -> akka://app@ip-10-0-4-146.eu-central-1.compute.internal:2174: Unreachable [Unreachable] (1)], member status: [akka://app@ip-10-0-4-146.eu-central-1.compute.internal:2174 Up seen=false, akka://app@ip-10-0-5-215.eu-central-1.compute.internal:43211 Up seen=true]
> Running CoordinatedShutdown with reason [ClusterDowningReason]
> SBR is downing
> SBR took decision DownReachable and is downing

也许我没有使用正确的配置设置正确的策略,但我不确定要尝试什么,我有一个 4 节点集群,所以我猜默认的 Keep Majority 应该这样做,虽然这种情况更像是一个崩溃的节点而不是网络分区

有没有办法使用 marathon-api 顺利部署 Akka 集群?我乐于接受建议

更新: 我还将 Akka 版本从 2.5.x 更新到 2.6.x,文档指出它不兼容,因此我需要手动干预第一次部署。最后使用默认配置的 Split Brain Resolver 确实有效

您需要使用像 Split Brain Resolver 这样的“真正的”downing 提供商。这可以让集群安全地关闭无法访问的节点。 (与自动击倒相反,自动击倒他们而不考虑它是否安全。)

还有一个单独的问题,即为什么 DC/OS 如此迅速地杀死节点,以至于它们没有机会正确关闭。但我对 DC/OS 的了解还不足以说明为什么会这样。而且,无论如何,downing provider 对于集群环境是必不可少的,因此无论如何您都希望将其安装到位。

根据您对 SBR 的评论进行了编辑:

  • 首先我想澄清一下,marathan-api 在这里几乎肯定是无关紧要的。 marathon-api 是节点发现 DC/OS 中其他节点的方式。您遇到的问题是基本的集群问题,即无法访问的节点。具有无法访问的节点的集群将以相同的方式运行,无论它在哪里 运行 以及如何发现节点。
  • 从根本上说,我最好的猜测是您在正常关机方面遇到了问题。如果 SBR 正在关闭您的整个集群,那是因为它已经到了无法访问的节点多于活动集群的程度。

例如,可能发生的情况:

  • 您有 4 个活动节点并想要升级。
  • DC/OS 杀死第一个节点。由于某些未知原因,您没有完全关闭,因此该节点被标记为无法访问。 (本质上是集群,因为它不是干净的关闭,如果节点仍然存在但在分区后面没有响应 and/or 则不会节点。)有 3 个活动节点和一个无法访问。
  • DC/OS 启动第二个节点。启动您的应用程序可能需要一段时间。因此,您有 3 个活动节点、1 个无法访问的节点和 1 个未就绪的节点。
  • DC/OS 杀死另一个节点。因此,您有 2 个活动节点、2 个无法访问的节点和 1 个未就绪的节点。此时SBR不能再保证你没有网络分区,因为你没有多数。此时,为了防止损坏,必须停止集群。

所以,我会推荐以下内容:

  • 我不太了解 DC/OS 的详细信息,但您可能需要放慢滚动升级的速度。在 K8S 中,我会使用类似 MinReadySeconds 的东西。
  • 您可能需要考虑第五个节点。奇数更好,因为它更容易确定多数。
  • 如果问题仍然存在,您将需要提供更多关于 SBR 决定的日志。

SBR 就是这里的答案。我知道你没有真正的网络分区,但你有无法访问的节点这一事实意味着 Akka 集群无法判断是否存在网络分区,这就是问题的根本原因。