与 Depolyment 不同, 在现实应用中, 尤其是分布式应用,它的多个实例之间,往往有依赖关系,比如:主从关系、主备关系。还有就是数据存储类应用,它的多个实例,往往都会在本地磁盘上保存一份数据。而这些实例一旦被杀掉,即便重建出来,实例与数据之间的对应关系也已经丢失,从而导致应用失败。
此时 Depolyment 就不能满足需求了. 对于这种实例之间有不对等关系, 以及实例对外部数据有依赖关系的应用, 就被成为 有状态应用 (Stateful Application)
StatefulSet 的设计其实非常容易理解。它把真实世界里的应用状态,抽象为了两种情况:
所以,StatefulSet 的核心功能,就是通过某种方式记录这些状态,然后在 Pod 被重新创建时,能够为新 Pod 恢复这些状态。
<aside> 💡 对于“有状态应用”实例的访问,必须使用 DNS 记录或者 hostname 的方式,而绝不应该直接访问这些 Pod 的 IP 地址。因为Pod 的IP地址可能由于 Pod 的重启而变化
</aside>
通过具体的 Service 方式, k8s 保证StatefulSet 状态的一致, 即使在Pod重启之后 (只要StatefulSet不被删除) , 那么一定能保证正确的启动顺序, 以及能够解析到正确的 Pod 的地址
StatefulSet 这个控制器的主要作用之一,就是使用 Pod 模板创建 Pod 的时候,对它们进行编号,并且按照编号顺序逐一完成创建工作。而当 StatefulSet 的“控制循环”发现 Pod 的“实际状态”与“期望状态”不一致,需要新建或者删除Pod 进行“调谐”的时候,它会严格按照这些 Pod 编号的顺序,逐一完成这些操作。
StatefulSet 对存储状态的管理机制, 主要依赖于 Persistent Volume Claim(PVC)
和 Persistent Volume(PV)
而 PVC、PV 的设计,也使得 StatefulSet 对存储状态的管理成为了可能。