使用 Operating 高效管理持久化卷

文章介绍了KusionStackOperating的最新版本,特别是CollaSet组件如何简化持久化卷管理,包括自动处理PVC模板变更、支持无中断应用扩展。文章还讨论了传统方法的痛点以及CollaSet如何通过自动化运维经验降低成本和风险。

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

b7a24a3a10f032e998723fbb90f048f6.gif

前言

KusionStack Operating 致力于提供符合 Kubernetes 标准的云原生运维、链路可观测、资源可洞察等能力,以帮助开发者更好地搭建自己的平台。

目前 KusionStack Opearating 已发布到 v0.3.0 版本。在最近版本中,Operating CollaSet 新增对持久卷的配置使用,允许用户声明 VolumeClaimTemplate 为 Pod 创建 PVCs。此外,对于持久化卷变更成本高和难以控制的问题,CollaSet 通过下沉和复用运维经验加以解决,并支持:

1. 用户根据对存储卷的需求,可灵活修改、添加或删除 PVC 模版;

2. 提供对 PVC 生命周期的控制。

01

使用Workload管理持久化卷

持久化卷声明 PVC(PersistentVolumeClaim)能够让用户请求持久化卷 PV (PersistentVolume),为应用的状态提供稳定、持久的存储介质。在无状态 Workload(如 Deployment、DaemonSet)部署的应用中使用持久化卷,需用户手动创建 PVC 并挂载到容器。

无状态 Workload 缺乏对持久化卷的统一管理,为简化持久化卷的使用,社区提供多种有状态 Workload,如 StatefulSet、Advanced StatefulSet、CloneSet 等,它们向用户暴露配置入口 VolumeClaimTemplates(PVC 模版),为每个 Pod 维护独立的 PVC。

StatefulSet

StatefulSet 是 Kubernetes 中用于部署和管理有状态的应用的原生 Workload API 对象。StatefulSet 为每个 Pod 实例提供稳定、唯一的网络标识符和 PVCs;当 Pod 发生故障时,通过唯一标识将新建的 Pod 与 PVCs 重新关联,以恢复数据和保持弹性。

Advanced Statefulset

Advanced StatefulSet 是 OpenKruise 基于 StatefulSet 设计的 Workload,增强了原生 StatefulSet 发布、原地升级和 PVC 管理等能力。Advanced StatefulSet 提供对持久卷的生命周期的控制:通过配置保留策略以决定 StatefulSet 和 Pod 生命周期结束时是否级联删除所关联的 PVCs。原生 StatefulSet 在 Kubernetes 1.27 beta 版本后也支持了 PVC 生命周期管理。

CloneSet

CloneSet 是由 OpenKruise 提供的 Workload,支持原地升级、分批灰度发布和 PVCs 管理等功能。它将持久化卷的管理与运维融合,不同升级方式 PVC 管理策略不同。如原地升级后的 Pod 会复用原持久化卷;重建升级会删除原 Pod 关联的持久化卷并重建。尽管重建升级也为灵活扩展持久化卷提供了可能,但 CloneSet 的设计目标不包括变更 PVC,因此仅变更 PVC 模版不生效。

02

管理持久化卷的痛点

在前文介绍的 Workloads 下,当应用存储空间不足,用户需手动扩展持久化卷,这件事情在大规模的集群下并不容易。原因是它们不感知 PVC 模版变化,因此用户需要手动维护和更新 PVCs(如 StatefulSet 中 PVC 变更事件在 Webhook 被拦截,无法被调和),存在以下痛点:

  • :过程需删除、重建 Workload,服务被强制中断导致不可用;

  • 成本:无法复用经验,运维成本高;当部署规模越来越大,问题变得更加突出。

接下来演示一个扩展 StatefulSet 持久卷容量的例子:

|环境准备

1. 部署 K8s 集群,如 Minikube,Kind 等

    • https://minikube.sigs.k8s.io/docs/start/

    • https://kind.sigs.k8s.io/docs/user/quick-start/

2. 安装 csi-driver-host-path

    • https://github.com/kubernetes-csi/csi-driver-host-path#development

3. 制备可扩展 StorageClass

$ git clone https://github.com/kubernetes-csi/csi-driver-host-path.git
$ kubectl apply -f ./csi-driver-host-path/examples/csi-storageclass.yaml

$ kubectl get storageclass
NAME                 PROVISIONER                RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
csi-hostpath-sc      hostpath.csi.k8s.io        Delete          Immediate           true                   30m

4. 使用 sample.yaml 准备一个简单的 StatefulSet

# sample.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sample
spec:
  replicas: 2
  selector:
    matchLabels:
      app: sample
  template:
    metadata:
      labels:
        app: sample
    spec:
      containers:
      - image: nginx:1.25
        name: nginx
        volumeMounts:
        - mountPath: /path/to/storage
          name: foo
  volumeClaimTemplates:
  - metadata:
      name: foo
    spec:
      storageClassName: csi-hostpath-sc # 使用提前制备的可扩展 StorageClass
      volumeMode: Filesystem
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 10G

|扩展持久化卷

1. 确保 StorageClass 可扩展

仅部分类型支持扩展,本例中 CSI 类型支持扩展

$ kubectl get storageclass csi-hostpath-sc | grep allowVolumeExpansion
allowVolumeExpansion: true

2. 删除原 StatefulSet,根据需求修改 PVC 模版大小为 20Gi

删除后服务处于不可用状态

$ kubectl delete statefulset sample
statefulset.apps/sample deleted
$ cat statefulset.yaml
...
  volumeClaimTemplates:
  ...
    spec:
      ...
      resources:
        requests:
-         storage: 10Gi
+         storage: 20Gi
...

3. 修改 PVC 容量至 20Gi

$ kubectl edit pvc foo-sample-0
spec:
...
  resources:
    requests:
-     storage: 10Gi
+     storage: 20Gi # 扩展容量至 20Gi
...

4. 使用修改后的 yaml 重新创建 StatefulSet

$ kubectl apply -f statefulset.yaml 
statefulset.apps/sample created

$ kubectl get pod
NAME                   READY   STATUS    RESTARTS   AGE
sample-0                  1/1     Running   0          18s
sample-1                  1/1     Running   0          11s

$ kubectl get pvc
NAME        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
foo-sample-0   Bound    pvc-80f27a1c-3a39-4e02-8425-2e04e5dd660f   20Gi       RWO            csi-hostpath-sc   2m5s
foo-sample-1   Bound    pvc-ee487d9b-dcd5-4826-a730-6a35f9fc4a52   20Gi       RWO            csi-hostpath-sc   115s

在以上示例中可以观察到,扩展 StatefulSet 持久化卷流程较为复杂;且部署的应用被删除和重建,难以保证服务持续可用,风险较高。

03

使用CollaSet管理持久化卷

CollaSet 是 Kusionstack Operating 提供的工作负载,为应用 Pod 提供运维、精细化生命周期管理等能力,同时支持部署有状态应用。CollaSet 支持管理持久化卷,包括更新、新增、删除持久化卷,控制持久卷的生命周期,下面通过两个示例展示 CollaSet 如何管理 PVC。

|扩展持久化卷

以下图为例,展示了用户变更持久卷流程,假设用户使用 CollaSet 时对持久卷的需求发生变化,要求将名为 foo 的持久卷扩容至 20Gi。此时用户仅需修改名称为 foo 的 VolumeClaimTemplates,CollaSet 接管复杂的 Pod 和 PVCs 更新替换操作:

0c5f47130fab4aea3c8e82cbfe94a62a.png

  1. 删除大小为 10Gi 的持久卷,同时删除 Pod-1,创建 Pod-1';

  2. 根据模版 foo 创建大小为 20Gi 的持久卷,并绑定至 PVC-1';

  3. 并将 PVC-1' 挂载到 Pod-1';

在 PVC 扩展时,用户可选择是否保留原 PVC-1。通过配置保留策略 whenScaled=Retain 以保留原 PVC-1,此时用户回滚至 10G 版本,原 PVC-1 将被自动挂回 Pod。若用户不再需要原始 PVC 数据,通过配置 whenScaled=Delete 删除 PVC-1。

|新增持久化卷

接着以上示例,假设用户进一步要求为每个 Pod 新增持久卷,以下图为例,用户在 PVC 模版列表新增一个名为 www 的持久卷,CollaSet 感知 PVC 模版列表新增,并自动创建挂载 PVC:

7df977d4e0da47c743bde2ae9081cc0e.png

  1. 删除 Pod-1',创建 Pod-1'';

  2. 创建 PVC-2;

  3. PVC-2 与 PVC1'' 挂载到 Pod-1''。

|试一试

0. 安装 Operating

    • https://www.kusionstack.io/docs/operating/started/install

1. 基于前示例中 sample.yaml 准备 CollaSet

# cat sample.yaml
- apiVersion: apps/v1
- kind: StatefulSet
+ apiVersion: apps.kusionstack.io/v1alpha1
+ kind: CollaSet
...
spec:
- replicas: 2
+ replicas: 1
$ kubecel apply -f sample.yaml
collaset.apps.kusionstack.io/sample created

$ kubectl get pod
NAME                   READY   STATUS    RESTARTS   AGE
sample-fn928           1/1     Running   0          13s

$ kubectl get pvc
NAME               STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
sample-foo-4hhjz   Bound    pvc-cf5b0db4-810f-4530-ae3c-33f8d3bb0ba0   10Gi       RWO            csi-hostpath-sc   17s

2. 更新、添加 PVC 模版

# cat sample.yaml
  template:
  ...
    spec:
      containers:
      ...
        volumeMounts:
        ...
+       - mountPath: /path/to/storage-www
+         name: www
  ...
  volumeClaimTemplates:
  - metadata:
      name: foo
    spec:
      ...
      resources:
        requests:
-         storage: 10Gi
+         storage: 20Gi     # 修改存储容量至 20Gi
      storageClassName: csi-hostpath-sc
      volumeMode: Filesystem
+ - metadata:
+     name: www     # 新增名 PVC 模版
+   spec:
+     accessModes:
+     - ReadWriteOnce
+     resources:
+       requests:
+        storage: 20Gi
+     storageClassName: csi-hostpath-sc
+     volumeMode: Filesystem
$ kubectl apply -f sample.yaml
collaset.apps.kusionstack.io/sample configured

3. 验证 Pod 与 PVC 状态,观察到 Pod 和 PVC 被重建和挂载

$ kubectl get pod
NAME                   READY   STATUS    RESTARTS   AGE
sample-fn928   1/1     Terminating         0          101s
sample-k8wtz   0/1     ContainerCreating   0          4s

$ kubectl get pvc
NAME               STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
sample-foo-w42vm   Bound    pvc-f9e525e9-174f-4bcf-9218-d22fc21c81a2   20Gi       RWO            csi-hostpath-sc   6s
sample-www-ns7c7   Bound    pvc-8ced1205-e447-43b0-a598-7e6ef2584073   20Gi       RWO            csi-hostpath-sc   6s

可以观察到 PVC 变更过程无需删除 Workload,服务保持可用;过程中用户也可以使用 ReplaceUpdate 或 Partition 等发布策略保证服务质量。更多内容详见 CollaSet 手册:https://www.kusionstack.io/docs/operating/manuals/collaset

总结

持久化数据是支撑有状态应用的基础,现有工作负载通过管理 PVC 支持有状态应用,具有许多优点,如优雅管理 PVC 生命周期、与 Pod 运维兼容等。当用户的需求发生变化,需要扩展、删除、新增持久化卷时需要人工介入,且存在风险。为更好地支持有状态应用,CollaSet 将人工管理运维经验下沉,感知 PVC 变更,以提升效率和降低风险。

更多的云原生运维能力还等着我们探索和发现,也欢迎大家一起参与共建!

欢迎 star ⭐️

https://github.com/KusionStack/kusion

https://github.com/KusionStack/operating

https://github.com/KusionStack/controller-mesh

https://github.com/KusionStack/resource-consist

https://github.com/KusionStack/kube-utils

https://github.com/kcl-lang/kcl

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值