全部產品
Search
文件中心

Container Service for Kubernetes:為StatefulSet配置雲端硬碟持久化儲存

更新時間:Sep 25, 2025

對於資料庫、訊息佇列等有狀態應用,StatefulSet 可通過 volumeClaimTemplates 為每個 Pod 動態建立並綁定獨立的雲端硬碟持久卷。Pod 被重建或重新調度時,能夠自動掛載回原有的儲存卷,從而實現資料持久化,保障商務持續性。

配置樣本如下:

apiVersion: apps/v1
kind: StatefulSet
# ...
spec:
  # ...
  volumeClaimTemplates:
  - metadata:
      name: data-volume                        # PVC 模板名稱
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "alicloud-disk-essd"   # 指定儲存類型
      resources:
        requests:
          storage: 20Gi                        # 申請的儲存空間大小

工作原理

  • 建立與擴容

    初始建立或擴容時,StatefulSet控制器會通過volumeClaimTemplates模板,為每個Pod副本(如web-0web-1)建立並綁定一個名稱唯一的PVC(如disk-essd-web-0disk-essd-web-1,名稱格式遵循[模板名]-[Pod名])。這一機制確保了Pod與其儲存之間穩定的映射關係。

    CSI 會根據模板中的參數配置 (storageClassNamestorageaccessModes),自動建立類型、大小和訪問模式比對的PV,完成綁定與掛載。

  • 縮容

    縮容時,控制器僅刪除 Pod 本身,其關聯的 PVC 及後端 PV 仍會保留,以確保資料安全。

  • 再次擴容與故障恢複

    基於縮容時的留存資料,再次擴容(調高副本數)或故障恢複(Pod刪除後重建)時,控制器會自動尋找並複用此前保留的同名 PVC。

    • 若存在,新的同名 Pod 會自動掛載此前的 PV,實現資料和狀態的快速恢複。

    • 若不存在(如擴容操作超過了歷史副本數峰值),則會建立 PVC和對應的PV。

準備StatefulSet

  1. 建立statefulset.yaml

    該樣本將建立一個Service 和一個包含2個副本的 StatefulSet,StatefulSet通過volumeClaimTemplates為每個副本自動建立一個 20 GiB 的雲端硬碟。

    volumeClaimTemplates中的參數說明如下。

    參數

    說明

    accessModes

    儲存卷的訪問模式。ReadWriteOnce表示該卷一次只能被一個節點以讀寫方式掛載。

    storageClassName

    待使用的StorageClass名稱。

    alicloud-disk-essd是ACK預設提供的StorageClass,用於建立ESSD雲端硬碟,預設PL等級為PL1。

    雲端硬碟採用隨用隨付,請參見Block Storage計費Block Storage價格

    storage

    雲端硬碟儲存卷的容量大小。

    展開查看樣本YAML

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      ports:
      - port: 80
        name: web
      # clusterIP 設定為 "None" 表明這是一個 Headless Service
      clusterIP: None
      selector:
        app: nginx
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: web
    spec:
      selector:
        matchLabels:
          app: nginx
      # serviceName 需與上面定義的 Headless Service 的名稱匹配
      serviceName: "nginx"
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            ports:
            - containerPort: 80
              name: web
            # 將持久卷掛載到容器內的指定路徑
            volumeMounts:
            - name: disk-essd
              mountPath: /data
      # PVC 的模板,StatefulSet 會根據此模板為每個 Pod 建立一個 PVC
      volumeClaimTemplates:
      - metadata:
          name: disk-essd
        spec:
          # 定義卷訪問模式
          accessModes: [ "ReadWriteOnce" ]
          # 指定用於動態供應 PV 的 StorageClass
          storageClassName: "alicloud-disk-essd"
          resources:
            requests:
              # 定義為每個 PVC 申請的儲存空間大小
              storage: 20Gi
  2. 部署StatefulSet。

    kubectl create -f statefulset.yaml
  3. 確認 Pod 處於 Running 狀態。

    kubectl get pod -l app=nginx
  4. 查看PVC,確認系統已經為每個 Pod 自動建立並綁定(Bound)了對應的 PVC。

    kubectl get pvc

    預期輸出:

    NAME              STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
    disk-essd-web-0   Bound    d-m5eb5ozeseslnz7zq54b   20Gi       RWO            alicloud-disk-essd   <unset>                 3m31s
    disk-essd-web-1   Bound    d-m5ecrvjrhqwehgzqpk5i   20Gi       RWO            alicloud-disk-essd   <unset>                 48s

通過擴縮容驗證儲存生命週期管理

通過擴容、縮容、再到擴容的流程,觀察關聯 PVC 的建立、保留和複用情況。

應用擴容

  1. 增加StatefulSet副本數至3個。

    kubectl scale sts web --replicas=3
  2. 確認 Pod 處於 Running 狀態。

    kubectl get pod -l app=nginx
  3. 查看PVC,確認系統已自動建立了Pod web-2 以及對應的PVC disk-essd-web-2

    kubectl get pvc

    預期輸出:

    NAME              STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
    disk-essd-web-0   Bound    d-m5eb5ozeseslnz7zq54b   20Gi       RWO            alicloud-disk-essd   <unset>                 4m1s
    disk-essd-web-1   Bound    d-m5ecrvjrhqwehgzqpk5i   20Gi       RWO            alicloud-disk-essd   <unset>                 78s
    disk-essd-web-2   Bound    d-m5ee2cvzx4dog1lounjn   20Gi       RWO            alicloud-disk-essd   <unset>                 16s

應用縮容

  1. 減少StatefulSet副本數至2個。

    kubectl scale sts web --replicas=2
  2. 確認 Pod 處於 Running 狀態。

    kubectl get pod -l app=nginx
  3. 查看PVC。

    kubectl get pvc

    預期輸出:

    NAME              STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
    disk-essd-web-0   Bound    d-m5eb5ozeseslnz7zq54b   20Gi       RWO            alicloud-disk-essd   <unset>                 4m21s
    disk-essd-web-1   Bound    d-m5ecrvjrhqwehgzqpk5i   20Gi       RWO            alicloud-disk-essd   <unset>                 98s
    disk-essd-web-2   Bound    d-m5ee2cvzx4dog1lounjn   20Gi       RWO            alicloud-disk-essd   <unset>                 36s

    此時,Pod web-2 已被刪除,但 PVC disk-essd-web-2 仍然存在,以確保資料持久性。

應用再次擴容

  1. 再次增加StatefulSet副本數至3個。

    kubectl scale sts web --replicas=3
  2. 確認 Pod 處於 Running 狀態。

    kubectl get pod -l app=nginx
  3. 查看PVC。

    kubectl get pvc

    預期輸出:

    NAME              STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
    disk-essd-web-0   Bound    d-m5eb5ozeseslnz7zq54b   20Gi       RWO            alicloud-disk-essd   <unset>                 4m50s
    disk-essd-web-1   Bound    d-m5ecrvjrhqwehgzqpk5i   20Gi       RWO            alicloud-disk-essd   <unset>                 2m7s
    disk-essd-web-2   Bound    d-m5ee2cvzx4dog1lounjn   20Gi       RWO            alicloud-disk-essd   <unset>                 65s

    此時,建立的Pod web-2 已自動綁定並使用此前遺留的PVC disk-essd-web-2

通過類比Pod故障驗證持久化儲存

通過“寫入資料 -> 刪除 Pod -> 檢查資料”的流程,來驗證儲存在雲端硬碟上的資料在 Pod 重建後是否仍然存在。

  1. 在 Pod 中寫入測試資料。

    以Pod web-1為例,在其掛載的雲端硬碟路徑 /data下建立一個test檔案。

    kubectl exec web-1 -- touch /data/test
    kubectl exec web-1 -- ls /data

    預期輸出:

    lost+found
    test
  2. 類比 Pod 故障,刪除 Pod。

    kubectl delete pod web-1

    再次執行kubectl get pod -l app=nginx,可以發現已自動建立一個同名的Pod web-1

  3. 驗證新 Pod 中的資料。

    在新Pod web-1中再次檢查 /data 目錄。

    kubectl exec web-1 -- ls /data

    預期輸出中,此前建立的 test 檔案依然存在,表明即使 Pod 被刪除重建,資料也實現了持久化儲存。

    lost+found
    test

應用於生產環境

  • 成本與資源管理:StatefulSet 縮容或刪除後,其關聯的 PVC 和雲端硬碟預設會被保留,存留資源會持續產生費用。請及時清理無需使用的 PVC和PV,並釋放雲端硬碟。

  • 資料安全與備份:持久化儲存僅解決 Pod 重建後的高可用問題,但不提供資料備份能力。對於核心業務,建議使用備份中心進行資料的備份和恢複。

  • 高可用與容災:雲端硬碟是可用性區域層級資源,不支援跨可用性區域掛載。建議選用支援多可用性區域容災的雲端硬碟類型,將資料即時同步寫入同一地區的不同可用性區域,實現跨可用性區域的故障恢複,請參見使用ESSD同城冗餘雲端硬碟

相關文檔

使用雲端硬碟儲存卷如遇問題,可參見雲端硬碟儲存卷FAQ排查。