跳至内容

如何使用 Amazon EBS 多重挂载将同一个卷附加到 Amazon EKS 中的多个工作负载?

3 分钟阅读
0

我想使用 Amazon Elastic Block Store(Amazon EBS)多重挂载来处理 Amazon Elastic Kubernetes Service(Amazon EKS)中跨多个集群的多个工作负载。

简述

Amazon EBS 多重挂载允许您将单个预调配 IOPS SSD(io1 或 io2)卷挂载到同一可用区中的多个实例。您可以使用多重挂载在不同 Amazon EKS 集群中的多个工作负载之间共享永久存储。

解决方法

注意: 如果您在运行 AWS 命令行界面(AWS CLI)命令时收到错误,请参阅排查 AWS CLI 错误。此外,请确保您使用的是最新版本的 AWS CLI。

重要信息: 诸如 XFS 和 EXT4 之类的标准文件系统并非为多个服务器同时访问而设计。请使用已加入集群的文件系统,为您的生产工作负载提供数据弹性和可靠性。

在开始之前,请确保在所需的 Amazon EKS 集群中安装 Amazon EBS CSI 驱动程序。

有关安装 Amazon EBS CSI 驱动程序的更多信息,请参阅将 Kubernetes 卷存储与 Amazon EBS 结合使用。

注意: 可以将启用多重挂载的卷挂载至最多 16 个 Linux 实例,这些实例基于 Nitro 系统而构建且位于同一可用区内。

要使用 Amazon EBS 多重挂载将同一个卷挂载到多个集群中的多个工作负载,请完成以下步骤:

预调配 Amazon EBS 卷

运行以下 AWS CLI 命令 create-volume:

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 替换为所需的可用区。

重要信息: 如果 io2 卷未挂载到实例,则可以在创建 io2 卷后为其启用 Amazon EBS 多重挂载。创建 io1 卷后,无法为其开启 Amazon EBS 多重挂载。

检索卷 ID

运行以下 AWS CLI 命令 describe-volumes:

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

注意: 将 example-region 替换为所需的 AWS 区域。

创建存储类别

使用以下配置创建存储类别清单:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: io2
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
  type: io2
  iops: "2000"

应用存储类别:

kubectl apply -f storageclass.yaml

在集群 A 中预置持久性工作负载

创建以下清单并命名为 workloadA.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: example-pv-claim-name-a
spec:
  storageClassName: io2
  volumeName: example-pv-name-a
  accessModes:
    - ReadWriteMany
  volumeMode: Block
  resources:
    requests:
      storage: 10Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: example-pod-a
spec:
  containers:
    - name: <example-pod-container-name>
      image: centos:6.6
      command: ["/bin/sh"]
      args: ["-c", "while true; do echo $(date -u) on pod A >> /data/out.txt; sleep 15; done"]
      volumeDevices:
        - name: example-volume-device-name
          devicePath: "/dev/xvda"
  volumes:
    - name: example-volume-device-name
      persistentVolumeClaim:
        claimName: example-pv-claim-name-a
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv-name-a
spec:
  storageClassName: io2
  volumeMode: Block
  accessModes:
    - ReadWriteMany
  capacity:
    storage: 10Gi
  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

注意: 请将清单中的所有示例字符串替换为所需的值。

使用相同的卷 ID 在集群 B 中创建另一个工作负载

创建以下清单并命名为 workloadB.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: example-pv-claim-name-b
spec:
  storageClassName: io2
  volumeName: example-pv-name-b
  accessModes:
    - ReadWriteMany
  volumeMode: Block
  resources:
    requests:
      storage: 10Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: example-pod-b
spec:
  containers:
    - name: example-pod-container-name
      image: centos:6.6
      command: ["/bin/sh"]
      args: ["-c", "while true; do echo $(date -u) on pod B >> /data/out.txt; sleep 15; done"]
      volumeDevices:
        - name: example-volume-device-name
          devicePath: "/dev/xvda"
  volumes:
    - name: example-volume-device-name
      persistentVolumeClaim:
        claimName: example-pv-claim-name-b
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv-name-b
spec:
  storageClassName: io2
  volumeMode: Block
  accessModes:
    - ReadWriteMany
  capacity:
    storage: 10Gi
  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

注意: 请将所有示例字符串替换为所需的值。

将 kubectl 上下文切换到集群 B,然后部署工作负载:

kubectl config use-context example-clusterB-context
kubectl apply -f workloadB.yaml

注意: 请将 example-clusterB-context 替换为您的集群 B 上下文。

验证容器组(pod)是否正在运行且内容是否相同

在不同的集群上进行身份验证并运行以下命令:

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

对于 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

对于 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

相关信息

使用多重挂载将 EBS 卷附加到多个 EC2 实例

为 Amazon EBS 卷启用多重挂载

将 Kubernetes 卷存储与 Amazon EBS 结合使用

什么是 Amazon Elastic File System?