磁碟區排程

概觀

DirectPV 為 Pod 提供磁碟機,這些 Pod 為 DirectPV 儲存類別提供 PersistentVolumeClaim

DirectPV 包含一個名為 directpv-min-io 的儲存類別,其 磁碟區繫結模式WaitForFirstConsumer。此模式會延遲磁碟區繫結和 PersistentVolume 的佈建,直到使用 PersistentVolumeClaim 建立 Pod 為止。然後,DirectPV 會選取或佈建符合 Pod 排程限制中指定拓撲的 PersistentVolumes。

磁碟區限制

Pod 可能包含 PersistentVolumeClaim 的額外限制。DirectPV 會選取和佈建符合 Pod 排程限制指定拓撲的 Persistent Volumes。

排程限制的一些範例如下

  • 資源需求,例如容量
  • 節點選取器
  • Pod 親和性和反親和性
  • 污點和容忍度

磁碟機選擇

以下順序和流程圖顯示 DirectPV CSI 控制器如何為 CreateVolume 請求選取合適的磁碟機。

  1. 驗證請求中的檔案系統類型是否為 xfs。DirectPV 僅支援 xfs 檔案系統。

  2. 驗證請求中的任何存取層。

  3. 檢查 DirectPVDrive CRD 物件中是否存在請求的磁碟區。如果存在,DirectPV 會排程包含磁碟區的第一個磁碟機。

  4. 如果沒有 DirectPVDrive CRD 物件具有請求的磁碟區,DirectPV 會依下列條件檢查每個磁碟機:

    • 要求的容量
    • 存取層(如果要求)
    • 拓撲限制(如果要求)
  5. 如果此程序選取多個磁碟機,DirectPV 會選取可用容量最大的磁碟機。

  6. 如果有兩個以上的磁碟機具有相同的最大可用容量,DirectPV 會隨機排程選取的其中一個磁碟機。

  7. 使用要求的磁碟區資訊更新已排程的磁碟機。

請注意下列行為

  • 如果沒有磁碟機符合,DirectPV 會傳回錯誤。
  • 發生錯誤時,Kubernetes 會重試請求。
  • 當兩個或多個並行請求排程同一個磁碟機時,該磁碟機只會成功排程給其中一個請求。所有其他請求將會失敗並重試。

Flowchart of the decision tree to schedule a drive

自訂磁碟機選擇

DirectPV 提供幾種方法來控制磁碟機的選擇。這些方法包括:

  • 節點選取器
  • Pod 親和性和反親和性
  • 污點和容忍度

除了這些方法之外,DirectPV 還可以使用磁碟機標籤,透過自訂的儲存類別來選取特定的磁碟機以進行磁碟區排程。

  • 使用label drives 命令來標記所選的磁碟機。

    # Label the 'nvme1n1' drive in all nodes as 'fast' with the 'tier' key.
    kubectl directpv label drives --drives=nvme1n1 tier=fast
    
  • 使用 create-storage-class.sh 腳本建立具有磁碟機標籤的新儲存類別。

    # Create new storage class 'fast-tier-storage' with drive labels 'directpv.min.io/tier: fast'
    create-storage-class.sh fast-tier-storage 'directpv.min.io/tier: fast'
    
  • 磁碟區配置中使用新建立的儲存類別。

    $ kubectl apply -f - <<EOF
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: sleep-pvc
    spec:
      volumeMode: Filesystem
      storageClassName: fast-tier-storage
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 8Mi
    EOF
    

獨特的磁碟機選擇

預設基於可用容量的磁碟機選擇方式,可能會導致在 StatefulSet 部署中於單一磁碟機上分配多個磁碟區。這種選擇方式對於像 MinIO 物件儲存這樣的應用程式而言,缺乏效能和高可用性。

為了克服這種情況,DirectPV 提供了一種方法,讓每個磁碟機僅分配一個磁碟區。要使用此功能,請以 directpv.min.io/volume-claim-id 格式建立帶有標籤的自訂儲存類別

以下是使用 create-storage-class.sh 腳本建立自訂儲存類別的範例:

create-storage-class.sh tenant-1-storage 'directpv.min.io/volume-claim-id: 555e99eb-e255-4407-83e3-fc443bf20f86'

這個自訂儲存類別必須在您的 StatefulSet 部署中使用。以下是部署 MinIO 物件儲存的範例:

kind: Service
apiVersion: v1
metadata:
  name: minio
  labels:
    app: minio
spec:
  selector:
    app: minio
  ports:
    - name: minio
      port: 9000

---

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: minio
  labels:
    app: minio
spec:
  serviceName: "minio"
  replicas: 2
  selector:
    matchLabels:
      app: minio
  template:
    metadata:
      labels:
        app: minio
        directpv.min.io/organization: minio
        directpv.min.io/app: minio-example
        directpv.min.io/tenant: tenant-1
    spec:
      containers:
      - name: minio
        image: minio/minio
        env:
        - name: MINIO_ACCESS_KEY
          value: minio
        - name: MINIO_SECRET_KEY
          value: minio123
        volumeMounts:
        - name: minio-data-1
          mountPath: /data1
        - name: minio-data-2
          mountPath: /data2
        args:
        - "server"
        - "http://minio-{0...1}.minio.default.svc.cluster.local:9000/data{1...2}"
  volumeClaimTemplates:
  - metadata:
      name: minio-data-1
    spec:
      storageClassName: tenant-1-storage
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 16Mi
  - metadata:
      name: minio-data-2
    spec:
      storageClassName: tenant-1-storage
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 16Mi