跳至內容

如何使用 Amazon EBS Multi-Attach 將同一個磁碟區掛載到 Amazon EKS 中的多個工作負載?

3 分的閱讀內容
0

我想要使用 Amazon Elastic Block Store (Amazon EBS) Multi-Attach 來處理 Amazon Elastic Kubernetes Service (Amazon EKS) 中跨多個叢集的多個工作負載。

簡短說明

當您在 Amazon EKS 中使用 Amazon EBS 儲存體建立永續性工作負載時,預設的磁碟區類型為 gp2。Amazon EBS Multi-Attach 允許您將單一個佈建 IOPS SSD (io1 或 io2) 磁碟區掛載到同一可用區域內的多個執行個體。

Amazon EBS Multi-Attach不支援一般用途 SSD 磁碟區,如 gp2 和 gp3。Amazon EBS CSI 驅動程式不支援將磁碟區多重掛載到同一叢集內不同節點上執行的工作負載。

若要將同一個 Amazon EBS 永續性儲存體多重掛載到不同叢集中的多個工作負載,請使用佈建 IOPS SSD 磁碟區。確保 Pod 在跨叢集的相同可用區域 (AZ) 工作節點上執行。

**注意:**如果您的工作負載分布於同一或不同叢集的多個可用區域,請使用 Amazon Elastic File System (Amazon EFS)。如需更多資訊,請參閱 GitHub 網站上的為 Amazon EKS 建立 Amazon EFS 檔案系統

解決方法

在開始之前,請確保在所需的 Amazon EKS 叢集中已安裝 Amazon EBS CSI 驅動程式。
**注意:**啟用 Multi-Attach 的磁碟區最多可掛載到同一可用區域內,以 Nitro 系統為基礎的 16 個 Linux 執行個體。

若要使用 Amazon EBS Multi-Attach 將相同磁碟區掛載到多個叢集的多個工作負載,請完成以下步驟。

佈建 Amazon EBS 磁碟區

若要佈建 Amazon EBS 磁碟區,請執行以下操作:

  1. 靜態佈建磁碟區:
    aws ec2 create-volume --volume-type io2 --multi-attach-enabled --size 10 --iops 2000 --region <example-region> --availability-zone <example-az> --tag-specifications 'ResourceType=volume,Tags=[{Key=purpose,Value=prod},{Key=Name,Value=multi-attach-eks}]'
    **注意:**將 <example-region> 替換為您所需的 AWS 區域。將 <example-az> 替換為您所需的可用區域。
  2. 如果您已有帶有 gp2 或 gp3 磁碟區的現有工作負載,請先建立該磁碟區的快照。然後,從該快照建立 io2 磁碟區。 
    **注意:**io1 磁碟區在建立後無法啟用 Amazon EBS Multi-Attach。如果 io2 磁碟區未掛載到任何執行個體,則可在建立後啟用 Amazon EBS Multi-Attach。在 Amazon EKS 中使用 io2 動態儲存體佈建時,請指定 Immediate (立即) 模式,以在沒有 Pod 的情況下佈建磁碟區並建立儲存類別。確保在建立 Pod 之前已開啟 Amazon EBS Multi-Attach。

檢索磁碟區 ID

檢索為工作負載佈建的磁碟區 ID:

aws ec2 describe-volumes --filters "Name=tag:Name,Values=multi-attach-eks*" --query "Volumes[*].{ID:VolumeId}" --region <example-region>  

**注意:**將 example-region 替換為所需的 AWS 區域。

使用上述磁碟區 ID 在現有叢集上佈建永續性工作負載

  1. 建立以下名為 workloadA.yml 的資訊清單:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: <example-pv-claim-name-a>
    spec:
      storageClassName: ""
      volumeName: <example-pv-name-a>
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 5Gi
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: <example-pod-a>
    spec:
      containers:
      - name: <example-pod-container-name>
        image: centos
        command: ["/bin/sh"]
        args: ["-c", "while true; do echo $(date -u) on pod A >> /data/out.txt; sleep 15; done"]
        volumeMounts:
        - name: <example-volume-mount-name>
          mountPath: /data
      volumes:
      - name: <example-volume-mount-name>
        persistentVolumeClaim:
          claimName: <example-pv-claim-name-a>
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: <example-pv-name-a>
    spec:
      accessModes:
      - ReadWriteOnce
      capacity:
        storage: 5Gi
      csi:
        driver: ebs.csi.aws.com
        fsType: ext4
        volumeHandle: <example-preceding-volume-id>
      nodeAffinity:
        required:
          nodeSelectorTerms:
            - matchExpressions:
                - key: topology.ebs.csi.aws.com/zone
                  operator: In
                  values:
                    - <example-az>

    **注意:**將以下命令中所有的 example 字串替換為您所需的值。確保 storageClassName 參數值設為空的 ****"" 字串。

  2. 切換 kubectl 上下文至叢集 A,然後部署工作負載:

    kubectl config use-context <example-clusterA-context>  
    kubectl apply -f workloadA.yml

使用上述磁碟區 ID 在另一叢集中建立另一工作負載

  1. 建立並部署以下名為 workloadB.yml 的資訊清單:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: <example-pv-claim-name-b>
    spec:
      storageClassName: ""
      volumeName: <example-pv-name-b>
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 5Gi
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: <example-pod-b>
    spec:
      containers:
      - name: <example-pod-container-name>
        image: centos
        command: ["/bin/sh"]
        args: ["-c", "tail -f /data/out.txt"]
        volumeMounts:
        - name: <example-volume-mount-name>
          mountPath: /data
      volumes:
      - name: <example-volume-mount-name>
        persistentVolumeClaim:
          claimName: <example-pv-claim-name-b>
    
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: <example-pv-name-b>
    spec:
      accessModes:
      - ReadWriteOnce
      capacity:
        storage: 5Gi
      csi:
        driver: ebs.csi.aws.com
        fsType: ext4
        volumeHandle: <example-preceding-volume-id>
      nodeAffinity:
        required:
          nodeSelectorTerms:
            - matchExpressions:
                - key: topology.ebs.csi.aws.com/zone
                  operator: In
                  values:
                    - example-az

    **注意:**將所有 example 字串替換為您所需的值。確保 storageClassName 參數值設為空的 ****"" 字串。

  2. 切換 kubectl 上下文至叢集 B,然後部署工作負載:

    kubectl config use-context <example-clusterB-context>
    kubectl apply -f workloadB.ym

    注意: 將 example-clusterB-context 替換為您的上下文。

檢查 Pod 是否在執行,並具有相同內容

  1. 在不同叢集中進行驗證並執行以下命令:

    kubectl get pods

    叢集 A 的範例輸出結果:

    NAME                          READY   STATUS    RESTARTS   AGE
    example-pod-a                 1/1     Running   0          18m  

    叢集 B 的範例輸出結果:

    NAME                          READY   STATUS    RESTARTS   AGE
    example-pod-b                 1/1     Running   0          3m13s
  2. 對於 example-pod-a,執行下列命令以查看寫入儲存體的內容:

    kubectl exec -it <example-pod-a> -- cat /data/out.txt

    範例輸出結果:

    Fri Sep 22 12:39:04 UTC 2024 on example-pod-a  
    Fri Sep 22 12:39:19 UTC 2024 on example-pod-a  
    Fri Sep 22 12:39:34 UTC 2024 on example-pod-a
  3. 對於 example-pod-b,執行以下命令以讀取與 example-pod-a 寫入相同儲存體中的內容:

    kubectl logs -f <example-pod-b>

    範例輸出結果:

    Fri Sep 22 12:39:04 UTC 2024 on example-pod-b  
    Fri Sep 22 12:39:19 UTC 2024 on example-pod-b  
    Fri Sep 22 12:39:34 UTC 2024 on example-pod-b

**注意:**標準檔案系統 (如 XFS 和 EXT4) 無法同時從多台伺服器存取。如需更多資訊,請參閱注意事項與限制

相關資訊

什麼是 Amazon Elastic File System?