首页 / Kubernetes (k8s) 入门教程 / StatefulSet(有状态)

Kubernetes (k8s) 入门教程

StatefulSet(有状态)

本教程共 65 篇 · 第 20 篇 · 更新于 2026-08-14 · 约 12 分钟阅读

KubernetesStatefulSet有状态集工作负载持久存储

本节目标:学完你能说清 StatefulSet 和 Deployment 的核心区别,讲出”三个稳定”特性,并判断哪些应用该用 StatefulSet 而不是 Deployment。

Deployment 把 Pod 当成”一次性的螺丝钉”,随便换、随便重建。但数据库这种应用,每个实例都有名字、有自己那块盘,换一个就不是它了。StatefulSet(有状态集)就是为这类应用准备的。

20-1 无状态 vs 有状态

无状态应用不在乎自己叫啥、跑在哪台机器、盘是不是同一块。Web 服务就是这样,随便扩缩,挂了换个新的顶上。

有状态应用反过来:它有自己的身份和地盘。比如 MySQL 主从,每个节点得有固定名字、固定存储,数据不能串。这种”身份敏感”的应用,Deployment 管不了,得 StatefulSet。

Note

一句话区分:Pod 删了重建,你还在乎”它是不是原来那个”吗?在乎,就用 StatefulSet。

20-2 三个”稳定”特性

StatefulSet 相比 Deployment,强在这三件事。

稳定的网络标识:每个 Pod 有固定名字,格式是 状态集名-序号,比如 web-0web-1web-2。重启后名字不变。

稳定的存储:每个 Pod 绑定自己专用的持久卷(PVC),Pod 重建盘还在,数据不丢。

有序的部署与伸缩:启动时按 0、1、2 顺序来,前一个就绪才起下一个。缩容反过来,从序号大的先删。

kubectl get pods -l app=web
# web-0   1/1   Running
# web-1   1/1   Running
# web-2   1/1   Running

20-3 稳定的网络标识

StatefulSet 通常配一个无头 Service(Headless Service),它不分配集群 IP,而是让每个 Pod 有可解析的 DNS 名:<pod名>.<service名>.<命名空间>.svc.cluster.local

Note

无头 Service 的完整机制(DNS 解析、适用场景)见第 26 章。

集群内其它程序能用 web-0.nginx 直接找到 0 号 Pod。这对主从架构(谁是谁得认得清)特别关键。

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  clusterIP: None          # 无头 Service
  selector:
    app: web
  ports:
  - port: 80

20-4 稳定的存储 volumeClaimTemplates

StatefulSet 用 volumeClaimTemplates 给每个 Pod 自动申请一块专属持久卷。模板里有 web-0 的盘,重建 web-0 时还是挂回那块盘。

volumeClaimTemplates:
- metadata:
    name: data
  spec:
    accessModes: ["ReadWriteOnce"]
    resources:
      requests:
        storage: 1Gi

Pod 里把这块盘挂上:

containers:
- name: nginx
  image: nginx:1.27
  volumeMounts:
  - name: data
    mountPath: /usr/share/nginx/html
Tip

删除 StatefulSet 时,默认不会删它创建的 PVC。这正合心意:数据比 Pod 珍贵。要清盘得手动删 PVC,操作前务必确认。

20-5 有序部署与 podManagementPolicy

默认 podManagementPolicy: OrderedReady:严格按序,前一个 RunningReady 才起下一个。

如果不在乎顺序,想并行起,可设 Parallel,所有 Pod 一起创建。适合无主从依赖、只图身份稳定的场景。

spec:
  serviceName: nginx
  replicas: 3
  podManagementPolicy: OrderedReady
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:1.27

serviceName 要填前面那个无头 Service 的名字,StatefulSet 靠它生成 DNS。

20-6 常见坑

一是以为 StatefulSet 自动搞定数据复制。它只保证”身份和盘固定”,主从同步、数据备份得你自己配(比如 MySQL 自身的复制)。

二是缩容会丢 Pod 但留盘。缩回 2 个,web-2 的盘还在,重新扩回 3 个会复用那块盘,数据可能”复活”。

三是用 StatefulSet 跑纯无状态服务。那是用牛刀杀鸡,Deployment 更轻、更灵活。

Warning

生产跑数据库,StatefulSet 只是”身份稳定”这一步。备份、监控、故障切换一套都不能少。Kubernetes 不替你管数据正确性。

有状态解决了。还有一类”每台机器都要有一个”的需求——日志、监控 Agent。第 21 章讲 DaemonSet。