StatefulSet-有状态pod副本集管理
StatefulSet用于管理有状态的Pod副本集,与deployment管理的无状态pod区别在于: 有状态意味着每个pod副本都具有唯一不变的身份标识,例如:id或者服务名称,多个Pod副本不是对等无差别的,而是相互之间可能需要通信来实现某种功能,每个Pod需要独立的持久化存储(保存日志或者数据等),以及多个pod可能需要按照固定的顺序逐个启动等业务需求
StatefulSet会为有状态pod副本集提供一下功能:
- 每个pod具有唯一且不变的身份标识,包括ID和网络访问地址
- 每个pod都配置稳定的持久化存储
- 对多个Pod提供有序的,优雅的部署和扩缩容等管理功能
- 对多个Pod提供有序的,优雅的滚动更新等管理功能
使用StatefulSet也存在以下一些限制
- 为每个Pod配置的持久化存储必须是PVC类型的共享存储
- 删除pod不会删除后端关联的存储,需要手动删除存储数据
- 必须创建一个Headless Service(无头服务),用于创建每个Pod的网络访问地址
- 删除StatefulSet资源时,不保证pod会终止,如要优雅删除,可将Pod副本缩容为0然后删除
- 使用OrderedReady策略执行滚动更新时,可能存在某个pod损坏,不能Ready状态,需要手动修复
1、下面例子为一个完整的有状态pod副本集,如下:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: busybox-stateful
spec:
selector:
matchLabels:
app: busybox
replicas: 2
serviceName: "busybox-service"
minReadySeconds: 10
template:
metadata:
labels:
app: busybox
spec:
terminationGracePeriodSeconds: 10
containers:
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command: [ "sh","-c","sleep 3600" ]
ports:
- containerPort: 80
volumeMounts:
- name: busybox-volume
mountPath: /usr/share/busybox
subPath: busybox
volumeClaimTemplates:
- metadata:
name: busybox-volume
spec:
storageClassName: "nfs-storage"
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 2Gi
---
apiVersion: v1
kind: Service
metadata:
name: busybox-service
labels:
app: busybox
spec:
selector:
app: busybox
clusterIP: None
ports:
- port: 80
- serviceName:指向一个无头服务,就是最下面创建的Service
- minReadySeconds:pod最短就绪时间,达到这个时间后才会设置pod为Ready状态,默认为0
- terminationGracePeriodSeconds 是容器优雅终止的宽限期,定义 Pod 被删除时 Kubernetes 等待容器正常退出的最长时间,默认值为30s,时间到了后容器会被强制删除
- volumeClaimTemplates:后端存储的PVC模板
- clusterIP: None 定义为一个无头服务
创建完成后可以看到pod的命名规则为:由statefulset名称和序号组成,中间用”-“连接,默认序号从0开始,这个完整的pod名字也将作为pod内容器的主机名,如图:


从1.26版本开始,引入了新字段spec.ordinals.start,可用于自定义pod的起始起始序号,比如设置为5,那么创建pod后将会变成busybox-stateful-5开始,如图:

2、StatefulSet会将Headless Service名称和Pod名称组合为pod的访问地址,以DNS域名格式表示,完整的域名格式为:<pod-name>.<service-name>.<namespace.svc>.<clusterDomain>,可通过nslookup工具验证,如图:

在同个K8s集群中,其他的Pod都可以通过此域名来访问StatefulSet中的pod,并且系统会保证此域名是一直不变,即使pod被重建,pod名称,服务域名都不会变,只有Pod的IP地址会变
3、StatefulSet删除机制
StatefulSet支持级联方式删除全部Pod和非级联方式保留Pod,默认是级联模式,通过kubectl delete命令的时候,指定参数–cascade=orphan=true 来禁止使用级联模式
4、StatefulSet扩缩容
kubectl scale statefulset statefulset-name --replicas=5 #可执行此命令实现副本增加减少
5、更新策略
- RollingUpdate:滚动更新,默认
- OnDelete:需要手动删除全部pod,触发statefulset controller来重新创建pod


