2.7 K8s控制器资源对象之 Stateful Set
简称:sts
控制有状态的Pod的控制器
StatefulSet一般用于管理具有以下特性的应用:
- 要求有稳定且唯一的网络标识符,即Pod重新调度后,其PodName和HostName不变(Pod的IP会改变),基于Headless Service来实现。Pod名称一次是
stsNAME-0、stsNAME-1、stsNAME-2... - 要求有稳定且持久的存储,即Pod重新调度后,还是能访问到相同的持久化数据。基于pvc来实现。
- 要求有序、平滑的部署和扩展,即当spec.podManagementPolicy=OrderedReady时,Pod是有顺序的,在部署或扩展的时候要依据定义的顺序依次进行(即从0到N-1,在下一个Pod运行之前,所有之前的Pod必须是Running或Ready状态)。其他可选值:Parallel
- 要求有序、平滑的终止和删除,即从N-1到0依次删除
- 要求有序的滚动更新:比如MySQL主从要先更新从,再更新主
StatefulSet一般有三个组件:
headless service
- StatefulSet中的每个Pod的名称是固定的,而且是可以被解析的。headless service为Pod分配一个DNS域名作为识别Pod的唯一标识符,podName命名格式为
stsNAME-0|1|2...。该名称的FQDN格式为podName.headlessServiceName[.nsName.svc.cluster.local]。例如myapp-0.myapp-svc.default.svc.cluster.local,可以简写为podName.serviceName - StatefulSet使用Headless服务来控制Pod的域名,这个域名的FQDN格式为
serviceName.nsName.svc.cluster.local
- StatefulSet中的每个Pod的名称是固定的,而且是可以被解析的。headless service为Pod分配一个DNS域名作为识别Pod的唯一标识符,podName命名格式为
volumeClaimTemplate
- StatefulSet中的每一个Pod都有自己的存储卷,它们不能共用一个存储卷 。VolumeClaimTemplate(卷声明模板)会为每一个Pod自动创建1个专有的volume。实现方式是:它根据声明的资源大小等信息为每一个Pod来先创建pvc并绑定pv,最后将pvc创建为volume。每个PVC的名称格式为
VolumeClaimTemplateNAME-PodNAME,而且该名称是可以被dns解析。在下面的例子中,VolumeClaimTemplate会为每个Pod自动创建一个Volume(大小为2Gb)。 - 因为Pod的名字是固定且唯一的,而且pvc的名字隐含了pod名字,实现volume与pod的关联映射。所以当Pod被调度到其他node节点上时,依然会根据pod名字选择相对应的volume,这就实现了数据与pod绑定。注意,当Pod或者StatefulSet被删除时,对应的PVC不会被删除,这个删除操作必须手动来执行(手动删除pvc后,pv会随之删除)。
- StatefulSet中的每一个Pod都有自己的存储卷,它们不能共用一个存储卷 。VolumeClaimTemplate(卷声明模板)会为每一个Pod自动创建1个专有的volume。实现方式是:它根据声明的资源大小等信息为每一个Pod来先创建pvc并绑定pv,最后将pvc创建为volume。每个PVC的名称格式为
StatefulSet控制器
StatefulSet由headless Service和volumeClaimTemplates组成。Service中的多个Pod将会被分别编号(为pod分配持久性DNS名称),并挂载volumeClaimTemplates中声明的pvc卷。注意svc必须在sts之前创建。Pod启动时会按照顺序启动、更新、逆序关闭。
sts中的volumeClaimTemplates在地位上相当于deployment中的pvc,实现了sc和pv的绑定。所以sts中无需使用pvc来进行sc和pv的绑定。
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
labels:
app: myapp-svc
spec:
ports:
- name: web
port: 80
clusterIP: None #设置为None,表示启用headless Service
selector:
app: myapp-pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: myapp #会将pod的2个副本按顺序命名为myapp-0,myapp-1,并按照顺序启动、逆序关闭。
spec:
serviceName: myapp-svc #指定headless Service
replicas: 2
selector:
matchLabels:
app: myapp-pod
updateStrategy: #更新策略
type: RollingUpdate
rollingUpdate:
partition: 0
template:
metadata:
labels:
app: myapp-pod
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v5
ports:
- containerPort: 80
name: web
volumeMounts:
- name: myappdata #volumeClaimTemplates的名字
mountPath: /usr/share/nginx/html
volumeClaimTemplates: #该模板作用:为每一个pod自动创建pvc、然后创建pvc类型的volume
- metadata:
name: myappdata #为每个pod分配一个pvc,pvc名称为:volumeClaimTemplatesname-podname
spec:
accessModes:
- "ReadWriteOnce"
storageClassName: "nfs-sc-retain" #指定StorageClass实现自动创建pv,如果不指定,需要事先创建pv
resources:
requests:
storage: 2Gi
支持扩缩容、动态更新、更新策略(分区更新:只允许pod的index≥N的进行更新)。