简介:
从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)
组成部分:
从上面的应用场景可以发现, StatefulSet由以下几个部分组成:
- 用于定义网络标志(DNS domain) 的Headless Service
- 用于创建PersistentVolumes的volumeClaimTemplates
- 定义具体应用的StatefulSet
StatefulSet中每个Pod的DNS格式 :
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保证:
- 对于有N个副本的StatefulSet,Pod将按照{0..N-1}的顺序被创建和部署
- 当删除Pod的时候,将按照逆序来终结,从{N-1..0}
- 对Pod执行scale操作之前,它所有的前任必须处于Running和Ready状态
- 在终止Pod前,它所有的继任者必须处于完全关闭状态
为什么需要 Headless 配合:
在deployment中,每一个pod是没有名称,是随机字符串,是无序的
而statefulset中是要求有序的,每一个pod的名称必须是固定的,当节点挂了,重建之后的标识符是不变的,每一个节点的节点名称是不能改变的,pod名称是作为pod识别的唯一标识符,必须保证其标识符的稳定并且唯一
为了实现标识符的稳定,这时候就需要一个headless service 解析直达到pod,还需要给pod配置一个唯一的名称
为什么需要 volumeClainTemplate :
大部分有状态副本集都会用到持久存储,比如分布式系统来说,由于数据是不一样的,每个节点都需要自己专用的存储节点
而在deployment中pod模板中创建的存储卷是一个共享的存储卷,多个pod使用同一个存储卷,而statefulset定义中的每一个pod都不能使用同一个存储卷,由此基于pod模板创建pod是不适应的
这就需要引入volumeClainTemplate,当在使用statefulset创建pod时,会自动生成一个PVC,从而请求绑定一个PV,从而有自己专用的存储卷
更新策略:
在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