“Deployment用于部署无状态服务,StatefulSet用来部署有状态服务”。
具体的,什么场景需要使用StatefulSet呢?官方给出的建议是,如果你部署的应用满足以下一个或多个部署需求,则建议使用StatefulSet。
稳定的主要是针对Pod发生re-schedule后仍然要保持之前的网络标识和持久化存储。这里所说的网络标识包括hostname、集群内DNS中该Pod对应的A Record,并不能保证Pod re-schedule之后IP不变。要想保持Pod IP不变,我们可以借助稳定的Pod hostname定制IPAM获取固定的Pod IP。借助StatefulSet的
稳定的唯一的网络标识
特性,我们能比较轻松的实现Pod的固定IP需求,然后如果使用Deployment,那么将会复杂的多,你需要考虑滚动更新的过程中的参数控制(maxSurge、maxUnavailable)、每个应用的IP池预留造成的IP浪费等等问题。
因此,我想再加一个StatefulSet的使用场景:
StatefulSet中反复强调的“稳定的网络标识”,主要指Pods的hostname以及对应的DNS Records。
$(statefulset name)-$(ordinal), ordinal
从0 ~ N-1
(N为期望副本数)。 statefulset.kubernetes.io/pod-name
, 然后设置到Pod的pod name和hostname中。$(service name).$(namespace).svc.cluster.local
通过DNS RR解析到后端其中一个Pod。SRV Records只包含对应的Running and Ready的Pods,不Ready的Pods不会在对应的SRV Records中。$(hostname).$(service name).$(namespace).svc.cluster.local
解析到对应hostname的Pod。那么什么情况下会导致出现同一namespace下会出现多个相同network identity的StatefulSet Pods呢?我们考虑下Node出现网络Unreachable的情况:
Terminating
或者Unknown
,因此StatefulSet Controller并不会在其他Node上再recreate同identity的Pods。当你确定了这个Node上的StatefulSet Pods shutdown或者无法和该StatefulSet的其他Pods网络不同时,接下来就需要强制删除apiserver中这些unreachable pods object,然后StatefulSet Controller就能在其他Ready Nodes上recreate同identity的Pods,使得StatefulSet继续健康工作。那么在Kubernetes 1.5+中,如何强制从apiserver中删除该StatefulSet pods呢?有如下三种方法:
Terminating
或者Unkown
,所以kubelet从apiserver中获取到这个信息后就会自动删除这些Pods。kubectl delete pods <pod> --grace-period=0 --force
小知识:当前Node Condition有以下6种:
Node Condition | Description |
---|---|
OutOfDisk | True if there is insufficient free space on the node for adding new pods, otherwise False |
Ready | True if the node is healthy and ready to accept pods, False if the node is not healthy and is not accepting pods, and Unknown if the node controller has not heard from the node in the last 40 seconds |
MemoryPressure | True if pressure exists on the node memory – that is, if the node memory is low; otherwise False |
DiskPressure | True if pressure exists on the disk size – that is, if the disk capacity is low; otherwise False |
NetworkUnavailable | True if the network for the node is not correctly configured, otherwise False |
ConfigOK | True if the kubelet is correctly configured, otherwise False |
Kubernetes 1.7+,StatefulSet开始支持Pod Management Policy配置,提供以下两种配置:
StatefulSet的更新策略(由.spec.updateStrategy.type
指定)支持以下两种:
.spec.updateStrategy.rollingUpdate.partition
来指定一个index分界点。 思考:StatefulSet滚动更新时,如果某个Pod更新失败,会怎么办呢? 先卖个关子,下一篇对StatefulSet Controller源码分析时我们再来回答。