有状态应用 StatefulSet
理解 StatefulSet 的特点与适用场景
掌握有状态应用的部署与网络标识
对比 Deployment 和 StatefulSet 的区别
核心讲解
Deployment 适合无状态,StatefulSet 适合有状态应用,比如数据库、中间件。
(1)核心特点
固定的 Pod 名称、有序编号,从 0 开始
固定的 DNS 域名,每个 Pod 有稳定的网络标识
有序部署、有序伸缩、有序更新
每个 Pod 对应自己的存储,删除重建数据还在
启动按顺序来,0 号先启动,然后依次
(2)无头服务 Headless Service
StatefulSet 必须配无头服务,ClusterIP=None,不负载均衡,每个 Pod 有独立的 DNS 记录。
Pod 域名:
Pod名.服务名.命名空间.svc.cluster.local
(3)适用场景
数据库:MySQL、PostgreSQL、Redis 主从
消息队列:Kafka、RocketMQ
其他有状态、需要固定标识的应用
操作示例
# statefulset-demo.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "web-headless"
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: web-headless
spec:
clusterIP: None
selector:
app: web
ports:
- port: 80
# 创建
kubectl apply -f statefulset-demo.yaml
# 查看,名称是 web-0、web-1、web-2 有序
kubectl get pods
# 查看无头服务
kubectl get svc web-headless
# 测试域名解析
kubectl run test --image=busybox --rm -it -- nslookup web-0.web-headless.default.svc.cluster.local
# 每个 Pod 有自己独立的 PVC
kubectl get pvc
常见误区
StatefulSet 和 Deployment 一样:有本质区别,StatefulSet 有序、有固定标识、独立存储
有状态应用随便扩副本:有状态应用扩副本要考虑数据同步,不是越多越好
无头服务没用:StatefulSet 必须配无头服务,不然没有稳定域名
数据库一定要用 StatefulSet:生产环境数据库一般用运营商或者云服务,手动部署 StatefulSet 运维成本很高
课后练习
创建一个 3 副本的 StatefulSet
配置无头服务,验证每个 Pod 的域名解析
验证每个 Pod 有独立的 PVC
对比 Deployment 和 StatefulSet 的核心区别
