本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

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 zonezones 參數不再需要指定,因為 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)。