StatefulSet

StatefulSet 用于管理有状态 Pod 的控制器,例如 Redis,ZK 等,与 Deployment 相反。在 K8s 上定义和管理有状态的应用是比较困难的,每个有状态的服务都有自己的特性,你要考虑它们出现问题之后的重启方式,数据恢复方式等等问题。github 上有很多已经写好了相对应的服务的有状态服务的配置方式,但是都不建议使用在自己的 K8s 生产环境中。

StatefulSet

主要用于管理有以下状态的应用:

  1. 稳定且有唯一的网络标识符。

  2. 稳定且持久的存储。

  3. 有序,平滑的部署和拓展。

  4. 有序,平滑的删除和终止。

StatefulSet 由三部分组成:

  1. headless service (无头服务)
  2. StatefulSet (StatefulSet 控制器)
  3. volumeClaimTemplate (存储卷申请模版。能自动为 Pod 创建 Volume 并且创建 Pvc。)

定义一个 StatefulSet 示例如下:

以上 yaml 配置文件创建了一个 ClusterIP 为 Node 的无头服务,并且创建了一个 Statefulset,里面有volumeClainmTemplate 存储卷申请模版,申请绑定一个模式为 RWO,大小为 5G 的存储。并且将映射到容器中的 /usr/share/nginx/html 下。

创建 Pod 是顺序创建的,且名称是固定有序的,能被解析的。当对 Pod 进行删除动作时,会进行逆序删除。当对 StatefulSet Replicas 数量进行增加的时候,他也会像新创建的时候创建出对应的 pod,pvc。

当对 StatefulSet 应用进行镜像升级的时候,我们可以选择 rollingUpdate,并可以设置 patition。

partition 默认为 0,即代表大于等于 0 的 Pod 都将会被更新。如果设置为 5 则代表 Pod 序号大于等于 5 的 Pod 都将会被更新。我们可以设置 partition 的数值来实现金丝雀发布。例如现在有 10 个 Pod,我们可以设置 partition 为 10。这样就只能更新序号为 10 的 Pod。如果序号为 10 的 Pod 没问题之后,我们在将 partition 设置为 0,使其全部进行更新。