【kubernetes】--Controller(StatefulSet)
文章目录
- 有状态无状态
- (1)无状态--deployment
- (2)有状态--statefulset
- Kubernetes StatefulSet 控制器详解
- 1. StatefulSet 的核心特性
- (1) 稳定的 Pod 标识
- (2) 有序部署与扩展
- (3) 持久化存储
- (4) 稳定的网络标识
- 2. StatefulSet 的典型应用场景
- 3. StatefulSet 的工作流程
- 4. StatefulSet 的关键操作
- (1) 扩容与缩容
- (2) 更新策略
- (3) 删除 StatefulSet
- 5. StatefulSet 的注意事项
- 6.案列
- 7. 对比 StatefulSet 与 Deployment
有状态无状态
(1)无状态–deployment
- 认为pod都是一样的
- 没有顺序要求
- 不用考虑在哪个pod上运行
- 随意扩展和伸缩
(2)有状态–statefulset
- 上面因素都要考虑到
- 每个pod是独立的,保持pod的启动顺序和唯一性
- 唯一网络标识符,持久存储
- 有序(比如mysql主从)
Kubernetes StatefulSet 控制器详解
StatefulSet 是 Kubernetes 中用于管理 有状态应用(Stateful Applications) 的核心控制器,它确保 Pod 拥有稳定的标识、有序部署/扩展、持久化存储和稳定的网络身份。与 Deployment(适用于无状态应用)不同,StatefulSet 为每个 Pod 提供唯一的标识,并保证其生命周期中的可预测性。
StatefulSet 是 Kubernetes 管理有状态应用的核心控制器,通过 唯一标识、有序性、持久化存储和稳定网络 满足数据库、消息队列等场景的需求。正确使用时需注意存储配置、更新策略和备份方案。
1. StatefulSet 的核心特性
(1) 稳定的 Pod 标识
- 每个 Pod 的名称是 唯一且有序 的,格式为
<statefulset-name>-<ordinal-index>
(如mysql-0
、mysql-1
)。 - Pod 重启后名称不变,且会绑定到相同的持久化存储。
在这里插入图片描述
每个pod名称都是唯一的
(2) 有序部署与扩展
- 顺序性:Pod 按索引顺序创建(从
0
到N-1
)、删除(从N-1
到0
)。- 例如,扩容时先创建
mysql-1
,再创建mysql-2
;缩容时先删除mysql-2
,再删除mysql-1
。
- 例如,扩容时先创建
- 适用场景:主从架构的数据库(如 MySQL 主库需先于从库启动)。
(3) 持久化存储
- 通过 PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 为每个 Pod 提供独立的存储。
- 删除 Pod 后,关联的 PVC 和 PV 不会被删除,数据得以保留。
- 重新调度时,Pod 会绑定到原来的 PVC。
(4) 稳定的网络标识
- 每个 Pod 拥有稳定的 DNS 名称:
- Pod 专属域名:
<pod-name>.<headless-service-name>.<namespace>.svc.cluster.local
。 - 例如:
mysql-0.mysql.default.svc.cluster.local
。
- Pod 专属域名:
- 通过 Headless Service(无头服务)暴露 Pod,直接解析到 Pod IP。
2. StatefulSet 的典型应用场景
- 数据库集群:MySQL、PostgreSQL、MongoDB 等。
- 分布式存储系统:Etcd、ZooKeeper、Redis Cluster。
- 消息队列:Kafka、RabbitMQ(需持久化存储和固定节点标识)。
3. StatefulSet 的工作流程
-
创建 Headless Service
定义一个无 ClusterIP 的 Service,用于 Pod 的网络标识。apiVersion: v1 kind: Service metadata:name: mysql spec:clusterIP: None # Headless Serviceselector:app: mysqlports:- port: 3306
-
定义 StatefulSet
指定副本数、存储模板(volumeClaimTemplates
)和 Pod 模板。apiVersion: apps/v1 kind: StatefulSet metadata:name: mysql spec:serviceName: mysql # 关联 Headless Servicereplicas: 3selector:matchLabels:app: mysqltemplate:metadata:labels:app: mysqlspec:containers:- name: mysqlimage: mysql:5.7volumeMounts:- name: datamountPath: /var/lib/mysqlvolumeClaimTemplates: # 每个 Pod 独立的 PVC- metadata:name: dataspec:accessModes: [ "ReadWriteOnce" ]resources:requests:storage: 10Gi
-
Pod 与存储的绑定
- StatefulSet 会自动为每个 Pod 创建 PVC,名称格式为
<volumeClaimTemplate-name>-<pod-name>
(如data-mysql-0
)。 - Pod 重启或重新调度时,会绑定到相同的 PVC。
- StatefulSet 会自动为每个 Pod 创建 PVC,名称格式为
4. StatefulSet 的关键操作
(1) 扩容与缩容
- 扩容:增加
replicas
字段,新 Pod 按顺序创建。kubectl scale statefulset mysql --replicas=5
- 缩容:减少
replicas
,Pod 按逆序终止。kubectl scale statefulset mysql --replicas=2
(2) 更新策略
- 滚动更新(RollingUpdate):默认策略,按顺序更新 Pod(从高序号到低序号)。
spec:updateStrategy:type: RollingUpdate
- 删除重建(OnDelete):手动删除 Pod 后触发更新。
spec:updateStrategy:type: OnDelete
(3) 删除 StatefulSet
- 默认会删除 Pod 但保留 PVC(需手动清理 PVC):
kubectl delete statefulset mysql kubectl delete pvc -l app=mysql # 清理关联的 PVC
5. StatefulSet 的注意事项
- 存储依赖:必须提前配置 StorageClass 或手动创建 PV。
- 网络依赖:需搭配 Headless Service 实现稳定的 DNS。
- 性能开销:有序性可能导致部署/扩展速度较慢。
- 数据备份:需额外工具(如 Velero)备份 PVC 数据。
6.案列
apiVersion: v1
kind: Service
metadata:name: nginxlabels:app: nginx
spec:ports:- port: 80name: webclusterIP: Noneselector:app: nginx---apiVersion: apps/v1
kind: StatefulSet
metadata:name: nginx-statefulsetnamespace: default
spec:serviceName: nginxreplicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.27.5ports:- containerPort: 80
7. 对比 StatefulSet 与 Deployment
特性 | StatefulSet | Deployment |
---|---|---|
Pod 名称 | 唯一有序(如 web-0 ) | 随机哈希(如 web-5x6d7 ) |
存储 | 每个 Pod 独立 PVC | 共享或无持久化存储 |
网络标识 | 稳定的 DNS | 通过 Service 负载均衡 |
部署顺序 | 顺序创建/删除 | 并行创建 |
适用场景 | 数据库、有状态服务 | 无状态应用(如 Web) |