StatefulSet是用于来管理有状态应用的对象。StatefulSet管理了一组Pod的部署和伸缩,并保证了这些Pod的顺序和唯一性。
像Deployment一样,StatefulSet管理基于相同容器规范的Pod。与Deployment不同,StatefulSet为其每个Pod维护一个粘性身份。这些Pod是根据相同的spec创建的,但不能互换,因为每个Pod都有一个永久性标识符,该标识符在任何重新计划中都会维护。
简单的示例
1 | apiVersion: v1 |
上面的Service是一个Headless Service,用来控制网络域。
spec.serviceName
: 必须字段。serviceName是管理此StatefulSet的服务名称。并且负责该集合的网络标识。Pod会遵循以下格式获取DNS/主机名:pod-specific-string.serviceName.default.svc.cluster.local
,其中pod-specific-string
由StatefulSet控制器管理。
该manifest已保存到Github:https://raw.githubusercontent.com/chengqing-su/kubernetes-learning/master/stateful-set%20/nginx-stateful-set.yaml
如何创建/更新/删除一个StatefulSet
创建
执行命令:
1 | kubectl apply -f https://raw.githubusercontent.com/chengqing-su/kubernetes-learning/master/stateful-set%20/nginx-stateful-set.yaml |
结果:
如何管理Pod
与 Deployment 不同的是, StatefulSet 是直接管理Pod的。下面展示的是web-stateful-set-0
的metadata
。
1 | metadata: |
粘性身份
ReplicaSet 创建的Pod的名称是由ReplicaSet的名称和一个随机字符串组成,比如web-server-jqxfq
。 Deployment 是通过ReplicaSet管理Pod,因此名称规则和 ReplicaSet 一致。
StatefulSet 有一个唯一的身份,它由一个序数、一个稳定的网络身份和稳定的存储组成。无论它(重新)调度在哪个节点上,标识都与Pod保持一致。
- 其序数是从0到N-1(其中N为Pod的数量)。
- 稳定的网络身份。StatefulSet中的每个Pod都从StatefulSet的名称和Pod的序数派生其主机名。 构造的主机名的模式为
$(StatefulSet name)-$(序数)
。 上面的示例了创建三个名为web-stateful-set-0
,web-stateful-set-1
,web-stateful-set-2
的Pod。 - 稳定的存储。Kubernetes为每个
VolumeClaimTemplate
创建一个PersistentVolume
。将Pod调度(重新)到节点上时,其volumeMounts
会安装与其PersistentVolume Claims
关联的PersistentVolumes
。删除Pod或StatefulSet时,不会删除与Pods的PersistentVolume声明关联的PersistentVolumes,必须手动完成。
更新
将上述manifest中的nginx的版本升级到1.17,新的一份manifest:https://raw.githubusercontent.com/chengqing-su/kubernetes-learning/master/stateful-set%20/nginx-stateful-set-update.yaml
执行命令:
1 | kubectl apply -f https://raw.githubusercontent.com/chengqing-su/kubernetes-learning/master/stateful-set%20/nginx-stateful-set-update.yaml |
结果:
删除
执行命令:
1 | kubectl delete -f https://raw.githubusercontent.com/chengqing-su/kubernetes-learning/master/stateful-set%20/nginx-stateful-set-update.yaml |
或者
1 | kubectl delete sts web-stateful-set |
结果:
部署和伸缩的保证
在上面的创建/更新/删除的操作中,能够更好的验证下述规则。
对于具有N个副本的StatefulSet,在部署Pod时,将按{0..N-1}的顺序顺序创建它们。
删除Pod时,它们以相反的顺序从{N-1..0}终止。
在对Pod进行缩放操作之前,其所有前面的Pod必须处于“运行且就绪”状态。
在终止Pod之前,必须完全关闭其所有后面所有的。
什么时候使用
StatefulSet对于需要以下一项或多项的应用程序非常有用。
稳定的唯一网络标识符。
稳定(跨Pod调度/重新计划的持久性),持久的存储。
有序,顺畅的部署和扩展。
有序的自动滚动更新。
有哪些局限
给定Pod的存储必须由PersistentVolume提供者根据请求的存储类进行设置,或者由管理员预先设置。
删除或缩小StatefulSet不会删除与StatefulSet关联的卷。这样做是为了确保数据安全,这通常比自动清除所有相关的StatefulSet资源有价值。
StatefulSet当前需要Headless Service来负责Pod的网络身份。
删除StatefulSet时,StatefulSet不提供有关Pod终止的任何保证。为了实现StatefulSet中Pod的有序且正常的终止,可以在删除之前将StatefulSet缩小为0。
如果将滚动更新与默认的Pod管理策略(OrderedReady)结合使用,则可能会陷入损坏状态,需要人工干预才能进行修复。