本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
Kubernetes 中的拓撲感知卷配置
在 Kubernetes 1.12 中,具有持續性卷的多區域叢集體驗正在透過拓撲感知動態佈建 Beta 功能得到改進。此功能允許 Kubernetes 在動態佈建卷時做出明智的決策,方法是從排程器取得關於 Pod 最佳佈建卷位置的輸入。在多區域叢集中,這表示卷將在可以運行 Pod 的適當區域中佈建,讓您可以輕鬆地跨故障域部署和擴展有狀態工作負載,以提供高可用性和容錯能力。
先前的挑戰
在此功能之前,在多區域叢集中使用區域持續性磁碟(例如 AWS ElasticBlockStore、Azure Disk、GCE PersistentDisk)運行有狀態工作負載面臨許多挑戰。動態佈建與 Pod 排程無關地處理,這表示只要您建立 PersistentVolumeClaim (PVC),就會佈建卷。這表示佈建程式不知道哪些 Pod 正在使用卷,以及它可能影響排程的任何 Pod 約束。
這導致 Pod 無法排程,因為卷佈建在以下區域中:
- 沒有足夠的 CPU 或記憶體資源來運行 Pod
- 與節點選擇器、Pod 親和性或反親和性策略衝突
- 由於污點而無法運行 Pod
另一個常見問題是,使用多個持續性卷的非 StatefulSet Pod 可能會在不同區域中佈建每個卷,再次導致 Pod 無法排程。
次佳的解決方案包括過度佈建節點,或在正確區域中手動建立卷,這使得動態部署和擴展有狀態工作負載變得困難。
拓撲感知動態佈建功能解決了上述所有問題。
支援的卷類型
在 1.12 版本中,以下驅動程式支援拓撲感知動態佈建
- AWS EBS
- Azure Disk
- GCE PD(包括區域 PD)
- CSI (Alpha) - 目前只有 GCE PD CSI 驅動程式實作了拓撲支援
設計原則
雖然最初支援的外掛程式集都是基於區域的,但我們設計此功能是為了遵守 Kubernetes 跨環境的可移植性原則。拓撲規範已通用化,並使用類似於 Pod 節點選擇器和節點親和性的基於標籤的規範。此機制允許您定義自己的拓撲邊界,例如內部部署叢集中的機架,而無需修改排程器來理解這些自訂拓撲。
此外,拓撲資訊從 Pod 規範中抽象出來,因此 Pod 不需要了解底層儲存系統的拓撲特性。這表示您可以在多個叢集、環境和儲存系統中使用相同的 Pod 規範。
開始使用
若要啟用此功能,您只需建立一個 volumeBindingMode
設定為 WaitForFirstConsumer
的 StorageClass
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: topology-aware-standard
provisioner: kubernetes.io/gce-pd
volumeBindingMode: WaitForFirstConsumer
parameters:
type: pd-standard
此新設定指示卷佈建程式不要立即建立卷,而是等待使用相關 PVC 的 Pod 完成排程。請注意,先前的 StorageClass zone
和 zones
參數不再需要指定,因為 Pod 策略現在驅動在哪個區域佈建卷的決策。
接下來,使用此 StorageClass 建立 Pod 和 PVC。此順序與以前相同,但在 PVC 中指定了不同的 StorageClass。以下是一個假設範例,透過指定許多 Pod 約束和排程策略來示範新功能的功能
- Pod 中的多個 PVC
- 跨區域子集的節點親和性
- 區域上的 Pod 反親和性
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: failure-domain.beta.kubernetes.io/zone
operator: In
values:
- us-central1-a
- us-central1-f
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: failure-domain.beta.kubernetes.io/zone
containers:
- name: nginx
image: gcr.io/google_containers/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
- name: logs
mountPath: /logs
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: topology-aware-standard
resources:
requests:
storage: 10Gi
- metadata:
name: logs
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: topology-aware-standard
resources:
requests:
storage: 1Gi
之後,您可以看到卷已根據 Pod 設定的策略在區域中佈建
$ kubectl get pv -o=jsonpath='{range .items[*]}{.spec.claimRef.name}{"\t"}{.metadata.labels.failure\-domain\.beta\.kubernetes\.io/zone}{"\n"}{end}'
www-web-0 us-central1-f
logs-web-0 us-central1-f
www-web-1 us-central1-a
logs-web-1 us-central1-a
如何了解更多資訊?
拓撲感知動態佈建功能的官方文件可在此處取得
CSI 驅動程式的文件可在 https://kubernetes-csi.github.io/docs/ 取得
下一步是什麼?
我們正在積極改進此功能以支援
- 更多卷類型,包括本機卷的動態佈建
- 每個節點的動態卷可連接計數和容量限制
如何參與?
如果您對此功能有任何意見回饋,或有興趣參與設計和開發,請加入 Kubernetes 儲存特別興趣小組 (SIG)。我們正在快速成長,並隨時歡迎新的貢獻者。
特別感謝所有協助將此功能帶入 Beta 版的貢獻者,包括 Cheng Xing (verult)、Chuqiang Li (lichuqiang)、David Zhu (davidz627)、Deep Debroy (ddebroy)、Jan Šafránek (jsafrane)、Jordan Liggitt (liggitt)、Michelle Au (msau42)、Pengfei Ni (feiskyer)、Saad Ali (saad-ali)、Tim Hockin (thockin) 和 Yecheng Fu (cofyc)。