简介:
    image.png

    从1.9 GA版本开始,StatefulSet成为kubernetes的稳定特性,StatefulSet是一种副本控制器,管理pod的部署、缩放等

    与ReplicaSet、Deployment不同的是,它对集合中的pod提供顺序、唯一性保证,StatefulSet为集合中的每个pod分配唯一、持久的pod名称、DNS解析、持久化存储,并且负责将这些标识粘在pod上,无论pod调度到任何节点上

    StatefulSet 作为 Controller 为 Pod 提供唯⼀的标识,它可以保证部署和 scale 的顺序

    StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计) , 其应用场景包括:

    • 稳定的持久化存储: 即Pod重新调度后还是能访问到相同的持久化数据, 基于PVC来实现
    • 稳定的网络标志: 即Pod重新调度后其PodName和HostName不变, 基于Headless Service(即没有Cluster IP的Service) 来实现
    • 有序部署: 即Pod是有顺序的, 在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下⼀个Pod运行之前所有之前的Pod必须都是Running和Ready状态) , 基于init containers来实现有序收缩, 有序删除(即从N-1到0)

    组成部分:
    image.png

    从上面的应用场景可以发现, StatefulSet由以下几个部分组成:

    • 用于定义网络标志(DNS domain) 的Headless Service
    • 用于创建PersistentVolumes的volumeClaimTemplates
    • 定义具体应用的StatefulSet

    StatefulSet中每个Pod的DNS格式 :
    image.png

    StatefulSet中每个Pod的DNS格式为 statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local , 其中

    • serviceName 为Headless Service的名字
    • 0..N-1 为Pod所在的序号, 从0开始到N-1
    • statefulSetName 为StatefulSet的名字
    • namespace 为服务所在的namespace, Headless Servic和StatefulSet必须在相同的namespace
    • .cluster.local 为Cluster Domain

    部署和Scale保证:
    image.png

    • 对于有N个副本的StatefulSet,Pod将按照{0..N-1}的顺序被创建和部署
    • 当删除Pod的时候,将按照逆序来终结,从{N-1..0}
    • 对Pod执行scale操作之前,它所有的前任必须处于Running和Ready状态
    • 在终止Pod前,它所有的继任者必须处于完全关闭状态

    为什么需要 Headless 配合:
    image.png

    在deployment中,每一个pod是没有名称,是随机字符串,是无序的

    而statefulset中是要求有序的,每一个pod的名称必须是固定的,当节点挂了,重建之后的标识符是不变的,每一个节点的节点名称是不能改变的,pod名称是作为pod识别的唯一标识符,必须保证其标识符的稳定并且唯一

    为了实现标识符的稳定,这时候就需要一个headless service 解析直达到pod,还需要给pod配置一个唯一的名称

    为什么需要 volumeClainTemplate :
    image.png

    大部分有状态副本集都会用到持久存储,比如分布式系统来说,由于数据是不一样的,每个节点都需要自己专用的存储节点

    而在deployment中pod模板中创建的存储卷是一个共享的存储卷,多个pod使用同一个存储卷,而statefulset定义中的每一个pod都不能使用同一个存储卷,由此基于pod模板创建pod是不适应的

    这就需要引入volumeClainTemplate,当在使用statefulset创建pod时,会自动生成一个PVC,从而请求绑定一个PV,从而有自己专用的存储卷

    更新策略:
    image.png

    在Kubernetes 1.7及更高版本中,通过.spec.updateStrategy字段允许配置或禁用Pod、labels、source request/limits、annotations自动滚动更新功能

    • OnDelete:通过.spec.updateStrategy.type 字段设置为OnDelete,StatefulSet控制器不会自动更新StatefulSet中的Pod,用户必须手动删除Pod,以使控制器创建新的Pod。
    • RollingUpdate:通过.spec.updateStrategy.type 字段设置为RollingUpdate,实现了Pod的自动滚动更新,如果.spec.updateStrategy未指定,则此为默认策略

    StatefulSet控制器将删除并重新创建StatefulSet中的每个Pod,它将以Pod终止(从最大序数到最小序数)的顺序进行,一次更新每个Pod,在更新下一个Pod之前,必须等待这个Pod Running and Ready

    • Partitions:通过指定 .spec.updateStrategy.rollingUpdate.partition 来对 RollingUpdate 更新策略进行分区,如果指定了分区,则当 StatefulSet 的 .spec.template 更新时,具有大于或等于分区序数的所有 Pod 将被更新


    具有小于分区的序数的所有 Pod 将不会被更新,即使删除它们也将被重新创建,如果 StatefulSet 的 .spec.updateStrategy.rollingUpdate.partition 大于其 .spec.replicas,则其 .spec.template 的更新将不会传播到 Pod,在大多数情况下,不需要使用分区。

    相关文档:https://www.cnblogs.com/wlbl/p/10694356.html
    相关文档:https://www.cnblogs.com/tylerzhou/p/11027559.html