首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Kubernetes:深入解读Deployment与StatefulSet的关键区别

Kubernetes:深入解读Deployment与StatefulSet的关键区别

作者头像
用户11081884
发布2026-07-20 20:35:20
发布2026-07-20 20:35:20
270
举报

部署 K8s 应用时第一个要回答的问题:用 Deployment 还是 StatefulSet?答案取决于你的应用有没有状态。

无状态 vs 有状态

无状态应用:实例之间完全对等,不保存任何需要持久化的数据,随时创建销毁都无所谓。比如 Nginx、API 网关、前端服务。

有状态应用:每个实例有唯一身份,需要独立的存储,实例之间可能有主从关系,不能随意替换。比如 MySQL、Kafka、Redis Cluster。

核心区别

维度

Deployment

StatefulSet

适用场景

无状态应用

有状态应用

Pod 身份

随机名称和 IP,重启后可能变

固定名称(web-0, web-1…)和稳定 DNS

存储

所有 Pod 共享同一个 PVC 模板

每个 Pod 独立的 PVC,Pod 重建后存储跟着走

扩缩容

并行创建/删除,速度快

按序号串行创建/删除(0→1→2)

服务发现

Service 负载均衡,流量随机分发

Headless Service,每个 Pod 有独立 DNS 记录

更新策略

RollingUpdate / Recreate,并行更新

支持分区更新,控制更新节奏

场景一:部署 Nginx(Deployment)

3 个副本,滚动更新,不需要持久化存储。

代码语言:javascript
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25-alpine
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1

场景二:部署 MySQL 主从集群(StatefulSet)

每个实例需要独立存储、稳定网络标识,用 Headless Service 做服务发现。

代码语言:javascript
复制
apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  ports:
  - port: 3306
    name: mysql
  clusterIP: None # Headless Service
  selector:
    app: mysql
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: "mysql"# 关联 Headless Service
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "your-secure-password"
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
  volumeClaimTemplates: # 每个 Pod 自动创建独立的 PVC
  - metadata:
      name: mysql-data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

关键点:volumeClaimTemplates 让每个 Pod 拿到自己的 PV,Pod 被调度到别的节点时数据跟着走;serviceName 指向 Headless Service,Pod 之间可以通过 mysql-0.mysqlmysql-1.mysql 直接通信。

怎么选

问自己三个问题:

  1. 应用需要持久化存储吗? 不需要-->Deployment。
  2. 实例之间有主从/依赖关系吗? 没有-->Deployment。
  3. 数据能外置到云数据库或 Redis 吗? 能-->用 Deployment 把状态外置,运维更简单。

只有当应用本身必须带着状态跑在 K8s 里(比如自建数据库集群),才用 StatefulSet。能用 Deployment 解决的,别用 StatefulSet。

“无他,惟手熟尔”!有需要的用起来!

如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Nicholas与Pypi 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 无状态 vs 有状态
  • 核心区别
  • 场景一:部署 Nginx(Deployment)
  • 场景二:部署 MySQL 主从集群(StatefulSet)
  • 怎么选
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档