0

如果我在 statefulSet 中部署 Postgres而不使用副本(仅一个 pod)并且我杀死了运行有状态集的节点,我将能够启动节点并重新连接到持久数据库

这是一个示例配置: https ://medium.com/@suyashmohan/setting-up-postgresql-database-on-kubernetes-24a2a192e962

我正在与一个确信这不应该工作的人一起工作,并且 statefulSets 仅作为一种维护副本之间状态的方式才有意义。我的印象是,将 PG 数据挂载到临时 pod 的问题是特定于不使用 statefulSet,即使上面的示例中只有一个 pod,这仍然会使用 StatefulSet 来解决问题。

(如在这个官方 mysql 示例中:https ://kubernetes.io/docs/tasks/run-application/run-replicated-stateful-application/

4

1 回答 1

2

如果 Pod 使用持久化卷存储,数据库将被持久化。Ephemeral Volumes不是持久化的,不应该用来保存数据库,顾名思义,持久性没有长期保证。

但是,如果您的 Pod 将数据库保存在某种持久化卷上(例如节点本身的本地存储或更复杂的东西),那么它将在运行之间持久化。

这意味着如果您的 Pod 在一个节点上运行,假设在该节点上使用本地存储,如果您停止该节点然后使其正确重新启动,则该 Pod 将再次被调度,并且持久卷将与所有之前保存的数据。


话虽如此,如果您只有 1 个 Pod(StatefulSet 只有 1 个副本)并且 Pod 当前运行的节点以某种方式被杀死/停止工作/停止响应,那么 Pod 将不会在另一个节点上自动重新启动(即使您没有使用本地存储)

当然,您将能够强制它运行到另一个节点,但只能通过手动操作。

这是因为(来自文档):

在 StatefulSet 的正常操作中,永远不需要强制删除 StatefulSet Pod。StatefulSet 控制器负责创建、缩放和删除 StatefulSet 的成员。它试图确保从序数 0 到 N-1 的指定数量的 Pod 处于活动状态并准备就绪。StatefulSet 确保在任何时候, 集群中最多有一个具有给定身份的 Pod 运行 。这被称为 StatefulSet 提供的至多一个语义。

如果控制器无法确定 Pod 是否正在运行(并且节点因错误而被杀死或停止正常工作的例子就是这种情况),那么 Pod 将永远不会重新启动,直到:

  • 手动操作,例如强制删除。
  • 节点再次开始应答并再次变为就绪状态。

请注意,耗尽节点不会产生任何问题,因为它会在再次启动 StatefulSets Pod 之前(在其他节点上)优雅地终止它们。


StatefulSets 可以很好地用于数据库,但通常它需要更复杂的安装,具有多主节点和(至少)3 个副本。

此外,数据库需要在磁盘上进行非常快速的写入操作,因此如果它们可以在高质量磁盘上工作,它们的性能会更好。


更新:

StatefulSets 通常用于每个副本 Pod 需要唯一身份时(使用仲裁的多主数据库或应用程序就是这种必要性的一个很好的例子)

当仅使用 1 个副本进行部署时,与 Deployment 的差异很小(但存在差异,例如,如果正在运行的节点停止工作,Deployment 的 Pod 最终会在另一个节点上重新启动,StatefulSet Pod 将需要手动干预) .. 一般来说,您应该参考文档中的“使用 StatefulSets ”来决定应用程序是否需要作为 StatefulSet 或 Deployment 运行。

就我个人而言,我会将数据库作为 StatefulSet 运行,因为它是一个有状态的应用程序。但我也会使用 3 个副本运行它,这样它就可以在不停止工作的情况下遭受一个 Pod 的丢失。

于 2022-01-24T13:28:52.020 回答