前言

与 Depolyment 不同, 在现实应用中, 尤其是分布式应用,它的多个实例之间,往往有依赖关系,比如:主从关系、主备关系。还有就是数据存储类应用,它的多个实例,往往都会在本地磁盘上保存一份数据。而这些实例一旦被杀掉,即便重建出来,实例与数据之间的对应关系也已经丢失,从而导致应用失败。

此时 Depolyment 就不能满足需求了. 对于这种实例之间有不对等关系, 以及实例对外部数据有依赖关系的应用, 就被成为 有状态应用 (Stateful Application)

StatefulSet

StatefulSet 的设计其实非常容易理解。它把真实世界里的应用状态,抽象为了两种情况:

所以,StatefulSet 的核心功能,就是通过某种方式记录这些状态,然后在 Pod 被重新创建时,能够为新 Pod 恢复这些状态。

<aside> 💡 对于“有状态应用”实例的访问,必须使用 DNS 记录或者 hostname 的方式,而绝不应该直接访问这些 Pod 的 IP 地址。因为Pod 的IP地址可能由于 Pod 的重启而变化

</aside>

通过具体的 Service 方式, k8s 保证StatefulSet 状态的一致, 即使在Pod重启之后 (只要StatefulSet不被删除) , 那么一定能保证正确的启动顺序, 以及能够解析到正确的 Pod 的地址

k8s Service

StatefulSet 的控制过程

StatefulSet 这个控制器的主要作用之一,就是使用 Pod 模板创建 Pod 的时候,对它们进行编号,并且按照编号顺序逐一完成创建工作。而当 StatefulSet 的“控制循环”发现 Pod 的“实际状态”与“期望状态”不一致,需要新建或者删除Pod 进行“调谐”的时候,它会严格按照这些 Pod 编号的顺序,逐一完成这些操作。

StatefulSet 存储状态

StatefulSet 对存储状态的管理机制, 主要依赖于 Persistent Volume Claim(PVC)Persistent Volume(PV)

k8s PV & PVC & StorageClass

而 PVC、PV 的设计,也使得 StatefulSet 对存储状态的管理成为了可能。