StatefulSet 是 Kubernetes 专门设计用于管理 有状态应用 的控制器。它在处理 网络标识、持久存储、Pod 启动顺序 等方面有独特的优势,非常适合管理数据库、分布式存储等需要持久性和有序性的应用。
StatefulSet基本的工作流程如下
以下将从 工作原理、核心配置、更新策略、应用场景、注意事项 等多个方面进行详细分析。
1. StatefulSet 工作原理
StatefulSet 的设计目标是提供有状态应用的核心特性:
唯一性:确保每个 Pod 在集群中都有唯一标识。
持久性:即使 Pod 被删除或重建,存储数据依然保留。
有序性:控制 Pod 的创建、更新、删除顺序。
1.1 组件关系
StatefulSet 通常与以下组件协同工作:
组件 | 描述 |
---|---|
StatefulSet | 定义和管理有状态应用,负责控制 Pod 和卷的生命周期。 |
Pod | 由 StatefulSet 创建,具有唯一标识(如 web-0, web-1) |
Headless Service | 提供稳定的网络标识,用于为每个 Pod 提供独立的 DNS 名称。 |
PersistentVolumeClaim (PVC) | 每个 Pod 绑定一个独立的 PVC,用于存储持久化数据。 |
1.2 有序操作
StatefulSet 在以下场景下保证 Pod 操作的有序性:
创建顺序:按序号(ordinal)依次创建 Pod(从 web-0 到 web-N)。
更新顺序:从高序号到低序号逐步更新 Pod。
删除顺序:从高序号 Pod 开始删除。
恢复顺序:当某个 Pod 失败时,先恢复低序号 Pod。
2. StatefulSet 配置详解
下面举例一个简单例子,这里用的是Nginx
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "web" # 引用 Headless Service
replicas: 3 # 创建 3 个副本
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumeClaimTemplates: # PVC需要提前配置好
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
定义一个无头服务:
apiVersion: v1
kind: Service
metadata:
name: web
spec:
clusterIP: None
selector:
app: nginx
ports:
- port: 80
关键字段解析
serviceName
该字段是为了关联一个 Headless Service。Headless Service 的 clusterIP 为 None,它为每个 Pod 提供唯一的 DNS 名称。例如,web-0 的 DNS 名称为:
web-0.web.default.svc.cluster.local
replicas
定义 StatefulSet 运行的 Pod 副本数量。
volumeClaimTemplates
定义 PVC 模板,用于动态生成持久存储卷。每个 Pod 都会获得独立的 PVC,例如 data-web-0, data-web-1, data-web-2。这些 PVC 可以关联到不同的 PersistentVolume(PV),确保每个 Pod 的数据独立。
podManagementPolicy
控制 Pod 的创建和删除方式:
OrderedReady
(默认):Pod 按序号顺序启动,只有前一个 Pod 处于 Ready 状态时,才启动下一个。
Parallel
:Pod 可以并行启动或删除。配置为:
podManagementPolicy: Parallel
3. StatefulSet 操作流程
3.1 创建 StatefulSet
使用StatefulSet 配置文件创建:
kubectl apply -f statefulset.yaml
3.2 查看 StatefulSet 和 Pod 状态
查看时要注意名称空间
kubectl get statefulsets
kubectl get pods
3.3 查看Statefulset详细信息
kubectl describe sts <statefulset-name>
kubectl describe sts web
3.4 直接修改statefulset
kubectl edit sts <statefulset-name>
kubectl edit sts web
谨慎操作:修改完立即生效
3.5 扩容与缩容
扩容:
kubectl scale statefulset web --replicas=5
新增 web-3 和 web-4 两个 Pod。
缩容:
kubectl scale statefulset web --replicas=2
删除web-4, web-3 和 web-2,且其对应的 PVC 会被保留。
3.4 删除 StatefulSet
保留 PVC:
kubectl delete statefulset web --cascade=orphan
不保留PVC:
kubectl delete pvc -l app=nginx
4. StatefulSet 更新机制
4.1 RollingUpdate 策略
RollingUpdate 是默认的更新策略,更新时按以下步骤进行:
从高序号 Pod 开始更新。只有当高序号 Pod 更新成功并进入 Ready 状态时,才会更新下一个 Pod。
updateStrategy:
type: RollingUpdate
4.2 OnDelete 策略
OnDelete 策略不自动更新 Pod。只有在手动删除 Pod 时,新的 Pod 才会被重新创建,并使用新的模板。
updateStrategy:
type: OnDelete
5. StatefulSet 使用场景
StatefulSet 适用于需要 持久化存储、稳定网络标识 和 有序操作 的应用。以下是几个典型场景:
5.1 数据库
如 MySQL、PostgreSQL、MongoDB:
需要每个数据库实例有唯一标识。数据存储需要持久化,即使 Pod 被重新调度或删除,数据也不能丢失。
5.2 分布式存储
如 Cassandra、Elasticsearch、HDFS:
每个存储节点有独立的存储卷。集群内节点需要通过稳定的 DNS 名称进行通信。
5.3 消息队列
如 Kafka、RabbitMQ:
每个 Broker 需要持久化存储日志或消息。Broker 节点需要稳定标识以加入集群。
5.4 缓存系统
如 Redis、Memcached:
配置主从模式,主节点和从节点需要有固定标识以确保同步关系。
6. StatefulSet 与其他控制器比较
7. StatefulSet 常见问题和注意事项
7.1 Pod 启动时间过长
StatefulSet 在创建 Pod 时,会等待前一个 Pod 进入 Ready 状态。因此,如果某个 Pod 启动时间较长,会阻塞后续 Pod 的创建。
解决方法:
检查容器的启动探针 (readinessProbe) 是否配置合理。如果无须严格的启动顺序,可以将 podManagementPolicy 设置为 Parallel。
7.2 删除 StatefulSet 时数据未保留
默认情况下,删除 StatefulSet 也会删除其 Pod 和相关资源。
如果希望保留 PVC,需使用 --cascade=orphan 参数。
7.3 滚动更新失败
如果某个 Pod 在更新过程中无法进入 Ready 状态,将阻塞后续 Pod 的更新。
解决方法:
调整更新策略为 OnDelete,手动控制更新。优化 Pod 的配置和探针设置。StatefulSet 是 Kubernetes 中管理有状态应用的核心工具。通过它,可以为有序性和持久性要求高的系统提供强大的支持。希望这份超详解能够帮助你深入理解并灵活使用 StatefulSet!
Linux上有趣的8个命令,你玩过几个? 万字长文:K8S命令详解汇总【自用珍藏版】 手把手教你搭建企业级Harbor镜像仓库 【Docker系列知识】常用命令大全汇总 局域网内构建统一可访问的YUM源(基础运维必备技能) Linux文件处理三剑客详解(运维高手必备) Nginx配置文件详解及常用功能配置(实用率90%)