部署StatefulSet並掛載雲端硬碟儲存卷時,可能會因為可用性區域配置、雲端硬碟類型等問題導致應用建立失敗。本文提供了雲端硬碟儲存多可用性區域部署的配置最佳化建議,協助您避免因底層配置導致的問題,最大限度地減少應用發布中斷。
方案背景
Kubernetes強大的容器編排能力,使得使用者在Kubernetes上構建大規模的有狀態應用(StatefulSet)變得越來越簡單。雖然Kubernetes簡化了應用分發部署的流程,但是也隱藏了底層的硬體邏輯,使用者很難感知具體的硬體邏輯,這可能會導致一些非預期的情況。
在多可用性區域構成的叢集下,需要應用部署在A可用性區域,最後發現實際部署在B可用性區域。
建立雲端硬碟儲存卷時,出現錯誤,例如動態建立PV失敗且提示InvalidDataDiskCatagory.NotSupported。
掛載應用時,出現錯誤
The instanceType of the specified instance does not support this disk category。調度應用時,出現錯誤
0/x node are available, x nodes had volume node affinity conflict。
以上這些問題均會導致應用發布中斷受阻,本文提供了一些高可用配置建議,可以減少上述問題的發生。
推薦配置
配置目標
對於StatefulSet,推薦使用雲端硬碟進行持久化儲存。相對於NAS,雲端硬碟更加穩定,資料傳輸頻寬更好。
叢集內包含多個可用性區域,確保機器和儲存資源滿足需求。
當叢集可用性區域內的節點均不可用時,可立即彈出節點進行匹配。
使用高可用的StorageClass,避免雲端硬碟掛載失敗。
確保應用可以均勻分配至各個節點(各個可用性區域)。
節點池推薦配置
每個節點池使用單一可用性區域。
每新增一個可用性區域,建議建立一個節點池。具體操作,請參見建立和管理節點池。
建立節點池時,確保每個節點池對應各自不同的可用性區域,建議使用節點池名稱區分不同的可用性區域。
開啟節點池的Auto Scaling功能。具體操作,請參見啟用節點自動調整。
當前可用性區域沒有可用的節點時,系統會自動彈出一個對應可用性區域的節點供Pod調度,如下圖所示。

多可用性區域內盡量使用同一類型的ECS資源,或者支援同一種類型Block Storage的ECS資源。
某些類型的雲端硬碟不支援掛載到某些規格的ECS執行個體。即使在同一個可用性區域調度,也可能因為有節點不支援聲明的雲端硬碟,導致Pod因雲端硬碟掛載問題而無法啟動。
在節點池上對所有節點池進行汙點配置,確保不會有其他非預期應用被調度過來影響當前應用。

叢集推薦配置
確保叢集版本不低於1.20。
確保叢集的CSI組件版本不低於1.22。更多資訊,請參見管理csi-plugin和csi-provisioner組件。
使用高可用的StorageClass。
YAML樣本如下:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: alicloud-disk-topology-alltype parameters: type: cloud_essd,cloud_ssd,cloud_efficiency provisioner: diskplugin.csi.alibabacloud.com reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer allowVolumeExpansion: true allowedTopologies: - matchLabelExpressions: - key: topology.diskplugin.csi.alibabacloud.com/zone values: - cn-beijing-a - cn-beijing-b部分參數說明如下:
type: cloud_essd,cloud_ssd,cloud_efficiency:結合雲端硬碟庫存,按照ESSD雲端硬碟、SSD雲端硬碟、高效雲端硬碟的順序依次嘗試建立,避免因雲端硬碟庫存不足而導致雲端硬碟建立失敗,進而導致Pod無法啟動。volumeBindingMode: WaitForFirstConsumer:先調度Pod到某一個特定的節點後,再根據StorageClass的配置建立雲端硬碟,可以保證雲端硬碟和節點處於同一可用性區域,避免因可用性區域不一致而導致雲端硬碟掛載失敗,進而導致Pod無法啟動。allowedTopologies:可以將製作儲存卷的拓撲限制在特定的地區可用性區域。當volumeBindingMode為WaitForFirstConsumer時,調度器將根據StorageClass的拓撲結構對Pod進行調度,以滿足雲端硬碟的建立需求。
應用推薦配置
以下給出了標準StatefulSet應用配置的模板,您可以根據需求自行定義應用配置。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: "mysql"
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
topologySpreadConstraints:
- labelSelector:
matchLabels:
app: mysql
maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "mysql"
volumeMounts:
- name: disk-csi
mountPath: /var/lib/mysql
tolerations:
- key: "app"
operator: "Exists"
effect: "NoSchedule"
volumeClaimTemplates:
- metadata:
name: disk-csi
spec:
accessModes: [ "ReadWriteMany" ]
storageClassName: alicloud-disk-topology-alltype
resources:
requests:
storage: 40Gi部分參數說明如下:
topologySpreadConstraints:盡量讓Pod分布在不同的可用性區域。更多資訊,請參見Topology Spread Constraints。volumeClaimTemplates:可以根據指定的Replicas數量自動建立對應數量的雲端硬碟,便於快速擴充。
當PV被動態建立出來,PV對應的YAML中會包含PV所在節點上的可用性區域資訊。此PV以及關聯的PVC只能在節點的可用性區域內進行調度,不會被調度到可用性區域之外,以此來確保Pod能掛載成功。
相關文檔
如果您需要加強雲端硬碟儲存資料的安全性,請參見雲端硬碟儲存資料安全最佳實務。
如果您需要即時瞭解雲端硬碟的使用方式,請參見容器儲存監控概述。
如果您的雲端硬碟大小不滿足要求或磁碟已滿,請參見擴容雲端硬碟儲存卷。
如果您還有其他雲端硬碟掛載的問題,請參見雲端硬碟儲存卷FAQ。