Kubernetes 的 StatefulSet 是一种工作负载 API 对象,专门用于管理有状态应用的部署和扩展。与 Deployment 不同,StatefulSet 能保证 Pod 的有序部署、稳定且唯一的网络标识和持久化存储,这些特性对数据库、消息队列等有状态服务至关重要。
StatefulSet 的核心特性
StatefulSet 为每个 Pod 提供以下关键保障:
稳定的网络标识:Pod 名称格式为 $(statefulset-name)-$(ordinal),例如 mysql-0、mysql-1。即使 Pod 被重建,名称也不会改变,并通过 DNS 始终解析到正确的网络地址。 稳定的持久化存储:每个 Pod 挂载独立的 PersistentVolume(PV),即使 Pod 被删除或重新调度,其数据仍能通过 PVC 绑定原 PV 保留。 有序部署与扩缩容:Pod 按序创建(0, 1, 2...)和删除(从高编号开始),支持串行启动和优雅终止,适合主从复制或集群初始化场景。适用于哪些有状态服务
StatefulSet 特别适合需要身份识别和数据持久性的服务:
数据库集群:如 MySQL 主从、PostgreSQL 流复制、MongoDB 副本集。每个实例需固定身份和独立数据盘。 分布式存储系统:如 etcd、Ceph、ZooKeeper,节点间依赖稳定网络和成员发现机制。 消息中间件:如 Kafka,Broker 需要唯一 ID 和持久日志存储。如何使用 StatefulSet 部署有状态服务
以部署一个简单的 Nginx 服务为例,展示基本结构:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
同时需要定义一个 Headless Service(无集群 IP)来管理网络标识:
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
clusterIP: None
selector:
app: nginx
ports:
- port: 80
targetPort: 80
这样每个 Pod 可通过 DNS 地址访问:web-0.nginx.default.svc.cluster.local 等。
实际运维中的注意事项
存储类配置:确保 StorageClass 支持动态供给,避免手动创建 PV 的负担。 更新策略:默认滚动更新按逆序替换 Pod,可通过 podManagementPolicy 和 updateStrategy 控制行为。 健康检查:合理设置 readinessProbe 和 livenessProbe,防止误删正在同步数据的实例。 备份与恢复:定期对 PVC 中的数据做快照或远程备份,避免单点故障。基本上就这些。StatefulSet 让 Kubernetes 能可靠运行有状态服务,关键是理解其稳定标识和存储绑定机制,并结合具体应用设计好网络、存储和初始化流程。
