目录
- 一、核心特性
- 二、工作原理
- 三、应用场景
- 四、YAML配置示例
StatefulSet是Kubernetes中用于管理有状态应用的一种控制器,它为Pod提供了稳定的、有序的、唯一的标识,确保在集群中正确地部署、扩展和更新有状态服务。
一、核心特性
-
稳定、唯一的网络标识:每个StatefulSet中的Pod都会被赋予一个基于StatefulSet名称和序号的稳定网络标识,包括:
- 固定域名:每个Pod具有一个固定的DNS子域名,格式为
<pod-name>.<statefulset-name>.<namespace>.svc.cluster.local
,便于服务间通过固定域名进行互相访问。 - 持久化IP:如果底层网络支持(如使用Headless Service配合
ClusterIP=None
),Pod可以获得一个稳定的IP地址,即使Pod被重新调度,IP地址也不会改变。
- 固定域名:每个Pod具有一个固定的DNS子域名,格式为
-
有序部署与扩展:StatefulSet中的Pod按照定义的序号(从0开始递增)逐个创建和销毁,确保Pod间的依赖关系得到妥善处理。例如,在有主从关系的服务中,主节点总是在从节点之前启动和终止。
-
有序更新:在滚动更新过程中,StatefulSet按照Pod的序号顺序逐一更新,确保旧版本Pod在新版本Pod准备好接收流量后再被替换,从而实现平滑过渡。
-
持久卷(Persistent Volume,PV)自动绑定:StatefulSet可以通过VolumeClaimTemplate为每个Pod自动请求、绑定和管理持久卷,确保每个Pod的数据持久化且独立,即使Pod被重新调度,数据也不会丢失。
二、工作原理
-
Pod创建与销毁:StatefulSet控制器根据
.spec.replicas
定义的数量,按照序号依次创建Pod。当需要缩容时,同样按照序号递减的顺序销毁Pod,确保依赖于Pod序号的服务不会因为Pod被随机删除而中断。 -
Pod更新:当StatefulSet的
.spec.template
发生变更时,会触发滚动更新。控制器按照序号顺序,先更新序号最大的Pod(即最后一个Pod),待其变为Ready状态后,再更新下一个Pod,直至所有Pod更新完毕。 -
PV管理:StatefulSet通过VolumeClaimTemplate为每个Pod生成一个PersistentVolumeClaim(PVC)。Kubernetes的Volume插件会自动为这些PVC绑定可用的PV。由于PVC名称包含Pod的序号,因此每个Pod的PV都是独立且持久的。
三、应用场景
StatefulSet适用于需要保持稳定网络标识、有序部署、有序更新及持久存储的有状态服务,如:
- 分布式数据库:如Cassandra、MongoDB、MySQL等,需要保证节点间的数据一致性,以及节点重启后的数据恢复和正确加入集群。
- 消息队列:如RabbitMQ、Kafka等,需要维护节点间的顺序和唯一性,以及持久化的消息存储。
- 缓存服务:如Redis、Memcached等,可能需要持久化数据或维持主从关系。
- 集群化应用:如Zookeeper、etcd等,需要严格的节点启动顺序和数据持久化。
四、YAML配置示例
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-statefulset
spec:
replicas: 3
serviceName: my-service
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: my-image:latest
ports:
- containerPort: 80
volumeClaimTemplates:
- metadata:
name: data-volume
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
在这个示例中:
- 创建了一个名为
my-statefulset
的StatefulSet,期望副本数为3。 - 定义了一个名为
my-service
的Headless Service,为StatefulSet中的Pod提供稳定的DNS解析。 - 通过
selector
和Pod模板的labels
确保StatefulSet管理的Pod被正确选择。 - 容器使用
my-image:latest
镜像,并监听80端口。 volumeClaimTemplates
定义了每个Pod需要的持久卷,请求1Gi的存储空间,访问模式为ReadWriteOnce
。