對於資料庫、訊息佇列等有狀態應用,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-0、web-1)建立並綁定一個名稱唯一的PVC(如disk-essd-web-0、disk-essd-web-1,名稱格式遵循[模板名]-[Pod名])。這一機制確保了Pod與其儲存之間穩定的映射關係。CSI 會根據模板中的參數配置 (
storageClassName、storage、accessModes),自動建立類型、大小和訪問模式比對的PV,完成綁定與掛載。縮容
縮容時,控制器僅刪除 Pod 本身,其關聯的 PVC 及後端 PV 仍會保留,以確保資料安全。
再次擴容與故障恢複
基於縮容時的留存資料,再次擴容(調高副本數)或故障恢複(Pod刪除後重建)時,控制器會自動尋找並複用此前保留的同名 PVC。
若存在,新的同名 Pod 會自動掛載此前的 PV,實現資料和狀態的快速恢複。
若不存在(如擴容操作超過了歷史副本數峰值),則會建立 PVC和對應的PV。
準備StatefulSet
建立
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雲端硬碟儲存卷的容量大小。
部署StatefulSet。
kubectl create -f statefulset.yaml確認 Pod 處於 Running 狀態。
kubectl get pod -l app=nginx查看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 的建立、保留和複用情況。
應用擴容
增加StatefulSet副本數至3個。
kubectl scale sts web --replicas=3確認 Pod 處於 Running 狀態。
kubectl get pod -l app=nginx查看PVC,確認系統已自動建立了Pod
web-2以及對應的PVCdisk-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
應用縮容
減少StatefulSet副本數至2個。
kubectl scale sts web --replicas=2確認 Pod 處於 Running 狀態。
kubectl get pod -l app=nginx查看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已被刪除,但 PVCdisk-essd-web-2仍然存在,以確保資料持久性。
應用再次擴容
再次增加StatefulSet副本數至3個。
kubectl scale sts web --replicas=3確認 Pod 處於 Running 狀態。
kubectl get pod -l app=nginx查看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已自動綁定並使用此前遺留的PVCdisk-essd-web-2。
通過類比Pod故障驗證持久化儲存
通過“寫入資料 -> 刪除 Pod -> 檢查資料”的流程,來驗證儲存在雲端硬碟上的資料在 Pod 重建後是否仍然存在。
在 Pod 中寫入測試資料。
以Pod
web-1為例,在其掛載的雲端硬碟路徑/data下建立一個test檔案。kubectl exec web-1 -- touch /data/test kubectl exec web-1 -- ls /data預期輸出:
lost+found test類比 Pod 故障,刪除 Pod。
kubectl delete pod web-1再次執行
kubectl get pod -l app=nginx,可以發現已自動建立一個同名的Podweb-1。驗證新 Pod 中的資料。
在新Pod
web-1中再次檢查/data目錄。kubectl exec web-1 -- ls /data預期輸出中,此前建立的 test 檔案依然存在,表明即使 Pod 被刪除重建,資料也實現了持久化儲存。
lost+found test
應用於生產環境
成本與資源管理:StatefulSet 縮容或刪除後,其關聯的 PVC 和雲端硬碟預設會被保留,存留資源會持續產生費用。請及時清理無需使用的 PVC和PV,並釋放雲端硬碟。
資料安全與備份:持久化儲存僅解決 Pod 重建後的高可用問題,但不提供資料備份能力。對於核心業務,建議使用備份中心進行資料的備份和恢複。
高可用與容災:雲端硬碟是可用性區域層級資源,不支援跨可用性區域掛載。建議選用支援多可用性區域容災的雲端硬碟類型,將資料即時同步寫入同一地區的不同可用性區域,實現跨可用性區域的故障恢複,請參見使用ESSD同城冗餘雲端硬碟。
相關文檔
使用雲端硬碟儲存卷如遇問題,可參見雲端硬碟儲存卷FAQ排查。