共计 2160 个字符,预计需要花费 6 分钟才能阅读完成。
这篇文章主要介绍“kubernetes 中有状态应用怎么缩容”,在日常操作中,相信很多人在 kubernetes 中有状态应用怎么缩容 问题上存在疑惑,丸趣 TV 小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”kubernetes 中有状态应用怎么缩容”的疑惑有所帮助!接下来,请跟着丸趣 TV 小编一起来学习吧!
通过 StatefulSet 创建的每个 Pod 都有自己的 PersistentVolumeClaim(PVC)和 PersistentVolume(PV)。当按一个副本按比例缩小 StatefulSet 的大小时,其 Pod 之一将终止,但关联的 PersistentVolumeClaim 和绑定到其的 PersistentVolume 保持不变。在随后扩大规模时,它们会重新连接到 Pod。
Scaling a StatefulSet
现在,想象一下使用 StatefulSet 部署一个有状态的应用程序,其数据在其 pod 中进行分区。每个实例仅保存和处理一部分数据。当您缩小有状态应用的规模时,其中一个实例将终止,其数据应重新分配到其余的 Pod。如果您不重新分配数据,则在再次进行扩展之前,它仍然不可访问。
Redistributing data on scale-down
在正常关机期间重新分发数据
您可能会想:“既然 Kubernetes 支持 Pod 正常关闭的机制,那么 Pod 是否可以在关闭过程中简单地将其数据重新分配给其他实例呢?”事实上,它不能。为什么不这样做有两个原因:
Pod(或更确切地说,其容器)可能会收到除缩容以外的其他原因的终止信号。容器中运行的应用程序不知道为什么终止该程序,因此不知道是否要清空数据。
即使该应用程序可以区分是缩容还是由于其他原因而终止,它也需要保证即使经过数小时或数天也可以完成关闭程序。Kubernetes 不提供该保证。如果应用程序进程在关闭过程中死掉,它将不会重新启动,因此也就没有机会完全分发数据。
因此,相信在正常关闭期间 Pod 能够重新分发(或以其他方式处理其所有数据)并不是一个好主意,并且会导致系统非常脆弱。
使用 tear-down 容器?
如果您不是 Kubernetes 的新手,那么你很可能知道什么是初始化容器。它们在容器的主要容器之前运行,并且必须在主要容器启动之前全部完成。
如果我们有 tear-down 容器(类似于 init 容器),但是在 Pod 的主容器终止后又会运行,该怎么办?他们可以在我们的有状态 Pod 中执行数据重新分发吗?
假设 tear-down 容器能够确定 Pod 是否由于缩容而终止。并假设 Kubernetes(更具体地说是 Kubelet)将确保 tear-down 容器成功完成(通过在每次返回非零退出代码时重新启动它)。如果这两个假设都成立,我们将拥有一种机制,可确保有状态的容器始终能够按比例缩小规模重新分配其数据。
但是?
可悲的是,当 tear-down 容器本身发生瞬态错误,并且一次或多次重新启动容器最终使它成功完成时,像上述的 tear-down 容器机制将只处理那些情况。但是,在 tear-down 过程中托管 Pod 的集群节点死掉的那些不幸时刻又如何呢?显然,该过程无法完成,因此无法访问数据。
现在很明显,我们不应该在 Pod 关闭时执行数据重新分配。相反,我们应该创建一个新的 Pod(可能安排在一个完全不同的集群节点上)以执行重新分发过程。
这为我们带来了以下解决方案:
缩小 StatefulSet 时,必须创建一个新的容器并将其绑定到孤立的 PersistentVolumeClaim。我们称其为“drain pod”,因为它的工作是将数据重新分发到其他地方(或以其他方式处理)。Pod 必须有权访问孤立的数据,并且可以使用它做任何想做的事情。由于每个应用程序的重新分发程序差异很大,因此新的容器应该是完全可配置的 - 用户应该能够在 drain Pod 内运行他们想要的任何容器。
StatefulSet Drain Controller
由于 StatefulSet 控制器当前尚不提供此功能,因此我们可以实现一个额外的控制器,其唯一目的是处理 StatefulSet 缩容。我最近实现了这种控制器的概念验证。您可以在 GitHub 上找到源代码:
luksa/statefulset-scaledown-controllergithub.com
下面我们解释一下它是如何工作的。
在将控制器部署到 Kubernetes 集群后,您只需在 StatefulSet 清单中添加注释,即可将 drain 容器模板添加到任何 StatefulSet 中。这是一个例子:
apiVersion: apps/v1kind: StatefulSetmetadata: name: datastore annotations: statefulsets.kubernetes.io/drainer-pod-template: | { metadata : { labels : { app : datastore-drainer .........
到此,关于“kubernetes 中有状态应用怎么缩容”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注丸趣 TV 网站,丸趣 TV 小编会继续努力为大家带来更多实用的文章!