部署后使用 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 Management 做 PUT /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 集群无法判断是否存在网络分区,这就是问题的根本原因。
我有一个使用 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 Management 做 PUT /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 集群无法判断是否存在网络分区,这就是问题的根本原因。