第四部分:StatefulSet 资源介绍

📝 前言

在 Kubernetes 中,大多数应用可以通过 Deployment 等无状态控制器轻松实现弹性伸缩和滚动升级。

但对于需要稳定网络标识、稳定存储以及有序部署的有状态应用,如数据库、消息队列或分布式协调服务,就需要使用 StatefulSet

本文将系统介绍 StatefulSet 的概念、应用场景、核心特性和实际使用示例。

🧭 背景介绍

有状态应用(Stateful Applications)与无状态应用不同,它们通常需要:

  • 固定且唯一的 Pod 名称,便于服务发现和内部通信。
  • 持久化存储,即使 Pod 迁移或重建后,数据仍需保留。
  • 有序部署与终止,某些分布式系统要求严格的启动和关闭顺序。

传统的 Deployment 在 Pod 弹性扩缩容时,Pod 名称和存储卷会随意变化,无法满足这些需求。

因此 Kubernetes 提供了 StatefulSet 来解决这一类问题。

🔍 使用场景

典型场景包括:

  • 数据库集群:MySQL、PostgreSQL、MongoDB 等。
  • 分布式协调服务:如 Zookeeper、Etcd、Consul。
  • 消息队列系统:Kafka、RabbitMQ 等。
  • 任何需要稳定网络标识和持久化存储的应用。

🧠 本章知识卡片

🚀 本章小节

1️⃣ 什么是 StatefulSet?

StatefulSet 是 Kubernetes 提供的 有状态工作负载控制器,用于部署和管理需要稳定标识与持久化存储的 Pod。

与 Deployment 或 ReplicaSet 这类无状态控制器不同,StatefulSet 具备以下关键特点:

  • 稳定网络 ID:为每个 Pod 分配固定且可预测的名称(如 myapp-0myapp-1),并配合 Headless Service 提供恒定的 DNS 解析地址。
  • 稳定存储卷:每个 Pod 都会自动创建并绑定独立的 **PersistentVolumeClaim (PVC)**,即使 Pod 被调度到新的节点也能挂载原来的数据卷。
  • 有序生命周期:Pod 会按照顺序进行 创建、更新、删除,确保分布式应用的启动和终止流程符合要求。

简单理解:StatefulSet 是 Deployment 的“有状态版本”,专门用于运行需要“身份”和“记忆”的应用,如数据库、分布式协调服务、消息队列等。

2️⃣ 工作流程图

StatefulSet 大致工作流程图如下所示:

3️⃣ 实战示例:部署 MySQL 主从复制集群

创建 Headless Service 为每个 Pod 提供固定 DNS 名称。

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
clusterIP: None # 关键:无 ClusterIP,才能给每个 Pod 独立 DNS
selector:
app: mysql
ports:
- port: 3306
name: mysql

创建 MySQL StatefulSet

  • 副本数 3mysql-0 作为主节点,mysql-1mysql-2 作为从节点。
  • 每个 Pod 都挂载独立 PVC,保证数据持久化。
  • 通过 initContainer 配置主从复制初始化逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: "mysql"
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.4
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: my-secret-pw
volumeMounts:
- name: data
mountPath: /var/lib/mysql
# 可以在此处添加 initContainer 脚本完成主从复制配置
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi

这里只是一个简单的示例,用于演示如何使用 StatefulSet,真实环境请使用官方提供的 mysql 部署文件。

应用访问

集群内部可通过 mysql-0.mysqlmysql-1.mysqlmysql-2.mysql 直接访问对应节点。

即便某个 Pod 重建,mysql-0 的存储卷 data-mysql-0 依然绑定到同一个数据目录,保证主节点数据不丢失。

4️⃣ 常用命令

命令 说明
kubectl get sts 查看 StatefulSet 列表
kubectl describe sts <name> 查看详细信息
kubectl scale sts <name> --replicas=N 扩缩容
kubectl rollout status sts <name> 查看滚动更新状态

✅ 总结

StatefulSet 是 Kubernetes 专为有状态应用设计的控制器,提供稳定网络标识、持久化存储和有序部署等能力。

  • 稳定性:确保 Pod 名称和存储卷不会因重建而变化。
  • 扩展性:通过 Headless Service 实现服务发现,方便集群通信。
  • 安全性:有序升级与删除,保障数据完整和业务连续。

借助 StatefulSet,你可以在 Kubernetes 中轻松部署数据库集群、消息队列等有状态服务,实现云原生架构下的高可用与弹性。