StatefulSet #
一、StatefulSet概述 #
StatefulSet用于管理有状态应用,提供稳定的网络标识和持久存储。
1.1 与Deployment对比 #
| 特性 | Deployment | StatefulSet |
|---|---|---|
| Pod标识 | 随机名称 | 固定序号名称 |
| 网络标识 | 随机分配 | 稳定DNS名称 |
| 存储 | 共享存储 | 独立PVC |
| 启动顺序 | 并行启动 | 有序启动 |
| 适用场景 | 无状态应用 | 有状态应用 |
1.2 StatefulSet特性 #
text
StatefulSet特性
│
├── 稳定的网络标识
│ ├── 固定Pod名称
│ └── 稳定DNS名称
│
├── 稳定的持久存储
│ ├── 每个Pod独立PVC
│ └── Pod重建后数据保留
│
├── 有序部署和扩展
│ ├── 顺序启动
│ └── 顺序停止
│
└── 有序滚动更新
└── 按序更新Pod
二、创建StatefulSet #
2.1 基本示例 #
yaml
# nginx-statefulset.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-headless
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-sts
spec:
serviceName: nginx-headless
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
name: web
2.2 创建和查看 #
bash
# 创建StatefulSet
kubectl apply -f nginx-statefulset.yaml
# 查看StatefulSet
kubectl get sts
# 输出示例
NAME READY AGE
nginx-sts 3/3 1m
# 查看Pod(注意名称格式)
kubectl get pods -l app=nginx
# 输出示例
NAME READY STATUS RESTARTS AGE
nginx-sts-0 1/1 Running 0 1m
nginx-sts-1 1/1 Running 0 50s
nginx-sts-2 1/1 Running 0 40s
2.3 Headless Service #
yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-headless
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
text
DNS解析格式
│
├── Pod DNS
│ └── <pod-name>.<service-name>.<namespace>.svc.cluster.local
│
└── 示例
└── nginx-sts-0.nginx-headless.default.svc.cluster.local
三、持久存储 #
3.1 volumeClaimTemplates #
yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web-sts
spec:
serviceName: web-headless
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.25
ports:
- containerPort: 80
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "standard"
resources:
requests:
storage: 1Gi
3.2 PVC命名规则 #
text
PVC命名格式
│
└── <pvc-name>-<statefulset-name>-<ordinal>
示例
│
├── www-web-sts-0
├── www-web-sts-1
└── www-web-sts-2
3.3 查看PVC #
bash
# 查看PVC
kubectl get pvc
# 输出示例
NAME STATUS VOLUME CAPACITY AGE
www-web-sts-0 Bound pvc-xxx 1Gi 1m
www-web-sts-1 Bound pvc-yyy 1Gi 50s
www-web-sts-2 Bound pvc-zzz 1Gi 40s
四、部署和扩展 #
4.1 有序部署 #
text
部署顺序
│
├── 1. nginx-sts-0 启动
│ └── 等待Running和Ready
│
├── 2. nginx-sts-1 启动
│ └── 等待Running和Ready
│
└── 3. nginx-sts-2 启动
└── 等待Running和Ready
4.2 扩容 #
bash
# 扩容到5个副本
kubectl scale sts nginx-sts --replicas=5
# 查看扩容过程
kubectl get pods -l app=nginx -w
# 输出示例
nginx-sts-0 1/1 Running 0 2m
nginx-sts-1 1/1 Running 0 1m
nginx-sts-2 1/1 Running 0 50s
nginx-sts-3 0/1 Pending 0 0s
nginx-sts-3 1/1 Running 0 5s
nginx-sts-4 0/1 Pending 0 0s
nginx-sts-4 1/1 Running 0 5s
4.3 缩容 #
bash
# 缩容到2个副本
kubectl scale sts nginx-sts --replicas=2
# 缩容顺序:从高序号开始删除
# nginx-sts-4 → nginx-sts-3 → nginx-sts-2
五、更新策略 #
5.1 RollingUpdate策略 #
yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web-sts
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 0
template:
spec:
containers:
- name: web
image: nginx:1.26
5.2 分区更新 #
yaml
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 2
text
分区更新(partition=2)
│
├── nginx-sts-0 ─── 不更新
│
├── nginx-sts-1 ─── 不更新
│
├── nginx-sts-2 ─── 更新
│
├── nginx-sts-3 ─── 更新
│
└── nginx-sts-4 ─── 更新
5.3 OnDelete策略 #
yaml
updateStrategy:
type: OnDelete
text
OnDelete策略
│
├── 更新Pod模板后
│
└── 手动删除Pod才会更新
六、完整配置示例 #
6.1 数据库StatefulSet #
yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-headless
spec:
ports:
- port: 3306
name: mysql
clusterIP: None
selector:
app: mysql
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql-headless
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
initContainers:
- name: init-mysql
image: mysql:8.0
command:
- bash
- "-c"
- |
set -ex
[[ $(hostname) =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
echo [mysqld] > /mnt/conf.d/server-id.cnf
echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
volumeMounts:
- name: conf
mountPath: /mnt/conf.d
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: data
mountPath: /var/lib/mysql
- name: conf
mountPath: /etc/mysql/conf.d
livenessProbe:
exec:
command: ["mysqladmin", "ping"]
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
initialDelaySeconds: 5
periodSeconds: 2
volumes:
- name: conf
emptyDir: {}
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: standard
resources:
requests:
storage: 10Gi
七、Pod管理 #
7.1 Pod标识 #
bash
# Pod名称
nginx-sts-0
nginx-sts-1
nginx-sts-2
# Pod DNS
nginx-sts-0.mysql-headless.default.svc.cluster.local
nginx-sts-1.mysql-headless.default.svc.cluster.local
nginx-sts-2.mysql-headless.default.svc.cluster.local
7.2 Pod重建 #
bash
# 删除Pod
kubectl delete pod nginx-sts-0
# StatefulSet会重建同名Pod
kubectl get pod nginx-sts-0
# 新Pod具有相同的:
# - 名称
# - 网络标识
# - 持久存储
7.3 Pod恢复顺序 #
text
Pod恢复
│
├── 1. 识别缺失的Pod
│
├── 2. 按序号顺序重建
│
└── 3. 等待Running和Ready
八、故障排查 #
8.1 常见问题 #
bash
# 查看StatefulSet状态
kubectl describe sts nginx-sts
# 查看Pod状态
kubectl get pods -l app=nginx
# 查看PVC状态
kubectl get pvc
# 查看事件
kubectl get events --field-selector involvedObject.name=nginx-sts
8.2 问题诊断 #
| 问题 | 原因 | 解决方案 |
|---|---|---|
| Pod卡在Pending | PVC未绑定 | 检查StorageClass |
| Pod启动失败 | 初始化失败 | 检查initContainer |
| 更新卡住 | Pod不健康 | 检查健康检查 |
九、最佳实践 #
9.1 Headless Service #
yaml
apiVersion: v1
kind: Service
metadata:
name: app-headless
spec:
clusterIP: None
selector:
app: app
ports:
- port: 8080
9.2 资源配置 #
yaml
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 1
memory: 1Gi
9.3 健康检查 #
yaml
livenessProbe:
exec:
command: ["pg_isready"]
initialDelaySeconds: 30
readinessProbe:
exec:
command: ["pg_isready"]
initialDelaySeconds: 5
十、总结 #
10.1 核心要点 #
| 要点 | 说明 |
|---|---|
| 稳定标识 | 固定Pod名称和DNS |
| 持久存储 | 每个Pod独立PVC |
| 有序部署 | 按序号启动和停止 |
| 更新策略 | RollingUpdate/OnDelete |
10.2 下一步 #
掌握了StatefulSet后,让我们学习 DaemonSet,了解如何在每个节点运行Pod。
最后更新:2026-03-28