StatefulSet介绍-更新-扩容缩容-HPA

StatefulSet是一种用于部署有状态应用的Kubernetes控制器,提供稳定的网络标识、持久化存储和有序的扩展。本文详细介绍了其功能、使用限制、创建示例、网络ID生成、存储管理以及部署、删除和更新策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

StatefulSet 常用于部署有状态的且需要有序启动的应用程序。

StatefulSet 用来管理某 Pod 集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符。和 Deployment 类似, StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同的是, StatefulSet 为它们的每个 Pod 维护了一个有粘性的 ID。这些 Pod 是基于相同的规约来创建的, 但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。

如部署的用用有以下需求的

  • 需要稳定的独一无二的网络标识符。
  • 需要持久化数据。
  • 需要有序的、优雅的部署和扩展。
  • 需要有序的自动滚动更新。

如果应用程序不需要任何稳定的标识符或者有序的部署、删除或者扩展,应该使用无状态的控制器部署应用程序,比如Deployment。

使用限制

  • 给定 Pod 的存储必须由 PersistentVolume Provisioner 基于所请求的 storage class 来制备,或者由管理员预先制备。
  • 删除或者扩缩 StatefulSet 并不会删除它关联的存储卷。 这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。
  • StatefulSet 当前需要无头服务来负责 Pod 的网络标识。你需要负责创建此服务。
    当删除一个 StatefulSet 时,该 StatefulSet 不提供任何终止 Pod 的保证。 为了实现 StatefulSet 中的 Pod 可以有序且体面地终止,可以在删除之前将 StatefulSet 缩容到 0。
  • 在默认 Pod 管理策略(OrderedReady) 时使用滚动更新, 可能进入需要人工干预才能修复的损坏状态。

创建StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  creationTimestamp: "2024-03-28T07:57:59Z"
  generation: 1
  name: web
  namespace: apps
  resourceVersion: "5178385"
  uid: 3841bb6f-14cc-4189-86e4-d99555ef12c0
spec:
  minReadySeconds: 10
  podManagementPolicy: OrderedReady
  replicas: 3  # 默认是1
  revisionHistoryLimit: 10  # 默认是0
  selector:
    matchLabels:
      app: nginx
  serviceName: nginx
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: lowyard/nginx-slim:0.8
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          name: web
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /usr/share/nginx/html
          name: www
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 10
  updateStrategy:
    rollingUpdate:
      partition: 0
    type: RollingUpdate
  volumeClaimTemplates:
  - apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      creationTimestamp: null
      name: www
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
      storageClassName: rook-ceph-rbd
      volumeMode: Filesystem
    status:
      phase: Pending

部署完成后:

[root@master01 ~]# kubectl get po -n apps 
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          5m16s
web-1   1/1     Running   0          3m26s
web-2   1/1     Running   0          2m6s

pod名字:
对于具有 N 个副本的 StatefulSet,该 StatefulSet 中的每个 Pod 将被分配一个整数序号, 该序号在此 StatefulSet 中是唯一的。默认情况下,这些 Pod 将被赋予从 0 到 N-1 的序号,也就是 web-0 web-1 web-2。

稳定的网络 ID

StatefulSet 中的每个 Pod 根据 StatefulSet 的名称和 Pod 的序号派生出它的主机名。
组合主机名的格式为:

$(StatefulSet 名称)-$(序号) ## 也就是 web-0、web-1、web-2 的 Pod

StatefulSet 可以使用无头服务控制它的 Pod 的网络域
管理域的这个服务的格式为:

$(服务名称).$(名字空间).svc.cluster.local ## 也就是 web-0.apps.svc.cluster.local

其中 cluster.local 是集群域。 一旦每个 Pod 创建成功,就会得到一个匹配的 DNS 子域,格式为: ( p o d 名称 ) . (pod 名称). (pod名称).(所属服务的 DNS 域名),其中所属服务由 StatefulSet 的 serviceName 域来设定。

稳定的存储

对于 StatefulSet 中定义的每个 VolumeClaimTemplate,每个 Pod 接收到一个 PersistentVolumeClaim。 在上面的 nginx 示例中,每个 Pod 将会得到基于 StorageClass my-storage-class 制备的 1 GiB 的 PersistentVolume。如果没有指定 StorageClass,就会使用默认的 StorageClass。 当一个 Pod 被调度(重新调度)到节点上时,它的 volumeMounts 会挂载与其 PersistentVolumeClaims 相关联的 PersistentVolume。

请注意,当 Pod 或者 StatefulSet 被删除时,与 PersistentVolumeClaims 相关联的 PersistentVolume 并不会被删除。要删除它必须通过手动方式来完成。

部署和删除

  • 对于包含 N 个 副本的 StatefulSet,当部署 Pod 时,它们是依次创建的,从0创建到N-1。
  • 当删除 Pod 时,它们是逆序终止的,删除顺序是N-1一直删除到0。
  • 在将扩缩操作应用到 Pod 之前,它前面的所有 Pod 必须是 Running 和 Ready 状态。
  • 在一个 Pod 终止之前,所有的继任者必须完全关闭。

更新策略

StatefulSet 的 .spec.updateStrategy 字段让你可以配置和禁用掉自动滚动更新 Pod 的容器、标签、资源请求或限制、以及注解。有两个允许的值,OnDelete 和 RollingUpdate。

OnDelete 手动删除更新

当 StatefulSet 的 .spec.updateStrategy.type 设置为 OnDelete 时, 它的控制器将不会自动更新 StatefulSet 中的 Pod。 用户必须手动删除 Pod 以便让控制器创建新的 Pod,以此来对 StatefulSet 的 .spec.template 的变动作出反应。

示例:

# 展示的为部分yaml文件
  updateStrategy:
    type: OnDelete

RollingUpdate 滚动更新

RollingUpdate 更新策略对 StatefulSet 中的 Pod 执行自动的滚动更新。这是默认的更新策略。

当 StatefulSet 的 .spec.updateStrategy.type 被设置为 RollingUpdate 时, StatefulSet 控制器会删除和重建 StatefulSet 中的每个 Pod。 它将按照与 Pod 终止相同的顺序(从最大序号到最小序号)进行,每次更新一个 Pod。

示例:

# 展示的为部分yaml文件
  updateStrategy:
    rollingUpdate:
      partition: 0
    type: RollingUpdate

查看实时更新命令

更新完StatefulSet 或者是扩容完以后可以用这个命令查看实时更新进度。

# 正常情况下还需要加上命名空间 -n “命名空间名字”
kubectl get pods -w -l app=nginx

分区滚动更新(主要用于灰度发布)

通过声明 .spec.updateStrategy.rollingUpdate.partition 的方式,RollingUpdate 更新策略可以实现分区。 如果声明了一个分区,当 StatefulSet 的 .spec.template 被更新时, 所有序号大于等于该分区序号的 Pod 都会被更新。 所有序号小于该分区序号的 Pod 都不会被更新,并且,即使它们被删除也会依据之前的版本进行重建。 如果 StatefulSet 的 .spec.updateStrategy.rollingUpdate.partition 大于它的 .spec.replicas,则对它的 .spec.template 的更新将不会传递到它的 Pod。 在大多数情况下,你不需要使用分区,但如果你希望进行阶段更新、执行金丝雀或执行分阶段上线,则这些分区会非常有用。

示例:
当partition: 2 设置为2时 更新大于等于pod名字是2以上的。

# 展示的为部分yaml文件
  updateStrategy:
    rollingUpdate:
      partition: 2  # 默认是0 就是更新大于等于0的pod 也就是更新所有pod
    type: RollingUpdate

最大不可用pod

你可以通过指定 .spec.updateStrategy.rollingUpdate.maxUnavailable 字段来控制更新期间不可用的 Pod 的最大数量。 该值可以是绝对值(例如,“5”)或者是期望 Pod 个数的百分比(例如,10%)。 绝对值是根据百分比值四舍五入计算的。 该字段不能为 0。默认设置为 1。
示例:

  strategy:
    rollingUpdate:
      maxUnavailable: 25% # 指定在回滚或更新时最大不可用的Pod的数量,可选字段,默认25%,可以设置成数字或百分比,如果该值为0,那么maxSurge就不能为0
    type: RollingUpdate # 更新deployment的方式,默认是RollingUpdate日方

更新 StatefulSet 出问题时

  • 在默认 Pod 管理策略(OrderedReady) 下使用滚动更新, 可能进入需要人工干预才能修复的损坏状态。

  • 如果更新后 Pod 模板配置进入无法运行或就绪的状态(例如, 由于错误的二进制文件或应用程序级配置错误),StatefulSet 将停止回滚并等待。

  • 在这种状态下,仅将 Pod 模板还原为正确的配置是不够的。 由于已知问题,StatefulSet 将继续等待损坏状态的 Pod 准备就绪(永远不会发生),然后再尝试将其恢复为正常工作配置。

  • 恢复模板后,还必须删除 StatefulSet 尝试使用错误的配置来运行的 Pod。这样, StatefulSet 才会开始使用被还原的模板来重新创建 Pod。

扩容/缩容 StatefulSet

扩容

在一个终端窗口监视 StatefulSet 的 Pod:

# 如果你已经有一个正在运行的 wach,你可以继续使用它。
# 否则,就启动一个。
# 当 StatefulSet 有 5 个健康的 Pod 时结束此 watch
kubectl get pods --watch -l app=nginx

在另一个终端窗口使用 kubectl scale 扩展副本数为 5:

# sts 是StatefulSet的缩写
kubectl scale sts web --replicas=5

在第一个 终端中检查 kubectl get 命令的输出,等待增加的 3 个 Pod 的状态变为 Running 和 Ready。

# 这应该已经处于 Running 状态
kubectl get pod --watch -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          2h
web-1     1/1       Running   0          2h
NAME      READY     STATUS    RESTARTS   AGE
web-2     0/1       Pending   0          0s
web-2     0/1       Pending   0         0s
web-2     0/1       ContainerCreating   0         0s
web-2     1/1       Running   0         19s
web-3     0/1       Pending   0         0s
web-3     0/1       Pending   0         0s
web-3     0/1       ContainerCreating   0         0s
web-3     1/1       Running   0         18s
web-4     0/1       Pending   0         0s
web-4     0/1       Pending   0         0s
web-4     0/1       ContainerCreating   0         0s
web-4     1/1       Running   0         19s

StatefulSet 控制器扩展了副本的数量。 如同创建 StatefulSet 所述,StatefulSet 按序号索引顺序创建各个 Pod,并且会等待前一个 Pod 变为 Running 和 Ready 才会启动下一个 Pod。

缩容

终端使用 kubectl patch 将 StatefulSet 缩容回三个副本:

kubectl patch sts web -p '{"spec":{"replicas":3}}'

缩容实时查看方法和扩容的一样。

HPA自动扩缩容

点击跳转

<think>嗯,用户现在问的是数据库能不能自动扩容。首先,我需要确定用户对数据库自动扩的理解程度。可能用户已经接触过一些云服务或者容器编排,比如之前的k8s问题,所以可能对自动扩有基础认识,但不确定具体如何应用到数据库上。 接下来,我需要考虑用户的实际需求。用户可能在使用数据库时遇到了性能问题,比如流量激增导致数据库负载过高,或者资源闲置想要节省成本。这时候自动扩就显得很重要了。用户可能想知道现有的技术是否支持数据库的自动扩,以及如何实现。 然后,我需要区分不同类型的数据库,因为关系型数据库和NoSQL在扩上有不同的机制。比如,传统的关系型数据库如MySQL扩展可能较复杂,而云原生的数据库如Aurora或NoSQL的MongoDB、Cassandra可能有更好的支持。此外,用户可能关心的是云服务提供商是否提供这样的功能,或者是否需要自己实现。 还要考虑到自动扩的不同维度,比如存储扩容、计算资源(CPU、内存)的扩,以及读写分离或分片等架构上的调整。需要解释这些方面各自的实现方式和自动化程度。 用户可能还关心实现自动扩的条件和挑战,比如数据一致性、分片策略、监控指标的选择(CPU、连接数、磁盘IO)等。需要指出哪些是可以自动化的,哪些需要人工干预,以及不同数据库类型的限制。 另外,用户可能对具体的云服务产品感兴趣,比如AWS的Aurora、Google Cloud的Spanner,或者阿里云的PolarDB,这些服务通常提供了自动扩的功能,应该举例说明,让用户有更直观的理解。 最后,需要总结自动扩的可行性和注意事项,帮助用户权衡利弊,根据自身业务需求选择合适的方案。可能用户是技术决策者或开发者,需要评估实施自动扩的复杂度和维护成本,因此提供实际案例和最佳实践会很有帮助。</think>--- 数据库的自动扩容能力取决于**数据库类型**、**架构设计**和**底层平台支持**。以下是分场景的详细解析: --- ### **1. 自动扩的维度** #### **(1) 存储扩容** - **传统数据库**: - 如MySQL、PostgreSQL的单机版,存储扩容通常需要**停机扩展磁盘**或使用逻辑卷管理(LVM),**无法自动完成**。 - 例外:云托管服务(如AWS RDS、阿里云RDS)支持**在线调整存储**,无需停机。 - **分布式数据库**: - 如Cassandra、TiDB,通过动态添加节点,存储量可**自动均衡**。 #### **(2) 计算资源扩(CPU/内存)** - **云托管数据库**: - AWS Aurora、Google Cloud SQL等支持**按负载自动升降配**(如CPU/内存弹性调整)。 - 基于监控指标(CPU利用率、连接数)触发扩- **容器化数据库**: -Kubernetes中运行的数据库(如PostgreSQL Operator),可通过HPA(Horizontal Pod Autoscaler)**自动增减Pod副本数**。 #### **(3) 读写分离与分片** - **读写分离**: - 如MySQL Group Replication,可自动添加只读副本(需配合代理层如ProxySQL)。 - **分片(Sharding)**: - 如MongoDB Sharded Cluster、Vitess,支持动态添加分片节点,但**分片策略调整需人工干预**。 --- ### **2. 典型场景与实现方式** #### **场景1:云托管数据库自动扩(以AWS Aurora为例)** - **存储自动扩展**: - 开启**存储自动扩容**后,当存储使用量超过阈值(如85%),系统自动以10%增量扩展,上限为128TB。 - **计算层扩**: - 通过Aurora Serverless v2,可基于ACU(Aurora Capacity Unit)**秒级调整计算资源**,支持到0.5 ACU以节省成本。 #### **场景2:Kubernetes中的数据库自动扩(以PostgreSQL为例)** 1. 部署**PostgreSQL Operator**(如Crunchy Data PGO)。 2. 配置HPA基于CPU/内存指标自动扩Pod: ```yaml apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: postgres-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: StatefulSet name: postgres minReplicas: 1 maxReplicas: 5 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 80 ``` 3. 时需确保**连接排空**,避免事务中断。 #### **场景3:NoSQL数据库弹性扩展(以MongoDB Atlas为例)** - **自动分片平衡**: - 添加新分片后,MongoDB自动迁移数据块(Chunk)实现负载均衡。 - **按需调整集群层级**: - 支持在M10(2GB内存)到M700(488GB内存)间**垂直自动扩**。 --- ### **3. 关键技术挑战** #### **(1) 有状态服务的复杂性** - 数据库扩容需处理**数据一致性**(如分布式事务)、**数据迁移同步**(如Vitess VReplication)。 - 需确保**节点数据已完全转移**,否则可能引发数据丢失。 #### **(2) 自动化工具依赖** - 开源方案(如Patroni for PostgreSQL)仅支持**半自动故障转移**,扩仍需人工介入。 - 完全自动化需结合云服务或专用Operator(如Redis Operator)。 #### **(3) 成本与性能平衡** - 频繁可能导致**冷启动延迟**(如Aurora Serverless恢复暂停实例需数秒)。 - 存储自动扩容可能增加费用,需设置合理上限。 --- ### **4. 最佳实践** 1. **优先选择云托管服务**: - 如Azure SQL Database、Amazon DynamoDB等,原生支持自动扩。 2. **设定缓冲阈值**: - 扩容阈值设为70%负载,阈值设为30%,避免频繁波动。 3. **隔离弹性层级**: - 计算层(无状态)与存储层(有状态)分开扩,降低复杂度。 4. **监控与告警**: - 监控慢查询、锁竞争等指标,避免单纯依赖资源利用率触发扩--- ### **5. 开源方案 vs 云服务** | **能力** | 开源方案(如K8s+Operators) | 云托管数据库(如Aurora) | |------------------|-----------------------------------|----------------------------------| | 存储自动扩容 | ❌ 需手动扩展PVC | ✅ 完全自动 | | 计算资源弹性 | ✅ 通过HPA实现(仅无状态副本) | ✅ 秒级调整(支持有状态实例) | | 分片自动化 | ❌ 需人工定义分片键 | ✅ 部分支持(如MongoDB Atlas) | | 成本 | 低(基础设施自管) | 高(按需付费) | --- ### **总结** 数据库自动扩**可以实现**,但需根据类型选择方案: - **云托管数据库**:开箱即用的自动弹性,适合快速上云场景。 - **自建数据库**:需结合Kubernetes Operators或分布式架构,实现有限自动化。 - **关键建议**:优先通过读写分离、缓存层优化减少对数据库扩的依赖。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值