了解 Kubernetes 中的状态管理

已完成

通常情况下,在谈论应用程序时,你可能经常听到“应用程序状态”一词。 在本单元中,我们将回顾状态的定义和不同类型的状态,以便你可以更好地准备处理它们的应用程序。

State

应用程序状态是应用程序运行时存储在内存中的所有内容。 状态可能涉及多种东西,但我们主要关注用户数据。

为举例说明应用程序状态,假设你打开了音乐播放器。 此应用程序具有一个状态。 该状态知道你是谁、你喜欢听的内容,以及你下载的音乐。 所有这些信息都是应用程序状态的一部分。

内存中状态是应用程序不需要在其他任何位置查找的信息。 磁盘状态包含应用程序眼前没有的信息,因此需要从另一个数据源检索这些信息。

状态类型

应用程序状态有两种类型。 第一种类型是非永久性的临时状态,在应用程序关闭时会立即消失

容器具有临时状态。 其中存储的所有数据会在删除容器时立即丢失。 某些应用程序可以独立处理该状态,因为它们可从其他源重新生成状态,而无需将状态存储在本地。 这些应用程序被称为stateless应用程序。

所有其他的非临时状态均称为永久性状态。 永久性状态在容器的生命周期结束后继续存在。 我们使用的大多数容器技术都有“卷”的概念,即状态所在的磁盘中位置。 即使你删除容器然后再启动,状态仍存储在安全位置,并且可以再次使用。

依赖于外部状态进行检索的应用程序被称为stateful应用程序。

状态和 Kubernetes

Kubernetes 可以处理无状态应用程序和有状态应用程序。 无状态应用更容易处理,因为我们可以仅关注应用程序本身,而不关注其状态(因为状态不存在)。

对于大多数无状态应用程序,若要拥有功能全面的系统并充分利用群集,使用带 Pod 的简单部署工作负载即可。

处理有状态应用程序则相反。 在这些情况下,你需要考虑应用程序及其状态、状态存储位置以及状态的安全可靠的存储方法。

这就是 Kubernetes 也使用了 PersistentVolumes (PV) 和 PersistentVolumeClaims (PVC) 概念的原因。

提示

本模块不会进一步讨论存储概念,但你可以参考摘要中的 Azure Kubernetes 服务资源以了解更多信息。

PersistentVolumes 是在节点中分配的磁盘,用于存储来自 Pod 容器的状态。 因为 Kubernetes 最适用于分布式应用,所以所有创建的卷都位于一组“可用卷”中。 容器随后会为自己声明该空间。 你可以使用 PersistentVolumeClaimsPersistentVolume 与 Pod 绑定,并使用其空间来存储所需数据。

所有数据库提供程序都是有状态应用程序。 如果要在群集中部署一个数据库提供程序,则需要 PV 和 PVC 才能将数据库数据存储在安全位置,并允许提供程序检索该数据(即使提供程序的容器已删除)。

状态处理的最佳做法

大多数应用程序都具有状态。 然而,处理状态的最佳做法是根本不处理它。

你可抱着使应用高度可用和高度可缩放的目标来设计任何高效应用程序。 但状态与之相反。 尽管存储提供程序提供了选项,并且部署和使用很容易,但状态并不能轻松缩放。 它也不是高度可用的。

高度可用状态

若要实现高可用性,应用程序必须始终处于联机状态。 使用区域和地区复制可以实现这一点。 Kubernetes 在其大多数工作负载中都具有区域感知能力。 这意味着你可以使用部署在不同区域的多个应用程序实例。 然而,磁盘不具有区域感知能力。

在 Kubernetes 上部署新的 PersistentVolume 对象时,它会绑定到一个节点上的磁盘。 该磁盘也将绑定到特定地区的特定区域。 同时使用 PV 和区域/地区复制会很复杂,需要大量维护来复制数据和同步数据。

高度可缩放状态

应用程序要做到高度可缩放,应随着与其连接的用户数的增加而增加吞吐量。 这在状态管理中很复杂,因为所有外部状态本质上都是磁盘,而磁盘的输入和输出速率有限。 吞吐量管理有助于解决这一问题。

数据库解决方案提出了“ReplicaSets”这一想法,那就是将整个数据库复制到多个实例中。 复制会增加磁盘数量以及状态的 I/O。

每次数据库更改时,都需要同步状态,以便所有磁盘都包含相同的数据。 此同步也很复杂。

将状态外部化

Azure 使用了高度可用且高度可缩放的平台即服务(PaaS) 解决方案(例如 Azure Cosmos DB),为你解决了大多数状态管理问题。

通过在外部存储状态并消除维护需求,可助你专注于应用程序并减少在基础结构中处理数据完整性的开销。

知识检查

1.

什么是应用程序的永久性状态?

2.

Kubernetes 如何处理状态?

3.

在 Kubernetes 应用程序中处理状态的最佳做法是什么?