Kubernetes 滚动更新通常会保留本地数据吗?

Kubernetes 滚动更新通常会保留本地数据吗?

使用本地节点存储来保存可变状态的 Kubernetes 应用程序(如Kubernetes 101例如)在应用程序更新时会丢失其存储空间。这是典型的部署更新方法启动新 Pod 并关闭旧 Pod。这很不幸,因为这意味着将数据(可能数百 GB)重新复制到每个节点,即使数据通常已经在无法访问的卷中。这大大减慢了更新速度。

应用程序程序员可以做什么来优化这一点?一些 pod 属性可以就地更新,但这仅涵盖一小部分更新。持久卷本质上是远程的,而不是本地的,因此它们无法被映射,并且不会具有与本地存储相同的性能;并且它们的生命周期不适当地与应该拥有它们的部署无关。问题 #9043讨论了该问题,但似乎没有达成任何共识;而且,无论如何,有时可以在同一节点上替换 pod,但不能就地更新。问题 #7562开始讨论它,但是它变成了对持久卷的讨论。问题 #598是相关的,但它实际上适用于你希望 pod 保持未分配给任何节点而不是以空目录启动它的情况。

答案1

就目前的 Kubernetes 设计而言,本地存储应该总是被视为短暂的,就像容器或 pod 一样。不仅仅是因为这样的场景,还因为你的 pod 可能随时崩溃并被重新安排。从卷文档

当 Pod 由于任何原因从节点中删除时,emptyDir 中的数据将被永久删除。

...

emptyDir 的一些用途如下:

  • 临时空间,例如用于基于磁盘的合并排序
  • 检查崩溃恢复所需的长时间计算
  • 保存内容管理器容器获取的文件,而 Web 服务器容器提供数据

GCE SSD 持久磁盘非常快,但如果您确实需要本地存储的性能,则可以从持久存储中临时复制数据来使用它。

答案2

如果您可以容忍它施加的限制,您可以考虑使用 hostPath 或本地 PV。

这应该可以让您获得 mmapping 的性能优势(因为卷是本地的)。但是,您需要考虑以下几点:

  • hostPath PV 仅支持 ReadWriteOnce (https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes),这意味着您可能需要使用 Delete 而不是 RollingUpgrade 的更新策略。
  • 如果您的集群包含多个节点,则需要考虑如何处理过时的 PV 内容 - initContainer 可能能够帮助解决这个问题。
  • 根据您的需要,您还需要考虑使用本地存储(hostPath PV 或其他)对您的扩展能力的影响 - 能够从一个实例中提取最大性能是一回事,但您可能会发现水平扩展最终是一个比大量优化更灵活、更通用的解决方案。

并且它们的生命周期不适当地与应该拥有它们的部署无关。

您可能还想研究的另一件事是您的选择对象——至少在我看来,部署应该是无状态的。

Statefulsets 通常更适合于确实需要一些状态暂停的情况(并且 statefulsets 对滚动更新的解释与部署不同),并为管理 PV 提供一些帮助。

相关内容