本文内容均来自个人笔记并重新梳理,如有错误欢迎指正!
如果对您有帮助,烦请点赞、关注、转发、订阅专栏!
专栏订阅入口
Linux 专栏 | Docker 专栏 | Kubernetes 专栏
往期精彩文章
【Docker】(全网首发)Kylin V10 下 MySQL 容器内存占用异常的解决方法
目录
一、基本介绍
在 Kubernetes 中,StatefulSet 是一种高级 API 对象,用于声明式地管理有状态应用的生命周期,确保指定数量的 Pod 副本始终运行且是最新的,并通过确保 Pod 的有序性、持久性和唯一性来实现对有状态应用的支持。
说明:有状态应用(Stateful Application)是指应用程序在处理客户请求时会存储客户端的状态信息。这意味着应用程序会记住之前的交互或状态,并在处理后续请求时使用这些信息。与无状态应用不同,有状态应用会跟踪每个客户端的会话状态,并将其存储在服务器端。这使得应用程序能够为每个客户端提供个性化的体验,并记住客户端在之前的操作中所做的选择。
与 Deployment 相同,StatefulSet 可以管理基于相同规范的 Pod。
与 Deployment 不同,StatefulSet 虽然每个 Pod 是根据相同规范创建的,但不可互换,且每个 Pod 都有一个持久标识符。
二、工作原理
StatefulSet 控制器的工作原理主要体现在以下几个方面:
- Pod 的有序性:StatefulSet 控制器会为每个 Pod 分配一个唯一的序号,并确保 Pod 的启动和终止顺序与序号一致。这对于有状态应用至关重要,因为它们通常需要按照特定的顺序处理数据
- Pod 的持久性:StatefulSet 控制器会为每个 Pod 提供持久化存储卷,并确保 Pod 即使重启或迁移到其他节点也能访问相同的存储卷。这对于有状态应用至关重要,因为它们需要保存数据以供后续使用
- Pod 的唯一性:StatefulSet 控制器会确保每个 Pod 的名称都是唯一的,即使 Pod 被删除并重新创建也是如此。这对于有状态应用至关重要,因为它们通常需要使用唯一的名称来标识 Pod
StatefulSet 控制器的工作流程大致可以分为以下几个步骤:
- 创建 Pod:当用户创建一个 StatefulSet 资源对象时,StatefulSet 控制器会根据 StatefulSet 的预期状态创建相应的 Pod
- 启动 Pod:StatefulSet 控制器会按照 Pod 的序号顺序启动 Pod
- 监控 Pod:StatefulSet 控制器会持续监控 Pod 的状态,确保副本数量与预期状态一致
- 滚动更新:StatefulSet 控制器支持滚动更新策略,可以逐步更新 StatefulSet 中的 Pod 版本,而不会导致应用程序服务中断
- 版本回滚:如果 StatefulSet 更新出现问题,StatefulSet 控制器可以回滚到之前的版本
- 清理旧资源:StatefulSet 控制器会清理不再需要的旧 Pod 和存储卷资源
三、相关特性
1、网络标识符
StatefulSet 控制器为每个 Pod 提供一个稳定、唯一的网络标识符,即 Pod 名称和稳定的网络域名。这使得有状态应用在整个生命周期中都能够保持相同的标识,方便应用内部的通信和数据交换。
2、持久化存储
StatefulSet 控制器为每个 Pod 提供一个稳定的持久化存储卷,并确保 Pod 即使重启或迁移到其他节点也能访问相同的存储卷。
3、有序启停
StatefulSet 控制器会按照 Pod 的序号顺序启动 Pod,并确保 Pod 的终止顺序与序号一致。
4、滚动更新
StatefulSet 控制器支持滚动更新策略,可以逐步更新 StatefulSet 中的 Pod 版本,而不会导致应用程序服务中断。
5、自动修复和回滚
Pod 出现故障时,StatefulSet 控制器会自动创建新的 Pod 来替换它,确保应用程序始终处于运行状态。如果更新出现问题,StatefulSet 控制器可以回滚到之前的版本,可以避免数据损坏或丢失。
6、 无头服务
StatefulSet 控制器可以通过无头服务(Headless Service,其 clusterIP 字段值为 None)实现 Pod 之间直接通信,而无需使用外部负载均衡器。
# 无头服务示例
apiVersion: v1
kind: Service
metadata:
name: demo-servic
labels:
app: demo-servic
spec:
selector:
app: nginx
clusterIP: None # 🔔 值为 None
ports:
- name: web
port: 80
四、资源清单(示例)
# statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: demo-statefulset
spec:
replicas: 3
selector:
matchLabels:
app: demo-statefulset
template:
metadata:
labels:
app: demo-statefulset
spec:
containers:
- name: demo-container
image: demo-image:latest
ports:
- containerPort: 80
volumeMounts:
- name: data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: data
labels:
app: demo-statefulset
spec:
storageClassName: demo-storageclass
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
上述 statefulset.yaml 文件定义了一个名为 demo-statefulset 的 StatefulSet 对象,该对象包括 3 个 Pod 副本(Pod 名称分别为 demo-statefulset-0,demo-statefulset-1,demo-statefulset-2),每个 Pod 包含一个名为 demo-container 的业务容器,业务容器使用 demo-image:latest 镜像,并指定监听端口为 80。每个 Pod 挂载一个独立的 PVC 对象实现数据的持久化存储(PVC 名称分别为 data-demo-statefulset-0,data-demo-statefulset-1,data-demo-statefulset-2)。
说明:可以通过以下命令查看 StatefulSet 资源清单支持定义的内容
kubectl explain statefulset --recursive
五、常用操作
1、创建 StatefulSet
kubectl create -f statefulset.yaml
或
kubectl apply -f statefulset.yaml
2、更新 StatefulSet
# 方式一:更新 statefulset.yaml 内容后执行
kubectl apply -f statefulset.yaml
# 方式二:更新镜像
kubectl set image statefulset demo-statefulset app=demo-image:v1
# 方式三:更新环境变量
kubectl set env statefulset demo-statefulset keyname=keyvalue
3、回滚 StatefulSet
# 默认回滚至上一版本
kubectl rollout undo statefulset demo-statefulset
# 回滚至指定版本
kubectl rollout undo statefulset demo-statefulset --to-revision=3
# 查看可回滚版本
kubectl rollout history statefulset demo-statefulset
4、查看 StatefulSet
# 查看实例列表
kubetcl get statefulset
# 查看详细信息
kubectl describe statefulset demo-statefulset
5、删除 StatefulSet
# 方式一:命令行
kubectl delete statefulset demo-statefulset
# 方式二:资源清单
kubectl delete -f statefulset.yaml
6、副本伸缩
kubectl scale statefulset demo-statefulset --replicas=1