

 **帮助改进此页面** 

要帮助改进本用户指南，请选择位于每个页面右侧窗格中的**在 GitHub 上编辑此页面**链接。

# 使用集群的应用程序数据存储
<a name="storage"></a>

您可以在 Amazon EKS 中使用多种 AWS 存储服务，来满足应用程序的存储需求。通过由 AWS 支持的各种容器存储接口（CSI）驱动程序，您可以轻松使用 Amazon EBS、Amazon S3、Amazon EFS、Amazon FSX 和 Amazon File Cache 来满足 Amazon EKS 上所运行应用程序的存储需求。要管理 Amazon EKS 集群的备份，请参阅 [Amazon EKS 的 AWS 备份支持](https://docs.aws.amazon.com/aws-backup/latest/devguide/working-with-supported-services.html#working-with-eks)。

本章介绍 Amazon EKS 集群的存储选项。

**Topics**
+ [

# 将 Kubernetes 卷存储与 Amazon EBS 结合使用
](ebs-csi.md)
+ [

# 将弹性文件系统存储与 Amazon EFS 结合使用
](efs-csi.md)
+ [

# 将高性能应用程序存储与适用于 Lustre 的 Amazon FSx 结合使用
](fsx-csi.md)
+ [

# 将适用于 NetApp ONTAP 的 FSx 与高性能应用程序存储结合使用
](fsx-ontap.md)
+ [

# 将适用于 OpenZFS 的 Amazon FSx 与数据存储结合使用
](fsx-openzfs-csi.md)
+ [

# 使用 Amazon File Cache 减少延迟
](file-cache-csi.md)
+ [

# 使用适用于 Amazon S3 的 Mountpoint CSI 驱动程序访问适用于 Amazon S3 对象
](s3-csi.md)
+ [

# 为 CSI 卷启用快照功能
](csi-snapshot-controller.md)

# 将 Kubernetes 卷存储与 Amazon EBS 结合使用
<a name="ebs-csi"></a>

**注意**  
 **新增：**Amazon EKS 自动模式可自动执行块存储例行任务。了解如何[将示例有状态工作负载部署到 EKS 自动模式](sample-storage-workload.md)。

[Amazon Elastic Block Store（Amazon EBS）Container Storage Interface（CSI）驱动程序](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/)管理作为您所创建 Kubernetes 卷存储的 Amazon EBS 卷的生命周期。Amazon EBS CSI 驱动程序为以下类型的 Kubernetes 卷制作 Amazon EBS 卷：通用[临时卷](https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/)和[持久性卷](https://kubernetes.io/docs/concepts/storage/persistent-volumes/)。

## 注意事项
<a name="ebs-csi-considerations"></a>
+ 您无需在 EKS 自动模式集群上安装 Amazon EBS CSI 控制器。
+ 您无法将 Amazon EBS 卷挂载到 Fargate 容器组（pod）。
+ 您可以在 Fargate 节点上运行 Amazon EBS CSI 控制器，但要在 Amazon EBS CSI 节点 `DaemonSet` 只能在 Amazon EC2 实例上运行。
+ Amazon EBS 卷和 Amazon EBS CSI 驱动程序与 Amazon EKS 混合节点功能不兼容。
+ 将为最新的附加组件版本和一个先前版本提供支持。在最新版本中发现的错误或漏洞将在新的次要版本中向后移植到先前的版本。
+ EKS 自动模式需要存储类使用 `ebs.csi.eks.amazonaws.com` 作为置备程序。标准 Amazon EBS CSI 驱动程序 (`ebs.csi.aws.com`) 单独管理自己的卷。要在 EKS 自动模式下使用现有卷，请使用卷快照将其迁移到使用自动模式置备程序的存储类。

**重要**  
要使用 Amazon EBS CSI 驱动程序的快照功能，必须先安装 CSI 快照控制器。有关更多信息，请参阅 [为 CSI 卷启用快照功能](csi-snapshot-controller.md)。

## 先决条件
<a name="ebs-csi-prereqs"></a>
+ 现有集群。要查看所需的平台版本，请运行以下命令。

  ```
  aws eks describe-addon-versions --addon-name aws-ebs-csi-driver
  ```
+ EBS CSI 驱动程序需要 AWS IAM 权限。
  +  AWS 建议使用 EKS 容器组身份。有关更多信息，请参阅 [EKS 容器组身份设置概述](pod-identities.md#pod-id-setup-overview)。
  + 有关服务账户 IAM 角色的信息，请参阅[为集群创建 IAM OIDC 提供商](enable-iam-roles-for-service-accounts.md)。

## 第 1 步：创建 IAM 角色
<a name="csi-iam-role"></a>

Amazon EBS CSI 插件需要 IAM 权限才能代表您调用 AWS API。如果您未完成这些步骤，则在尝试安装附加组件并运行 `kubectl describe pvc` 时，将会显示 `failed to provision volume with StorageClass` 以及 `could not create volume in EC2: UnauthorizedOperation` 错误。有关更多信息，请参阅 GitHub 上的[设置驱动程序权限](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/docs/install.md#set-up-driver-permissions)。

**注意**  
容器组（pod）将有权访问分配给 IAM 角色的权限，除非您阻止对 IMDS 的访问。有关更多信息，请参阅 [使用最佳实践保护 Amazon EKS 集群](security-best-practices.md)。

以下过程为您演示了如何创建 IAM 角色并向其附加 AWS 托管策略。要实现此过程，可以使用以下过程之一：
+  [`eksctl`](#eksctl_store_app_data) 
+  [AWS 管理控制台](#console_store_app_data) 
+  [AWS CLI](#awscli_store_app_data) 

**注意**  
您可创建一项权限范围最小化的自主管理型策略。审阅 [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEBSCSIDriverPolicy.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEBSCSIDriverPolicy.html) 并创建一项权限精简的自定义 IAM 策略。

**注意**  
此过程中的具体步骤是为将驱动程序用作 Amazon EKS 附加组件而编写的。要将驱动程序用作自行管理的附加组件，需要遵循不同的步骤。有关更多信息，请参阅 GitHub 上的 [Set up driver permissions](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/docs/install.md#set-up-driver-permissions)。

### `eksctl`
<a name="eksctl_store_app_data"></a>

1. 创建 IAM 角色并附加到策略。AWS 维护 AWS 托管策略，或者您可创建自己的自定义策略。您可以使用以下命令创建 IAM 角色并将 AWS 托管策略附加到其上。将 *my-cluster* 替换为您的集群的名称。此命令将部署 AWS CloudFormation 堆栈，该堆栈将创建 IAM 角色，并会将 IAM 策略附加到该堆栈。

   ```
   eksctl create iamserviceaccount \
           --name ebs-csi-controller-sa \
           --namespace kube-system \
           --cluster my-cluster \
           --role-name AmazonEKS_EBS_CSI_DriverRole \
           --role-only \
           --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
           --approve
   ```

1. 如果您不使用自定义 [KMS 密钥](https://aws.amazon.com/kms/)，可以跳过此步骤。如果在 Amazon EBS 卷上使用一个密钥进行加密，请根据需要自定义 IAM 角色。例如，执行以下操作：

   1. 复制并在新的 `kms-key-for-encryption-on-ebs.json` 文件中粘贴以下代码。将 *custom-key-arn* 替换为自定义 [KMS 密钥 ARN](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awskeymanagementservice.html#awskeymanagementservice-key)。

      ```
      {
            "Version":"2012-10-17",		 	 	 
            "Statement": [
              {
                "Effect": "Allow",
                "Action": [
                  "kms:CreateGrant",
                  "kms:ListGrants",
                  "kms:RevokeGrant"
                ],
                "Resource": ["arn:aws:kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab"],
                "Condition": {
                  "Bool": {
                    "kms:GrantIsForAWSResource": "true"
                  }
                }
              },
              {
                "Effect": "Allow",
                "Action": [
                  "kms:Encrypt",
                  "kms:Decrypt",
                  "kms:ReEncrypt*",
                  "kms:GenerateDataKey*",
                  "kms:DescribeKey"
                ],
                "Resource": ["arn:aws:kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab"]
              }
            ]
          }
      ```

   1. 创建策略。您可以将 *KMS\$1Key\$1For\$1Encryption\$1On\$1EBS\$1Policy* 更改为其它名称。但是，如果更改了名称，请确保在后面的步骤中也进行相应的更改。

      ```
      aws iam create-policy \
            --policy-name KMS_Key_For_Encryption_On_EBS_Policy \
            --policy-document file://kms-key-for-encryption-on-ebs.json
      ```

   1. 使用以下命令将 IAM policy 附加到该角色。请将 *111122223333* 替换为您的账户 ID。

      ```
      aws iam attach-role-policy \
            --policy-arn arn:aws:iam::111122223333:policy/KMS_Key_For_Encryption_On_EBS_Policy \
            --role-name AmazonEKS_EBS_CSI_DriverRole
      ```

### AWS 管理控制台
<a name="console_store_app_data"></a>

1. 通过 https://console.aws.amazon.com/iam/ 打开 IAM 控制台。

1. 在左侧导航窗格中，选择 **Roles**（角色）。

1. 在 **Roles**（角色）页面上，选择 **Create role**（创建角色）。

1. 在 **Select trusted entity**（选择受信任的实体）页面上，请执行以下操作：

   1. 在 **Trusted entity type**（受信任的实体类型）部分中，选择 **Web identity**（Web 身份）。

   1. 对于 **Identity provider**（身份提供商），为您的集群选择 **OpenID Connect provider URL**（OpenID Connect 提供程序 URL）（如 Amazon EKS 中的 **Overview**（概述）下所示）。

   1. 对于 **Audience (受众)**，请选择 `sts.amazonaws.com`。

   1. 选择**下一步**。

1. 在 **Add permissions**（添加权限）页面上，请执行以下操作：

   1. 在 **Filter policies (筛选器策略)** 框中，输入 `AmazonEBSCSIDriverPolicy`。

   1. 选中搜索返回的 `AmazonEBSCSIDriverPolicy` 左侧的复选框。

   1. 选择**下一步**。

1. 在 **Name, review, and create**（命名、查看和创建）页面中，请执行以下操作：

   1. 对于**角色名称**，为角色输入唯一名称，例如 *AmazonEKS\$1EBS\$1CSI\$1DriverRole*。

   1. 在**添加标签（可选）**下，将标签作为键值对附加，以将元数据添加到角色。有关在 IAM 中使用标签的更多信息，请参阅《IAM 用户指南》** 中的[标记 IAM 资源](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags.html)。

   1. 选择**创建角色**。

1. 创建角色后，在控制台中选择角色以将其打开进行编辑。

1. 选择 **Trust relationships**（信任关系）选项卡，然后选择 **Edit trust policy**（编辑信任策略）。

1. 该行看起来类似于以下行：

   ```
   "oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com"
   ```

   在上一行末尾添加逗号，然后在前一行后面添加以下行。将 *region-code* 替换为您的集群所在的 AWS 区域。将 *EXAMPLED539D4633E53DE1B71EXAMPLE* 替换为您的集群的 OIDC 提供者 ID。

   ```
   "oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:kube-system:ebs-csi-controller-sa"
   ```

1. 选择 **Update policy**（更新策略）以完成操作。

1. 如果在 Amazon EBS 卷上使用自定义 [KMS 密钥](https://aws.amazon.com/kms/)进行加密，请根据需要自定义 IAM 角色。例如，执行以下操作：

   1. 在左侧导航窗格中，选择 **Policies（策略）**。

   1. 在**策略**页面上，选择 **Create a policy (创建策略)**。

   1. 在**创建策略**页面上，选择 **JSON** 选项卡。

   1. 将以下代码复制并粘贴到编辑器中，并将 *custom-key-arn* 替换为自定义 [KMS 密钥 ARN](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awskeymanagementservice.html#awskeymanagementservice-key)。

      ```
      {
            "Version":"2012-10-17",		 	 	 
            "Statement": [
              {
                "Effect": "Allow",
                "Action": [
                  "kms:CreateGrant",
                  "kms:ListGrants",
                  "kms:RevokeGrant"
                ],
                "Resource": ["arn:aws:kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab"],
                "Condition": {
                  "Bool": {
                    "kms:GrantIsForAWSResource": "true"
                  }
                }
              },
              {
                "Effect": "Allow",
                "Action": [
                  "kms:Encrypt",
                  "kms:Decrypt",
                  "kms:ReEncrypt*",
                  "kms:GenerateDataKey*",
                  "kms:DescribeKey"
                ],
                "Resource": ["arn:aws:kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab"]
              }
            ]
          }
      ```

   1. 选择**下一步：标签**。

   1. 在 **Add tags (Optional)**（添加标签（可选））页面上，选择 **Next: Review**（下一步：审核）。

   1. 在**名称**中，输入策略的唯一名称（例如，*KMS\$1Key\$1For\$1Encryption\$1On\$1EBS\$1Policy*）。

   1. 选择**创建策略**。

   1. 在左侧导航窗格中，选择 **角色**。

   1. 在控制台中选择 ***AmazonEKS\$1EBS\$1CSI\$1DriverRole*** 以打开它进行编辑。

   1. 从**添加权限**下拉列表中，选择**附加策略**。

   1. 在**筛选策略**框中，输入 *KMS\$1Key\$1For\$1Encryption\$1On\$1EBS\$1Policy*。

   1. 选中搜索中返回的 *KMS\$1Key\$1For\$1Encryption\$1On\$1EBS\$1Policy* 左侧的复选框。

   1. 选择**附加策略**。

### AWS CLI
<a name="awscli_store_app_data"></a>

1. 查看集群的 OIDC 提供者 URL。将 *my-cluster* 替换为您的集群名称。如果命令的输出为 `None`，请查看**先决条件**。

   ```
   aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text
   ```

   示例输出如下。

   ```
   https://oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE
   ```

1. 创建 IAM 角色并向其授予 `AssumeRoleWithWebIdentity` 操作。

   1. 将以下内容复制到名为 `aws-ebs-csi-driver-trust-policy.json` 的文件中。请将 *111122223333* 替换为您的账户 ID。将 *EXAMPLED539D4633E53DE1B71EXAMPLE* 和 *region-code* 替换为上一步中返回的值。

      ```
      {
            "Version":"2012-10-17",		 	 	 
            "Statement": [
              {
                "Effect": "Allow",
                "Principal": {
                  "Federated": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
                },
                "Action": "sts:AssumeRoleWithWebIdentity",
                "Condition": {
                  "StringEquals": {
                    "oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com",
                    "oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:kube-system:ebs-csi-controller-sa"
                  }
                }
              }
            ]
          }
      ```

   1. 创建角色。您可以将 *AmazonEKS\$1EBS\$1CSI\$1DriverRole* 更改为其它名称。如果更改了名称，请确保在后面的步骤中也进行相应的更改。

      ```
      aws iam create-role \
            --role-name AmazonEKS_EBS_CSI_DriverRole \
            --assume-role-policy-document file://"aws-ebs-csi-driver-trust-policy.json"
      ```

1. 附加策略。AWS 维护 AWS 托管策略，或者您可创建自己的自定义策略。使用以下命令以将 AWS 托管策略附加到角色。

   ```
   aws iam attach-role-policy \
         --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
         --role-name AmazonEKS_EBS_CSI_DriverRole
   ```

1. 如果在 Amazon EBS 卷上使用自定义 [KMS 密钥](https://aws.amazon.com/kms/)进行加密，请根据需要自定义 IAM 角色。例如，执行以下操作：

   1. 复制并在新的 `kms-key-for-encryption-on-ebs.json` 文件中粘贴以下代码。将 *custom-key-arn* 替换为自定义 [KMS 密钥 ARN](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awskeymanagementservice.html#awskeymanagementservice-key)。

      ```
      {
            "Version":"2012-10-17",		 	 	 
            "Statement": [
              {
                "Effect": "Allow",
                "Action": [
                  "kms:CreateGrant",
                  "kms:ListGrants",
                  "kms:RevokeGrant"
                ],
                "Resource": ["arn:aws:kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab"],
                "Condition": {
                  "Bool": {
                    "kms:GrantIsForAWSResource": "true"
                  }
                }
              },
              {
                "Effect": "Allow",
                "Action": [
                  "kms:Encrypt",
                  "kms:Decrypt",
                  "kms:ReEncrypt*",
                  "kms:GenerateDataKey*",
                  "kms:DescribeKey"
                ],
                "Resource": ["arn:aws:kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab"]
              }
            ]
          }
      ```

   1. 创建策略。您可以将 *KMS\$1Key\$1For\$1Encryption\$1On\$1EBS\$1Policy* 更改为其它名称。但是，如果更改了名称，请确保在后面的步骤中也进行相应的更改。

      ```
      aws iam create-policy \
            --policy-name KMS_Key_For_Encryption_On_EBS_Policy \
            --policy-document file://kms-key-for-encryption-on-ebs.json
      ```

   1. 使用以下命令将 IAM policy 附加到该角色。请将 *111122223333* 替换为您的账户 ID。

      ```
      aws iam attach-role-policy \
            --policy-arn arn:aws:iam::111122223333:policy/KMS_Key_For_Encryption_On_EBS_Policy \
            --role-name AmazonEKS_EBS_CSI_DriverRole
      ```

现在您已经创建了 Amazon EBS CSI 驱动程序 IAM 角色，可以前往完成下一部分。使用此 IAM 角色部署附加组件后，该附加组件会创建一个名为 `ebs-csi-controller-sa` 的服务账户，并配置为使用该服务账户。服务账户绑定到被分配了所需的 Kubernetes 权限的 Kubernetes `clusterrole`。

## 第 2 步：获取 Amazon EBS CSI 驱动程序
<a name="managing-ebs-csi"></a>

我们建议您通过 Amazon EKS 附加组件来安装 Amazon EBS CSI 驱动程序，从而提高安全性并减少工作量。要将 Amazon EKS 附加组件添加到您的集群，请参阅 [创建 Amazon EKS 附加组件](creating-an-add-on.md)。有关附加组件的更多信息，请参阅 [Amazon EKS 附加组件](eks-add-ons.md)。

**重要**  
在将 Amazon EBS 驱动程序添加为 Amazon EKS 附加组件之前，请确认您的集群上没有安装该驱动程序的自行管理版本。如果安装了这样的版本，请参阅 GitHub 上的 [Uninstalling a self-managed Amazon EBS CSI driver](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/docs/install.md#uninstalling-the-ebs-csi-driver)。

**注意**  
默认情况下，EBS CSI 所使用的 RBAC 角色拥有对节点执行变更操作的权限，以支持其污点移除功能。受限于 Kubernetes RBAC 的机制，该权限同时也允许此角色对集群内的其余节点执行变更操作。Helm 图表中设有一个参数 (`node.serviceAccount.disableMutation`)，可禁用 ebs-csi-node 服务账户的节点变更类 RBAC 权限。启用此参数后，污点移除等驱动功能将无法正常运行。

如果要对 Amazon EBS CSI 驱动程序进行自主管理型安装，请参阅 GitHub 上的 [Installation](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/docs/install.md)。

## 第 3 步：部署示例应用程序
<a name="ebs-sample-app"></a>

您可以部署各种示例应用程序并根据需要对其进行修改。有关更多信息，请参阅 GitHub 上的 [Kubernetes Examples](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/tree/master/examples/kubernetes)。

# 将弹性文件系统存储与 Amazon EFS 结合使用
<a name="efs-csi"></a>

 [Amazon Elastic File System](https://docs.aws.amazon.com/efs/latest/ug/whatisefs.html)（Amazon EFS）提供无服务器的完全弹性文件存储，因此，您无需预置或管理存储容量和性能，即可共享文件数据。[Amazon EFS Container Storage Interface (CSI) 驱动程序](https://github.com/kubernetes-sigs/aws-efs-csi-driver)提供了一个 CSI 接口，允许在AWS上运行的 Kubernetes 集群管理 Amazon EFS 文件系统的生命周期。本主题介绍了如何部署 Amazon EFS CSI 驱动程序到您的 Amazon EKS 集群。

## 注意事项
<a name="efs-csi-considerations"></a>
+ Amazon EFS CSI 驱动程序与基于 Windows 的容器映像不兼容。
+ 不能将持久性卷的[动态预置](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/examples/kubernetes/dynamic_provisioning/README.md)与 Fargate 节点结合使用，但可以使用[静态预置](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/examples/kubernetes/static_provisioning/README.md)。
+  [动态预置](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/examples/kubernetes/dynamic_provisioning/README.md)需要 [1.2](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/CHANGELOG-1.x.md#v12) 或更高版本的驱动程序。您可以在任何支持的 Amazon EKS 集群版本上通过 `1.1` 版本的驱动程序，对持久性卷使用[静态预置](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/examples/kubernetes/static_provisioning/README.md)（请参阅 [Amazon EKS 支持的版本](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)）。
+ 此驱动程序的 [1.3.2](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/CHANGELOG-1.x.md#v132) 版或更高版本支持 Arm64 架构，包括基于 Amazon EC2 Graviton 的实例。
+ 版本 [1.4.2](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/CHANGELOG-1.x.md#v142) 或更高版本的此驱动程序支持使用 FIPS 装载文件系统。
+ 注意 Amazon EFS 的资源配额。例如，可以为每个 Amazon EFS 文件系统创建 1000 个接入点的配额。有关更多信息，请参阅[您无法更改的 Amazon EFS 资源配额](https://docs.aws.amazon.com/efs/latest/ug/limits.html#limits-efs-resources-per-account-per-region)。
+ 从 [2.0.0](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/CHANGELOG-2.x.md#v200) 版本开始，此驱动程序使用 `stunnel` 切换到 `efs-proxy` 进行 TLS 连接。使用 `efs-proxy` 时，它将打开多个线程，其数量等于一加上它正在运行的节点的内核数。
+ Amazon EFS CSI 驱动程序与 Amazon EKS 混合节点功能不兼容。

## 先决条件
<a name="efs-csi-prereqs"></a>
+ Amazon EFS CSI 驱动程序需要 AWS Identity and Access Management（IAM）权限。
  +  AWS 建议使用 EKS 容器组身份。有关更多信息，请参阅 [EKS 容器组身份设置概述](pod-identities.md#pod-id-setup-overview)。
  + 有关服务账户的 IAM 角色以及为您的集群设置 IAM OpenID Connect（OIDC）提供者的信息，请参阅[为集群创建 IAM OIDC 提供商](enable-iam-roles-for-service-accounts.md)。
+ 在您的设备或 AWS CloudShell 上安装和配置 AWS 命令行界面（AWS CLI）的版本 `2.12.3` 或更高版本，或版本 `1.27.160` 或更高版本。要查看当前版本，请使用 `aws --version | cut -d / -f2 | cut -d ' ' -f1`。`yum`、`apt-get` 或适用于 macOS 的 Homebrew 等软件包管理器通常比 AWS CLI 的最新版本落后几个版本。要安装最新版本，请参阅《AWS 命令行界面用户指南》**中的[安装](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)和[使用 aws configure 快速配置](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)。AWS CloudShell 中安装的 AWS CLI 版本也可能比最新版本落后几个版本。要对其进行更新，请参阅《AWS CloudShell 用户指南》**中的[将 AWS CLI 安装到您的主目录](https://docs.aws.amazon.com/cloudshell/latest/userguide/vm-specs.html#install-cli-software)。
+ 您的设备或 AWS CloudShell 上安装了 `kubectl` 命令行工具。该版本可以与集群的 Kubernetes 版本相同，或者最多早于或晚于该版本一个次要版本。例如，如果您的集群版本为 `1.29`，则可以将 `kubectl` 的 `1.28`、`1.29` 或 `1.30` 版本与之配合使用。要安装或升级 `kubectl`，请参阅 [设置 `kubectl` 和 `eksctl`](install-kubectl.md)。

**注意**  
Fargate 上运行的容器组（pod）会自动挂载 Amazon EFS 文件系统，无需手动执行驱动程序安装步骤。

## 第 1 步：创建 IAM 角色
<a name="efs-create-iam-resources"></a>

Amazon EFS CSI 驱动程序需要 IAM 权限才能与您的文件系统进行交互。创建 IAM 角色并向其附加所需的 AWS 托管策略。要实现此过程，可以使用以下过程之一：
+  [`eksctl`](#eksctl_efs_store_app_data) 
+  [AWS 管理控制台](#console_efs_store_app_data) 
+  [AWS CLI](#awscli_efs_store_app_data) 

**注意**  
此过程中的具体步骤是为将驱动程序用作 Amazon EKS 附加组件而编写的。有关自主管理型安装的详细信息，请参阅 GitHub 上的 [Set up driver permission](https://github.com/kubernetes-sigs/aws-efs-csi-driver#set-up-driver-permission)。

### `eksctl`
<a name="eksctl_efs_store_app_data"></a>

#### 如果使用容器组身份
<a name="efs-eksctl-pod-identities"></a>

使用 `eksctl` 运行以下命令以创建 IAM 角色和容器组身份。将 `my-cluster` 替换为您的集群名称。您也可以将 `AmazonEKS_EFS_CSI_DriverRole` 替换为其他名称。

```
export cluster_name=my-cluster
export role_name=AmazonEKS_EFS_CSI_DriverRole
eksctl create podidentityassociation \
    --service-account-name efs-csi-controller-sa \
    --namespace kube-system \
    --cluster $cluster_name \
    --role-name $role_name \
    --permission-policy-arns arn:aws:iam::aws:policy/service-role/AmazonEFSCSIDriverPolicy
```

#### 如果对服务账户使用 IAM 角色
<a name="efs-eksctl-irsa"></a>

使用 `eksctl` 运行以下命令以创建 IAM 角色。将 `my-cluster` 替换为您的集群名称。您也可以将 `AmazonEKS_EFS_CSI_DriverRole` 替换为其他名称。

```
export cluster_name=my-cluster
export role_name=AmazonEKS_EFS_CSI_DriverRole
eksctl create iamserviceaccount \
    --name efs-csi-controller-sa \
    --namespace kube-system \
    --cluster $cluster_name \
    --role-name $role_name \
    --role-only \
    --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEFSCSIDriverPolicy \
    --approve
TRUST_POLICY=$(aws iam get-role --output json --role-name $role_name --query 'Role.AssumeRolePolicyDocument' | \
    sed -e 's/efs-csi-controller-sa/efs-csi-*/' -e 's/StringEquals/StringLike/')
aws iam update-assume-role-policy --role-name $role_name --policy-document "$TRUST_POLICY"
```

### AWS 管理控制台
<a name="console_efs_store_app_data"></a>

使用 AWS 管理控制台 运行以下命令以创建 IAM 角色。

1. 通过 https://console.aws.amazon.com/iam/ 打开 IAM 控制台。

1. 在左侧导航窗格中，选择 **Roles**（角色）。

1. 在 **Roles**（角色）页面上，选择 **Create role**（创建角色）。

1. 在 **Select trusted entity**（选择受信任的实体）页面上，请执行以下操作：

   1. 如果使用 EKS 容器组身份：

      1. 在**可信实体类型**部分中，选择 **AWS 服务**。

      1. 在**服务或应用场景**下拉列表中，选择 **EKS**。

      1. 在**应用场景**部分中，选择 **EKS – 容器组身份**。

      1. 选择**下一步**。

   1. 如果对服务账户使用 IAM 角色：

      1. 在 **Trusted entity type**（受信任的实体类型）部分中，选择 **Web identity**（Web 身份）。

      1. 对于 **Identity provider**（身份提供商），为您的集群选择 **OpenID Connect provider URL**（OpenID Connect 提供程序 URL）（如 Amazon EKS 中的 **Overview**（概述）下所示）。

      1. 对于 **Audience (受众)**，请选择 `sts.amazonaws.com`。

      1. 选择**下一步**。

1. 在 **Add permissions**（添加权限）页面上，请执行以下操作：

   1. 在 **Filter policies (筛选器策略)** 框中，输入 `AmazonEFSCSIDriverPolicy`。

   1. 选中搜索返回的 `AmazonEFSCSIDriverPolicy` 左侧的复选框。

   1. 选择**下一步**。

1. 在 **Name, review, and create**（命名、查看和创建）页面中，请执行以下操作：

   1. 对于 **Role name**（角色名称），请为角色输入唯一名称，例如 `AmazonEKS_EFS_CSI_DriverRole`。

   1. 在**添加标签（可选）**下，将标签作为键值对附加，以将元数据添加到角色。有关在 IAM 中使用标签的更多信息，请参阅《IAM 用户指南》** 中的[标记 IAM 资源](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags.html)。

   1. 选择**创建角色**。

1. 创建角色后：

   1. 如果使用 EKS 容器组身份：

      1. 打开 [Amazon EKS 控制台](https://console.aws.amazon.com/eks/home#/clusters)。

      1. 在左侧导航窗格中，选择**集群**，然后为您要配置 EKS 容器组身份关联的集群选择名称。

      1. 选择**访问**选项卡。

      1. 在**容器组身份关联**中，选择**创建**。

      1. 选择 **IAM 角色**下拉列表，然后选择您新创建的角色。

      1. 选择 **Kubernetes 命名空间**字段并输入 `kube-system`。

      1. 选择 **Kubernetes 服务账户**字段并输入 `efs-csi-controller-sa`。

      1. 选择**创建**。

      1. 有关创建容器组身份关联的更多信息，请参阅[创建容器组身份关联（AWS 控制台）](pod-id-association.md#pod-id-association-create)。

   1. 如果对服务账户使用 IAM 角色：

      1. 选择要打开进行编辑的角色。

      1. 选择 **Trust relationships**（信任关系）选项卡，然后选择 **Edit trust policy**（编辑信任策略）。

      1. 该行看起来类似于以下行：

         ```
         "oidc.eks.region-code.amazonaws.com/id/<EXAMPLED539D4633E53DE1B71EXAMPLE>:aud": "sts.amazonaws.com"
         ```

         将以下行添加到上一行的上方。将 `<region-code>` 替换为集群所在的 AWS 区域。将 `<EXAMPLED539D4633E53DE1B71EXAMPLE>` 替换为集群的 OIDC 提供者 ID。

         ```
         "oidc.eks.<region-code>.amazonaws.com/id/<EXAMPLED539D4633E53DE1B71EXAMPLE>:sub": "system:serviceaccount:kube-system:efs-csi-*",
         ```

      1. 将 `Condition` 运算符从 `"StringEquals"` 修改为 `"StringLike"`。

      1. 选择 **Update policy**（更新策略）以完成操作。

### AWS CLI
<a name="awscli_efs_store_app_data"></a>

使用 AWS CLI 运行以下命令以创建 IAM 角色。

#### 如果使用容器组身份
<a name="efs-cli-pod-identities"></a>

1. 创建向 `pods.eks.amazonaws.com` 服务授予 `AssumeRole` 和 `TagSession` 操作权限的 IAM 角色。

   1. 将以下内容复制到名为 `aws-efs-csi-driver-trust-policy-pod-identity.json` 的文件中。

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "AllowEksAuthToAssumeRoleForPodIdentity",
                  "Effect": "Allow",
                  "Principal": {
                      "Service": "pods.eks.amazonaws.com"
                  },
                  "Action": [
                      "sts:AssumeRole",
                      "sts:TagSession"
                  ]
              }
          ]
      }
      ```

   1. 创建角色。将 `my-cluster` 替换为您的集群名称。您也可以将 `AmazonEKS_EFS_CSI_DriverRole` 替换为其他名称。

      ```
      export cluster_name=my-cluster
      export role_name=AmazonEKS_EFS_CSI_DriverRole
      aws iam create-role \
        --role-name $role_name \
        --assume-role-policy-document file://"aws-efs-csi-driver-trust-policy-pod-identity.json"
      ```

1. 使用以下命令以将所需的 AWS 托管策略附加到角色。

   ```
   aws iam attach-role-policy \
     --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEFSCSIDriverPolicy \
     --role-name $role_name
   ```

1. 运行以下命令以创建容器组身份关联。将 ` arn:aws:iam::<111122223333>:role/my-role` 替换为在之前步骤中创建的角色。

   ```
   aws eks create-pod-identity-association --cluster-name $cluster_name --role-arn {arn-aws}iam::<111122223333>:role/my-role --namespace kube-system --service-account efs-csi-controller-sa
   ```

1. 有关创建容器组身份关联的更多信息，请参阅[创建容器组身份关联（AWS 控制台）](pod-id-association.md#pod-id-association-create)。

#### 如果对服务账户使用 IAM 角色
<a name="efs-cli-irsa"></a>

1. 查看集群的 OIDC 提供者 URL。将 `my-cluster` 替换为您的集群名称。您也可以将 `AmazonEKS_EFS_CSI_DriverRole` 替换为其他名称。

   ```
   export cluster_name=my-cluster
   export role_name=AmazonEKS_EFS_CSI_DriverRole
   aws eks describe-cluster --name $cluster_name --query "cluster.identity.oidc.issuer" --output text
   ```

   示例输出如下。

   ```
   https://oidc.eks.<region-code>.amazonaws.com/id/<EXAMPLED539D4633E53DE1B71EXAMPLE>
   ```

   如果命令的输出为 `None`，请查看**先决条件**。

1. 创建授予 `AssumeRoleWithWebIdentity` 操作权限的 IAM 角色。

   1. 将以下内容复制到名为 `aws-efs-csi-driver-trust-policy.json` 的文件中。请将 `<111122223333>` 替换为您的账户 ID。将 `<EXAMPLED539D4633E53DE1B71EXAMPLE>` 和 `<region-code>` 替换为在上一步中返回的值。

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
              "StringLike": {
                "oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:kube-system:efs-csi-*",
                "oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com"
              }
            }
          }
        ]
      }
      ```

   1. 创建角色。

      ```
      aws iam create-role \
        --role-name $role_name \
        --assume-role-policy-document file://"aws-efs-csi-driver-trust-policy.json"
      ```

1. 使用以下命令以将所需的 AWS 托管策略附加到角色。

   ```
   aws iam attach-role-policy \
     --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEFSCSIDriverPolicy \
     --role-name $role_name
   ```

## 第 2 步：获取 Amazon EFS CSI 驱动程序
<a name="efs-install-driver"></a>

我们建议您通过 Amazon EKS 附加组件方式来安装 Amazon EFS CSI 驱动程序。要将 Amazon EKS 附加组件添加到您的集群，请参阅 [创建 Amazon EKS 附加组件](creating-an-add-on.md)。有关附加组件的更多信息，请参阅 [Amazon EKS 附加组件](eks-add-ons.md)。如果您无法使用 Amazon EKS 附加组件，我们鼓励您向[容器路线图 GitHub 存储库](https://github.com/aws/containers-roadmap/issues)提交有关您为什么无法使用的问题。

**重要**  
在将 Amazon EFS 驱动程序添加为 Amazon EKS 附加组件之前，请确认集群上没有安装该驱动程序的自行管理版本。如果安装了这样的版本，请参阅 GitHub 上的 [Uninstalling the Amazon EFS CSI Driver](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/docs/README.md#uninstalling-the-amazon-efs-csi-driver)。

如果要对 Amazon EFS CSI 驱动程序进行自主管理型安装，请参阅 GitHub 上的 [Installation](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/docs/README.md#installation)。

## 第 3 步：创建 Amazon EFS 文件系统
<a name="efs-create-filesystem"></a>

要创建 Amazon EFS 文件系统，请参阅 GitHub 上的[为 Amazon EKS 创建 Amazon EKS 文件系统](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/docs/efs-create-filesystem.md)。

## 第 4 步：部署示例应用程序
<a name="efs-sample-app"></a>

您可以部署各种示例应用程序并根据需要对其进行修改。有关更多信息，请参阅 GitHub 上的[示例](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/docs/README.md#examples)。

# 将高性能应用程序存储与适用于 Lustre 的 Amazon FSx 结合使用
<a name="fsx-csi"></a>

[Amazon FSx for Lustre Container Storage Interface (CSI) 驱动程序](https://github.com/kubernetes-sigs/aws-fsx-csi-driver)提供了一个 CSI 接口，允许 Amazon EKS 集群管理 Amazon FSx for Lustre 文件系统的生命周期。有关更多信息，请参阅[适用于 Lustre 的 Amazon FSx 用户指南](https://docs.aws.amazon.com/fsx/latest/LustreGuide/what-is.html)。

要详细了解如何将适用于 Lustre 的 Amazon FSx CSI 驱动程序部署到 Amazon EKS 集群并验证其是否起作用，请参阅[部署适用于 Lustre 的 FSx 驱动程序](fsx-csi-create.md)。

# 部署适用于 Lustre 的 FSx 驱动程序
<a name="fsx-csi-create"></a>

本主题演示如何将[适用于 Lustre 的 FSx CSI 驱动程序](fsx-csi.md)部署到 Amazon EKS 集群，以及验证驱动程序是否正常工作。建议使用最新版本的驱动程序。有关可用版本，请参阅 GitHub 上的 [CSI Specification Compatibility Matrix](https://github.com/kubernetes-sigs/aws-fsx-csi-driver/blob/master/docs/README.md#csi-specification-compatibility-matrix)（CSI 规范兼容性矩阵）。

**注意**  
Fargate 或 Amazon EKS 混合节点功能均不支持该驱动程序。

有关可用参数的详细说明和演示驱动程序功能的完整示例，请参阅 GitHub 上的 [FSx for Lustre Container Storage Interface (CSI) driver](https://github.com/kubernetes-sigs/aws-fsx-csi-driver) 项目。

## 先决条件
<a name="fsx-csi-prereqs"></a>
+ 现有集群。
+ Amazon FSx CSI 驱动程序 EKS 附加组件需要 EKS 容器组身份代理进行身份验证。如果没有此组件，附加组件将因错误 `Amazon EKS Pod Identity agent is not installed in the cluster` 而失败，从而无法进行卷操作。在部署 FSx CSI 驱动程序附加组件之前或之后安装容器组身份代理。有关更多信息，请参阅 [设置 Amazon EKS 容器组身份代理](pod-id-agent-setup.md)。
+ 在您的设备或 AWS CloudShell 上安装和配置 AWS 命令行界面（AWS CLI）的版本 `2.12.3` 或更高版本，或版本 `1.27.160` 或更高版本。要查看当前版本，请使用 `aws --version | cut -d / -f2 | cut -d ' ' -f1`。`yum`、`apt-get` 或适用于 macOS 的 Homebrew 等软件包管理器通常比 AWS CLI 的最新版本落后几个版本。要安装最新版本，请参阅《AWS 命令行界面用户指南》**中的[安装](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)和[使用 aws configure 快速配置](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)。AWS CloudShell 中安装的 AWS CLI 版本也可能比最新版本落后几个版本。要对其进行更新，请参阅《AWS CloudShell 用户指南》**中的[将 AWS CLI 安装到您的主目录](https://docs.aws.amazon.com/cloudshell/latest/userguide/vm-specs.html#install-cli-software)。
+ 您的设备或 AWS CloudShell 上安装 `0.215.0` 版或更高版本的 `eksctl` 命令行工具。要安装或更新 `eksctl`，请参阅 `eksctl` 文档中的 [Installation](https://eksctl.io/installation)。
+ 您的设备或 AWS CloudShell 上安装了 `kubectl` 命令行工具。该版本可以与集群的 Kubernetes 版本相同，或者最多早于或晚于该版本一个次要版本。例如，如果您的集群版本为 `1.29`，则可以将 `kubectl` 的 `1.28`、`1.29` 或 `1.30` 版本与之配合使用。要安装或升级 `kubectl`，请参阅 [设置 `kubectl` 和 `eksctl`](install-kubectl.md)。

## 第 1 步：创建 IAM 角色
<a name="fsx-create-iam-role"></a>

Amazon FSx CSI 插件需要 IAM 权限才能代表您调用 AWS API。

**注意**  
容器组（pod）将有权访问分配给 IAM 角色的权限，除非您阻止对 IMDS 的访问。有关更多信息，请参阅 [使用最佳实践保护 Amazon EKS 集群](security-best-practices.md)。

以下过程为您演示了如何创建 IAM 角色并向其附加 AWS 托管策略。

1. 使用以下命令创建 IAM 角色并附加 AWS 托管策略。将 `my-cluster` 替换为您要使用的集群的名称。此命令将部署 AWS CloudFormation 堆栈，该堆栈将创建 IAM 角色，并会将 IAM 策略附加到该堆栈。

   ```
   eksctl create iamserviceaccount \
       --name fsx-csi-controller-sa \
       --namespace kube-system \
       --cluster my-cluster \
       --role-name AmazonEKS_FSx_CSI_DriverRole \
       --role-only \
       --attach-policy-arn arn:aws:iam::aws:policy/AmazonFSxFullAccess \
       --approve
   ```

   创建服务账户时，您将看到几行输出。输出的最后一行类似于以下行。

   ```
   [ℹ]  1 task: {
       2 sequential sub-tasks: {
           create IAM role for serviceaccount "kube-system/fsx-csi-controller-sa",
           create serviceaccount "kube-system/fsx-csi-controller-sa",
       } }
   [ℹ]  building iamserviceaccount stack "eksctl-my-cluster-addon-iamserviceaccount-kube-system-fsx-csi-controller-sa"
   [ℹ]  deploying stack "eksctl-my-cluster-addon-iamserviceaccount-kube-system-fsx-csi-controller-sa"
   [ℹ]  waiting for CloudFormation stack "eksctl-my-cluster-addon-iamserviceaccount-kube-system-fsx-csi-controller-sa"
   [ℹ]  created serviceaccount "kube-system/fsx-csi-controller-sa"
   ```

   记录已部署的 AWS CloudFormation 堆栈的名称。在上面的示例输出中，堆栈的名称为 `eksctl-my-cluster-addon-iamserviceaccount-kube-system-fsx-csi-controller-sa`。

现在您已经创建了 Amazon FSx CSI 驱动程序 IAM 角色，可以前往完成下一部分。使用此 IAM 角色部署附加组件后，该附加组件会创建一个名为 `fsx-csi-controller-sa` 的服务账户，并配置为使用该服务账户。服务账户绑定到被分配了所需的 Kubernetes 权限的 Kubernetes `clusterrole`。

## 第 2 步：安装 Amazon FSx CSI 驱动程序
<a name="fsx-csi-deploy-driver"></a>

我们建议您通过 Amazon EKS 附加组件来安装 Amazon FSx CSI 驱动程序，从而提高安全性并减少工作量。要将 Amazon EKS 附加组件添加到您的集群，请参阅 [创建 Amazon EKS 附加组件](creating-an-add-on.md)。有关附加组件的更多信息，请参阅 [Amazon EKS 附加组件](eks-add-ons.md)。

**重要**  
集群中预先安装的 Amazon FSx CSI 驱动程序可能会导致附加组件安装失败。当您在存在非 EKS FSx CSI 驱动程序的情况下尝试安装 Amazon EKS 附加组件版本时，由于资源冲突，安装将失败。在安装过程中使用 `OVERWRITE` 标志解决此问题。  

```
aws eks create-addon --addon-name aws-fsx-csi-driver --cluster-name my-cluster --resolve-conflicts OVERWRITE
```

如果要对 Amazon FSx CSI 驱动程序进行自主管理型安装，请参阅 GitHub 上的 [Installation](https://github.com/kubernetes-sigs/aws-fsx-csi-driver/blob/master/docs/install.md)。

## 第 3 步：部署存储类、持久卷声明和示例应用程序
<a name="fsx-csi-deploy-storage-class"></a>

此过程利用 [FSx for Lustre Container Storage Interface（CSI）驱动程序](https://github.com/kubernetes-sigs/aws-fsx-csi-driver) GitHub 存储库来使用动态预置的 FSx for Lustre 卷。

1. 注意集群的安全组。您可以在 AWS 管理控制台中的**联网**部分下或通过使用以下 AWS CLI 命令来查看它。将 `my-cluster` 替换为您要使用的集群的名称。

   ```
   aws eks describe-cluster --name my-cluster --query cluster.resourcesVpcConfig.clusterSecurityGroupId
   ```

1. 根据《Amazon FSx for Lustre 用户指南》中的 [Amazon VPC 安全组](https://docs.aws.amazon.com/fsx/latest/LustreGuide/limit-access-security-groups.html#fsx-vpc-security-groups)显示的标准，为您的 Amazon FSx 文件系统创建安全组。对于 **VPC**，选择 **Networking**（联网）部分下显示的集群的 VPC。对于“与 Lustre 客户端关联的安全组”，请使用您的集群安全组。您可以单独保留出站规则以允许**所有流量**。

1. 使用下面的命令下载存储类清单。

   ```
   curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-fsx-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/storageclass.yaml
   ```

1. 编辑 `storageclass.yaml` 文件的参数部分。将所有 example value 替换为您自己的值。

   ```
   parameters:
     subnetId: subnet-0eabfaa81fb22bcaf
     securityGroupIds: sg-068000ccf82dfba88
     deploymentType: PERSISTENT_1
     automaticBackupRetentionDays: "1"
     dailyAutomaticBackupStartTime: "00:00"
     copyTagsToBackups: "true"
     perUnitStorageThroughput: "200"
     dataCompressionType: "NONE"
     weeklyMaintenanceStartTime: "7:09:00"
     fileSystemTypeVersion: "2.12"
   ```
   +  **`subnetId`** – 应在其中创建 Amazon FSx for Lustre 文件系统的子网 ID。并非所有可用区都支持 Amazon FSx for Lustre。打开 https://console.aws.amazon.com/fsx/ 中 Amazon FSx for Lustre 控制台，确认您要使用的子网是否位于支持的可用区中。该子网可以包含您的节点，也可以是不同的子网或 VPC：
     + 您可以通过在 **Compute**（计算）部分下选择节点组来在 AWS 管理控制台 中检查节点子网。
     + 如果您指定的子网不是节点所在的子网，则必须[已连接](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/amazon-vpc-to-amazon-vpc-connectivity-options.html) VPC，并且必须确保已在您的安全组中打开必要的端口。
   +  **`securityGroupIds`** – 您为文件系统创建的安全组的 ID。
   +  **`deploymentType`（可选）**– 文件系统部署类型。有效值为 `SCRATCH_1`、`SCRATCH_2`、`PERSISTENT_1` 和 `PERSISTENT_2`。有关部署类型的更多信息，请参阅[创建 Amazon FSx for Lustre 文件系统](https://docs.aws.amazon.com/fsx/latest/LustreGuide/getting-started-step1.html)。
   +  **其他参数（可选）** – 有关其他参数的信息，请参阅 GitHub 上的[编辑 StorageClass](https://github.com/kubernetes-sigs/aws-fsx-csi-driver/tree/master/examples/kubernetes/dynamic_provisioning#edit-storageclass)。

1. 创建存储类清单。

   ```
   kubectl apply -f storageclass.yaml
   ```

   示例输出如下。

   ```
   storageclass.storage.k8s.io/fsx-sc created
   ```

1. 下载持久卷注册清单。

   ```
   curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-fsx-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/claim.yaml
   ```

1. （可选）编辑 `claim.yaml` 文件。根据您的存储需求和上一步选择的 `deploymentType`，将 `1200Gi` 更改为下面列出的增量值之一。

   ```
   storage: 1200Gi
   ```
   +  `SCRATCH_2` 和 `PERSISTENT` – `1.2 TiB`、`2.4 TiB`，或 2.4TiB 之上 2.4TiB 的增量。
   +  `SCRATCH_1` 和 `1.2 TiB` – `2.4 TiB`、`3.6 TiB`，或 3.6TiB 之上 3.6TiB 的增量。

1. 创建持久卷注册。

   ```
   kubectl apply -f claim.yaml
   ```

   示例输出如下。

   ```
   persistentvolumeclaim/fsx-claim created
   ```

1. 确认已预配置文件系统。

   ```
   kubectl describe pvc
   ```

   示例输出如下。

   ```
   Name:          fsx-claim
   Namespace:     default
   StorageClass:  fsx-sc
   Status:        Bound
   [...]
   ```
**注意**  
`Status` 可能会在 5-10 分钟内显示为 `Pending`，然后才会更改为 `Bound`。在 `Status` 变成 `Bound` 之前，请勿继续执行下一步。如果 `Status` 显示 `Pending` 10 分钟以上，使用 `Events` 中的警告消息作为解决任何问题的参考。

1. 部署示例应用程序。

   ```
   kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-fsx-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/pod.yaml
   ```

1. 验证示例应用程序正在运行。

   ```
   kubectl get pods
   ```

   示例输出如下。

   ```
   NAME      READY   STATUS              RESTARTS   AGE
   fsx-app   1/1     Running             0          8s
   ```

1. 验证应用程序是否正确挂载了文件系统。

   ```
   kubectl exec -ti fsx-app -- df -h
   ```

   示例输出如下。

   ```
   Filesystem                   Size  Used Avail Use% Mounted on
   overlay                       80G  4.0G   77G   5% /
   tmpfs                         64M     0   64M   0% /dev
   tmpfs                        3.8G     0  3.8G   0% /sys/fs/cgroup
   192.0.2.0@tcp:/abcdef01      1.1T  7.8M  1.1T   1% /data
   /dev/nvme0n1p1                80G  4.0G   77G   5% /etc/hosts
   shm                           64M     0   64M   0% /dev/shm
   tmpfs                        6.9G   12K  6.9G   1% /run/secrets/kubernetes.io/serviceaccount
   tmpfs                        3.8G     0  3.8G   0% /proc/acpi
   tmpfs                        3.8G     0  3.8G   0% /sys/firmware
   ```

1. 验证示例应用程序已将数据写入 FSx for Lustre 文件系统。

   ```
   kubectl exec -it fsx-app -- ls /data
   ```

   示例输出如下。

   ```
   out.txt
   ```

   此示例输出显示示例应用程序成功编写了 `out.txt` 文件到文件系统。

**注意**  
删除集群之前，请务必删除 FSx for Lustre 文件系统。有关更多信息，请参阅《适用于 Lustre 的 FSx 用户指南》**中的[清理资源](https://docs.aws.amazon.com/fsx/latest/LustreGuide/getting-started-step4.html)。

## 适用于 Lustre 的 FSx 的性能调整
<a name="_performance_tuning_for_fsx_for_lustre"></a>

在 Amazon EKS 中使用适用于 Lustre 的 FSx 时，您可以通过在节点初始化期间应用 Lustre 调整来优化性能。建议使用启动模板用户数据来确保所有节点的配置一致。

这些调优包括：
+ 网络和 RPC 优化
+ Lustre 模块管理
+ LRU（锁定资源单位）调优：
+ 客户端缓存控制设置
+ OST 和 MDC 的 RPC 控件

有关实现这些性能调优的详细说明：
+ 要优化标准节点（非 EFA）的性能，请参阅[优化节点上的适用于 Lustre 的 Amazon FSx 性能（非 EFA）](fsx-csi-tuning-non-efa.md)，了解可添加到启动模板用户数据的完整脚本。
+ 要优化启用 EFA 的节点的性能，请参阅[优化节点上的适用于 Lustre 的 Amazon FSx 性能（EFA）](fsx-csi-tuning-efa.md)。

# 优化节点上的适用于 Lustre 的 Amazon FSx 性能（EFA）
<a name="fsx-csi-tuning-efa"></a>

本主题介绍如何使用 Amazon EKS 和适用于 Lustre 的 Amazon FSx 设置 Elastic Fabric Adapter（EFA）调优。

**注意**  
有关创建和部署 FSx for Lustre CSI 驱动程序的信息，请参阅[部署适用于 Lustre 的 FSx 驱动程序](fsx-csi-create.md)。
要优化没有 EFA 的标准节点，请参阅[优化节点上的适用于 Lustre 的 Amazon FSx 性能（非 EFA）](fsx-csi-tuning-non-efa.md)。

## 步骤 1：创建 EKS 集群
<a name="create-eks-cluster"></a>

使用提供的配置文件创建一个集群：

```
# Create cluster using efa-cluster.yaml
eksctl create cluster -f efa-cluster.yaml
```

示例：`efa-cluster.yaml`

```
#efa-cluster.yaml

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: csi-fsx
  region: us-east-1
  version: "1.30"

iam:
  withOIDC: true

availabilityZones: ["us-east-1a", "us-east-1d"]

managedNodeGroups:
  - name: my-efa-ng
    instanceType: c6gn.16xlarge
    minSize: 1
    desiredCapacity: 1
    maxSize: 1
    availabilityZones: ["us-east-1b"]
    volumeSize: 300
    privateNetworking: true
    amiFamily: Ubuntu2204
    efaEnabled: true
    preBootstrapCommands:
      - |
        #!/bin/bash
        eth_intf="$(/sbin/ip -br -4 a sh | grep $(hostname -i)/ | awk '{print $1}')"
        efa_version=$(modinfo efa | awk '/^version:/ {print $2}' | sed 's/[^0-9.]//g')
        min_efa_version="2.12.1"

        if [[ "$(printf '%s\n' "$min_efa_version" "$efa_version" | sort -V | head -n1)" != "$min_efa_version" ]]; then
            sudo curl -O https://efa-installer.amazonaws.com/aws-efa-installer-1.37.0.tar.gz
            tar -xf aws-efa-installer-1.37.0.tar.gz && cd aws-efa-installer
            echo "Installing EFA driver"
            sudo apt-get update && apt-get upgrade -y
            sudo apt install -y pciutils environment-modules libnl-3-dev libnl-route-3-200 libnl-route-3-dev dkms
            sudo ./efa_installer.sh -y
            modinfo efa
        else
            echo "Using EFA driver version $efa_version"
        fi

        echo "Installing Lustre client"
        sudo wget -O - https://fsx-lustre-client-repo-public-keys.s3.amazonaws.com/fsx-ubuntu-public-key.asc | gpg --dearmor | sudo tee /usr/share/keyrings/fsx-ubuntu-public-key.gpg > /dev/null
        sudo echo "deb [signed-by=/usr/share/keyrings/fsx-ubuntu-public-key.gpg] https://fsx-lustre-client-repo.s3.amazonaws.com/ubuntu jammy main" > /etc/apt/sources.list.d/fsxlustreclientrepo.list
        sudo apt update | tail
        sudo apt install -y lustre-client-modules-$(uname -r) amazon-ec2-utils | tail
        modinfo lustre

        echo "Loading Lustre/EFA modules..."
        sudo /sbin/modprobe lnet
        sudo /sbin/modprobe kefalnd ipif_name="$eth_intf"
        sudo /sbin/modprobe ksocklnd
        sudo lnetctl lnet configure

        echo "Configuring TCP interface..."
        sudo lnetctl net del --net tcp 2> /dev/null
        sudo lnetctl net add --net tcp --if $eth_intf

        # For P5 instance type which supports 32 network cards,
        # by default add 8 EFA interfaces selecting every 4th device (1 per PCI bus)
        echo "Configuring EFA interface(s)..."
        instance_type="$(ec2-metadata --instance-type | awk '{ print $2 }')"
        num_efa_devices="$(ls -1 /sys/class/infiniband | wc -l)"
        echo "Found $num_efa_devices available EFA device(s)"

        if [[ "$instance_type" == "p5.48xlarge" || "$instance_type" == "p5e.48xlarge" ]]; then
           for intf in $(ls -1 /sys/class/infiniband | awk 'NR % 4 == 1'); do
               sudo lnetctl net add --net efa --if $intf --peer-credits 32
          done
        else
        # Other instances: Configure 2 EFA interfaces by default if the instance supports multiple network cards,
        # or 1 interface for single network card instances
        # Can be modified to add more interfaces if instance type supports it
            sudo lnetctl net add --net efa --if $(ls -1 /sys/class/infiniband | head -n1) --peer-credits 32
            if [[ $num_efa_devices -gt 1 ]]; then
               sudo lnetctl net add --net efa --if $(ls -1 /sys/class/infiniband | tail -n1) --peer-credits 32
            fi
        fi

        echo "Setting discovery and UDSP rule"
        sudo lnetctl set discovery 1
        sudo lnetctl udsp add --src efa --priority 0
        sudo /sbin/modprobe lustre

        sudo lnetctl net show
        echo "Added $(sudo lnetctl net show | grep -c '@efa') EFA interface(s)"
```

## 步骤 2：创建节点组
<a name="create-node-group"></a>

创建一个启用 EFA 的节点组：

```
# Create node group using efa-ng.yaml
eksctl create nodegroup -f efa-ng.yaml
```

**重要**  
=== 在 `# 5. Mount FSx filesystem` 部分中应根据环境调整这些值。

```
FSX_DNS="<your-fsx-filesystem-dns>" # Needs to be adjusted.
MOUNT_NAME="<your-mount-name>" # Needs to be adjusted.
MOUNT_POINT="</your/mount/point>" # Needs to be adjusted.
```

===

示例：`efa-ng.yaml`

```
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: final-efa
  region: us-east-1

managedNodeGroups:
  - name: ng-1
    instanceType: c6gn.16xlarge
    minSize: 1
    desiredCapacity: 1
    maxSize: 1
    availabilityZones: ["us-east-1a"]
    volumeSize: 300
    privateNetworking: true
    amiFamily: Ubuntu2204
    efaEnabled: true
    preBootstrapCommands:
      - |
        #!/bin/bash
        exec 1> >(logger -s -t $(basename $0)) 2>&1

        #########################################################################################
        #                                    Configuration Section                              #
        #########################################################################################

        # File System Configuration
        FSX_DNS="<your-fsx-filesystem-dns>" # Needs to be adjusted.
        MOUNT_NAME="<your-mount-name>" # Needs to be adjusted.
        MOUNT_POINT="</your/mount/point>" # Needs to be adjusted.

        # Lustre Tuning Parameters
        LUSTRE_LRU_MAX_AGE=600000
        LUSTRE_MAX_CACHED_MB=64
        LUSTRE_OST_MAX_RPC=32
        LUSTRE_MDC_MAX_RPC=64
        LUSTRE_MDC_MOD_RPC=50

        # File paths
        FUNCTIONS_SCRIPT="/usr/local/bin/lustre_functions.sh"
        TUNINGS_SCRIPT="/usr/local/bin/apply_lustre_tunings.sh"
        SERVICE_FILE="/etc/systemd/system/lustre-tunings.service"

        #EFA
        MIN_EFA_VERSION="2.12.1"

        # Function to check if a command was successful
        check_success() {
            if [ $? -eq 0 ]; then
                echo "SUCCESS: $1"
            else
                echo "FAILED: $1"
                return 1
            fi
        }

        echo "********Starting FSx for Lustre configuration********"

        # 1. Install Lustre client
        if grep -q '^ID=ubuntu' /etc/os-release; then
            echo "Detected Ubuntu, proceeding with Lustre setup..."
            # Add Lustre repository
            sudo wget -O - https://fsx-lustre-client-repo-public-keys.s3.amazonaws.com/fsx-ubuntu-public-key.asc | sudo gpg --dearmor | sudo tee /usr/share/keyrings/fsx-ubuntu-public-key.gpg > /dev/null

            echo "deb [signed-by=/usr/share/keyrings/fsx-ubuntu-public-key.gpg] https://fsx-lustre-client-repo.s3.amazonaws.com/ubuntu jammy main" | sudo tee /etc/apt/sources.list.d/fsxlustreclientrepo.list

            sudo apt-get update
            sudo apt-get install -y lustre-client-modules-$(uname -r)
            sudo apt-get install -y lustre-client
        else
            echo "Not Ubuntu, exiting"
            exit 1
        fi

        check_success "Install Lustre client"

        # Ensure Lustre tools are in the PATH
        export PATH=$PATH:/usr/sbin

        # 2. Apply network and RPC tunings
        echo "********Applying network and RPC tunings********"
        if ! grep -q "options ptlrpc ptlrpcd_per_cpt_max" /etc/modprobe.d/modprobe.conf; then
            echo "options ptlrpc ptlrpcd_per_cpt_max=64" | sudo tee -a /etc/modprobe.d/modprobe.conf
            check_success "Set ptlrpcd_per_cpt_max"
        else
            echo "ptlrpcd_per_cpt_max already set in modprobe.conf"
        fi

        if ! grep -q "options ksocklnd credits" /etc/modprobe.d/modprobe.conf; then
            echo "options ksocklnd credits=2560" | sudo tee -a /etc/modprobe.d/modprobe.conf
            check_success "Set ksocklnd credits"
        else
            echo "ksocklnd credits already set in modprobe.conf"
        fi

        # 3. Load Lustre modules
        manage_lustre_modules() {
            echo "Checking for existing Lustre modules..."
            if lsmod | grep -q lustre; then
                echo "Existing Lustre modules found."

                # Check for mounted Lustre filesystems
                echo "Checking for mounted Lustre filesystems..."
                if mount | grep -q "type lustre"; then
                    echo "Found mounted Lustre filesystems. Attempting to unmount..."
                    mounted_fs=$(mount | grep "type lustre" | awk '{print $3}')
                    for fs in $mounted_fs; do
                        echo "Unmounting $fs"
                        sudo umount $fs
                        check_success "Unmount filesystem $fs"
                    done
                else
                    echo "No Lustre filesystems mounted."
                fi

                # After unmounting, try to remove modules
                echo "Attempting to remove Lustre modules..."
                sudo lustre_rmmod
                if [ $? -eq 0 ]; then
                    echo "SUCCESS: Removed existing Lustre modules"
                else
                    echo "WARNING: Could not remove Lustre modules. They may still be in use."
                    echo "Please check for any remaining Lustre processes or mounts."
                    return 1
                fi
            else
                echo "No existing Lustre modules found."
            fi

            echo "Loading Lustre modules..."
            sudo modprobe lustre
            check_success "Load Lustre modules" || exit 1

            echo "Checking loaded Lustre modules:"
            lsmod | grep lustre
        }

        # Managing Lustre kernel modules
        echo "********Managing Lustre kernel modules********"
        manage_lustre_modules

        # 4. Initializing Lustre networking
        echo "********Initializing Lustre networking********"
        sudo lctl network up
        check_success "Initialize Lustre networking" || exit 1

        # 4.5 EFA Setup and Configuration
        setup_efa() {
            echo "********Starting EFA Setup********"

            # Get interface and version information
            eth_intf="$(/sbin/ip -br -4 a sh | grep $(hostname -i)/ | awk '{print $1}')"
            efa_version=$(modinfo efa | awk '/^version:/ {print $2}' | sed 's/[^0-9.]//g')
            min_efa_version=$MIN_EFA_VERSION

            # Install or verify EFA driver
            if [[ "$(printf '%s\n' "$min_efa_version" "$efa_version" | sort -V | head -n1)" != "$min_efa_version" ]]; then
                echo "Installing EFA driver..."
                sudo curl -O https://efa-installer.amazonaws.com/aws-efa-installer-1.37.0.tar.gz
                tar -xf aws-efa-installer-1.37.0.tar.gz && cd aws-efa-installer

                # Install dependencies
                sudo apt-get update && apt-get upgrade -y
                sudo apt install -y pciutils environment-modules libnl-3-dev libnl-route-3-200 libnl-route-3-dev dkms

                # Install EFA
                sudo ./efa_installer.sh -y
                modinfo efa
            else
                echo "Using existing EFA driver version $efa_version"
            fi
        }

        configure_efa_network() {
            echo "********Configuring EFA Network********"

            # Load required modules
            echo "Loading network modules..."
            sudo /sbin/modprobe lnet
            sudo /sbin/modprobe kefalnd ipif_name="$eth_intf"
            sudo /sbin/modprobe ksocklnd

            # Initialize LNet
            echo "Initializing LNet..."
            sudo lnetctl lnet configure

            # Configure TCP interface
            echo "Configuring TCP interface..."
            sudo lnetctl net del --net tcp 2> /dev/null
            sudo lnetctl net add --net tcp --if $eth_intf

            # For P5 instance type which supports 32 network cards,
            # by default add 8 EFA interfaces selecting every 4th device (1 per PCI bus)
            echo "Configuring EFA interface(s)..."
            instance_type="$(ec2-metadata --instance-type | awk '{ print $2 }')"
            num_efa_devices="$(ls -1 /sys/class/infiniband | wc -l)"
            echo "Found $num_efa_devices available EFA device(s)"

            if [[ "$instance_type" == "p5.48xlarge" || "$instance_type" == "p5e.48xlarge" ]]; then
                # P5 instance configuration
                for intf in $(ls -1 /sys/class/infiniband | awk 'NR % 4 == 1'); do
                    sudo lnetctl net add --net efa --if $intf --peer-credits 32
                done
            else
                # Standard configuration
                # Other instances: Configure 2 EFA interfaces by default if the instance supports multiple network cards,
                # or 1 interface for single network card instances
                # Can be modified to add more interfaces if instance type supports it
                sudo lnetctl net add --net efa --if $(ls -1 /sys/class/infiniband | head -n1) --peer-credits 32
                if [[ $num_efa_devices -gt 1 ]]; then
                    sudo lnetctl net add --net efa --if $(ls -1 /sys/class/infiniband | tail -n1) --peer-credits 32
                fi
            fi

            # Configure discovery and UDSP
            echo "Setting up discovery and UDSP rules..."
            sudo lnetctl set discovery 1
            sudo lnetctl udsp add --src efa --priority 0
            sudo /sbin/modprobe lustre

            # Verify configuration
            echo "Verifying EFA network configuration..."
            sudo lnetctl net show
            echo "Added $(sudo lnetctl net show | grep -c '@efa') EFA interface(s)"
        }

        # Main execution
        setup_efa
        configure_efa_network

        # 5. Mount FSx filesystem
        if [ ! -z "$FSX_DNS" ] && [ ! -z "$MOUNT_NAME" ]; then
            echo "********Creating mount point********"
            sudo mkdir -p $MOUNT_POINT
            check_success "Create mount point"

            echo "Mounting FSx filesystem..."
            sudo mount -t lustre ${FSX_DNS}@tcp:/${MOUNT_NAME} ${MOUNT_POINT}
            check_success "Mount FSx filesystem"
        else
            echo "Skipping FSx mount as DNS or mount name is not provided"
        fi

        # 6. Applying Lustre performance tunings
        echo "********Applying Lustre performance tunings********"

        # Get number of CPUs
        NUM_CPUS=$(nproc)

        # Calculate LRU size (100 * number of CPUs)
        LRU_SIZE=$((100 * NUM_CPUS))

        #Apply LRU tunings
        echo "Apply LRU tunings"
        sudo lctl set_param ldlm.namespaces.*.lru_max_age=${LUSTRE_LRU_MAX_AGE}
        check_success "Set lru_max_age"
        sudo lctl set_param ldlm.namespaces.*.lru_size=$LRU_SIZE
        check_success "Set lru_size"

        # Client Cache Control
        sudo lctl set_param llite.*.max_cached_mb=${LUSTRE_MAX_CACHED_MB}
        check_success "Set max_cached_mb"

        # RPC Controls
        sudo lctl set_param osc.*OST*.max_rpcs_in_flight=${LUSTRE_OST_MAX_RPC}
        check_success "Set OST max_rpcs_in_flight"

        sudo lctl set_param mdc.*.max_rpcs_in_flight=${LUSTRE_MDC_MAX_RPC}
        check_success "Set MDC max_rpcs_in_flight"

        sudo lctl set_param mdc.*.max_mod_rpcs_in_flight=${LUSTRE_MDC_MOD_RPC}
        check_success "Set MDC max_mod_rpcs_in_flight"

        # 7. Verify all tunings
        echo "********Verifying all tunings********"

        # Function to verify parameter value
        verify_param() {
            local param=$1
            local expected=$2
            local actual=$3

            if [ "$actual" == "$expected" ]; then
                echo "SUCCESS: $param is correctly set to $expected"
            else
                echo "WARNING: $param is set to $actual (expected $expected)"
            fi
        }

        echo "Verifying all parameters:"

        # LRU tunings
        actual_lru_max_age=$(lctl get_param -n ldlm.namespaces.*.lru_max_age | head -1)
        verify_param "lru_max_age" "600000" "$actual_lru_max_age"

        actual_lru_size=$(lctl get_param -n ldlm.namespaces.*.lru_size | head -1)
        verify_param "lru_size" "$LRU_SIZE" "$actual_lru_size"

        # Client Cache
        actual_max_cached_mb=$(lctl get_param -n llite.*.max_cached_mb | grep "max_cached_mb:" | awk '{print $2}')
        verify_param "max_cached_mb" "64" "$actual_max_cached_mb"

        # RPC Controls
        actual_ost_rpcs=$(lctl get_param -n osc.*OST*.max_rpcs_in_flight | head -1)
        verify_param "OST max_rpcs_in_flight" "32" "$actual_ost_rpcs"

        actual_mdc_rpcs=$(lctl get_param -n mdc.*.max_rpcs_in_flight | head -1)
        verify_param "MDC max_rpcs_in_flight" "64" "$actual_mdc_rpcs"

        actual_mdc_mod_rpcs=$(lctl get_param -n mdc.*.max_mod_rpcs_in_flight | head -1)
        verify_param "MDC max_mod_rpcs_in_flight" "50" "$actual_mdc_mod_rpcs"

        # Network and RPC configurations from modprobe.conf
        actual_ptlrpc=$(grep "ptlrpc ptlrpcd_per_cpt_max" /etc/modprobe.d/modprobe.conf | awk '{print $3}')
        verify_param "ptlrpcd_per_cpt_max" "ptlrpcd_per_cpt_max=64" "$actual_ptlrpc"

        actual_ksocklnd=$(grep "ksocklnd credits" /etc/modprobe.d/modprobe.conf | awk '{print $3}')
        verify_param "ksocklnd credits" "credits=2560" "$actual_ksocklnd"

        # 8. Setup persistence
        setup_persistence() {
            # Create functions file
            cat << EOF > $FUNCTIONS_SCRIPT
        #!/bin/bash

        apply_lustre_tunings() {
            local NUM_CPUS=\$(nproc)
            local LRU_SIZE=\$((100 * NUM_CPUS))

            echo "Applying Lustre performance tunings..."
            lctl set_param ldlm.namespaces.*.lru_max_age=$LUSTRE_LRU_MAX_AGE
            lctl set_param ldlm.namespaces.*.lru_size=\$LRU_SIZE
            lctl set_param llite.*.max_cached_mb=$LUSTRE_MAX_CACHED_MB
            lctl set_param osc.*OST*.max_rpcs_in_flight=$LUSTRE_OST_MAX_RPC
            lctl set_param mdc.*.max_rpcs_in_flight=$LUSTRE_MDC_MAX_RPC
            lctl set_param mdc.*.max_mod_rpcs_in_flight=$LUSTRE_MDC_MOD_RPC
        }
        EOF

            # Create tuning script
            cat << EOF > $TUNINGS_SCRIPT
        #!/bin/bash
        exec 1> >(logger -s -t \$(basename \$0)) 2>&1

        source $FUNCTIONS_SCRIPT

        # Function to check if Lustre is mounted
        is_lustre_mounted() {
            mount | grep -q "type lustre"
        }

        # Function to mount Lustre
        mount_lustre() {
            echo "Mounting Lustre filesystem..."
            mkdir -p $MOUNT_POINT
            mount -t lustre ${FSX_DNS}@tcp:/${MOUNT_NAME} $MOUNT_POINT
            return \$?
        }

        # Main execution
        # Try to mount if not already mounted
        if ! is_lustre_mounted; then
            echo "Lustre filesystem not mounted, attempting to mount..."
            mount_lustre
        fi

        # Wait for successful mount (up to 5 minutes)
        for i in {1..30}; do
            if is_lustre_mounted; then
                echo "Lustre filesystem mounted, applying tunings..."
                apply_lustre_tunings
                exit 0
            fi
            echo "Waiting for Lustre filesystem to be mounted... (attempt $i/30)"
            sleep 10
        done

        echo "Timeout waiting for Lustre filesystem mount"
        exit 1
        EOF

        # Create systemd service

        # Create systemd directory if it doesn't exist
        sudo mkdir -p /etc/systemd/system/

            # Create service file directly for Ubuntu
            cat << EOF > $SERVICE_FILE
        [Unit]
        Description=Apply Lustre Performance Tunings
        After=network.target remote-fs.target

        [Service]
        Type=oneshot
        ExecStart=/bin/bash -c 'source $FUNCTIONS_SCRIPT && $TUNINGS_SCRIPT'
        RemainAfterExit=yes

        [Install]
        WantedBy=multi-user.target
        EOF


            # Make scripts executable and enable service
            sudo chmod +x $FUNCTIONS_SCRIPT
            sudo chmod +x $TUNINGS_SCRIPT
            systemctl enable lustre-tunings.service
            systemctl start lustre-tunings.service
        }

        echo "********Setting up persistent tuning********"
        setup_persistence

        echo "FSx for Lustre configuration completed."
```

## （可选）第 3 步。验证 EFA 设置
<a name="verify-efa-setup"></a>

通过 SSH 连接到节点：

```
# Get instance ID from EKS console or {aws} CLI
ssh -i /path/to/your-key.pem ec2-user@<node-internal-ip>
```

验证 EFA 配置：

```
sudo lnetctl net show
```

检查设置日志：

```
sudo cat /var/log/cloud-init-output.log
```

`lnetctl net show` 的预期输出示例如下：

```
net:
    - net type: tcp
      ...
    - net type: efa
      local NI(s):
        - nid: xxx.xxx.xxx.xxx@efa
          status: up
```

## 示例部署
<a name="example-deployments"></a>

### a. 创建 claim.yaml
<a name="_a_create_claim_yaml"></a>

```
#claim.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: fsx-claim-efa
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 4800Gi
  volumeName: fsx-pv
```

应用声明：

```
kubectl apply -f claim.yaml
```

### b. 创建 pv.yaml
<a name="_b_create_pv_yaml"></a>

更新 `<replaceable-placeholders>`：

```
#pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: fsx-pv
spec:
  capacity:
    storage: 4800Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  mountOptions:
    - flock
  persistentVolumeReclaimPolicy: Recycle
  csi:
    driver: fsx.csi.aws.com
    volumeHandle: fs-<1234567890abcdef0>
    volumeAttributes:
      dnsname: fs-<1234567890abcdef0>.fsx.us-east-1.amazonaws.com
      mountname: <abcdef01>
```

应用持久性卷：

```
kubectl apply -f pv.yaml
```

### c. 创建 pod.yaml
<a name="_c_create_pod_yaml"></a>

```
#pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: fsx-efa-app
spec:
  containers:
  - name: app
    image: amazonlinux:2
    command: ["/bin/sh"]
    args: ["-c", "while true; do dd if=/dev/urandom bs=100M count=20 > data/test_file; sleep 10; done"]
    resources:
      requests:
        vpc.amazonaws.com/efa: 1
      limits:
        vpc.amazonaws.com/efa: 1
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: fsx-claim-efa
```

应用容器组（pod）：

```
kubectl apply -f pod.yaml
```

## 其他验证命令
<a name="verification-commands"></a>

验证容器组（pod）是否挂载到并写入文件系统：

```
kubectl exec -ti fsx-efa-app -- df -h | grep data
# Expected output:
# <192.0.2.0>@tcp:/<abcdef01>  4.5T  1.2G  4.5T   1% /data

kubectl exec -ti fsx-efa-app -- ls /data
# Expected output:
# test_file
```

通过 SSH 连接到节点来验证流量是否通过 EFA：

```
sudo lnetctl net show -v
```

预期输出将显示 EFA 接口及流量统计数据。

## 相关信息
<a name="_related_information"></a>
+  [部署适用于 Lustre 的 FSx 驱动程序](fsx-csi-create.md) 
+  [优化节点上的适用于 Lustre 的 Amazon FSx 性能（非 EFA）](fsx-csi-tuning-non-efa.md) 
+  [适用于 Lustre 的 Amazon FSx 性能](https://docs.aws.amazon.com/fsx/latest/LustreGuide/performance.html) 
+  [Elastic Fabric Adapter](https://docs.aws.amazon.com/ec2/latest/userguide/efa.html) 

# 优化节点上的适用于 Lustre 的 Amazon FSx 性能（非 EFA）
<a name="fsx-csi-tuning-non-efa"></a>

您可以在节点初始化期间使用启动模板用户数据应用调优参数，从而优化适用于 Lustre 的 Amazon FSx 性能。

**注意**  
有关创建和部署 FSx for Lustre CSI 驱动程序的信息，请参阅[部署适用于 Lustre 的 FSx 驱动程序](fsx-csi-create.md)。要优化启用 EFA 的节点的性能，请参阅[优化节点上的适用于 Lustre 的 Amazon FSx 性能（EFA）](fsx-csi-tuning-efa.md)。

## 为什么要使用启动模板用户数据？
<a name="_why_use_launch_template_user_data"></a>
+ 在节点初始化期间自动应用调优。
+ 可确保所有节点的配置一致。
+ 无需手动配置节点。

## 示例脚本概览
<a name="_example_script_overview"></a>

本主题中定义的示例脚本会执行以下操作：

### `# 1. Install Lustre client`
<a name="_1_install_lustre_client"></a>
+ 自动检测 Amazon Linux（AL）操作系统版本。
+ 安装相应的 Lustre 客户端程序包。

### `# 2. Apply network and RPC tunings`
<a name="_2_apply_network_and_rpc_tunings"></a>
+ 设置 `ptlrpcd_per_cpt_max=64` 以实现并行 RPC 处理。
+ 配置 `ksocklnd credits=2560` 以优化网络缓冲区。

### `# 3. Load Lustre modules`
<a name="_3_load_lustre_modules"></a>
+ 安全地移除现有 Lustre 模块（如有）。
+ 处理现有文件系统的卸载。
+ 加载全新的 Lustre 模块。

### `# 4. Lustre Network Initialization`
<a name="_4_lustre_network_initialization"></a>
+ 初始化 Lustre 联网配置。
+ 设置所需的网络参数。

### `# 5. Mount FSx filesystem`
<a name="_5_mount_fsx_filesystem"></a>
+ 必须在这一部分中根据环境调整值。

### `# 6. Apply tunings`
<a name="_6_apply_tunings"></a>
+ LRU（锁定资源单位）调优：
  +  `lru_max_age=600000` 
  +  根据 CPU 计数计算的 `lru_size`
+ 客户端缓存控制：`max_cached_mb=64`
+ RPC 控制：
  + OST `max_rpcs_in_flight=32` 
  + MDC `max_rpcs_in_flight=64` 
  + MDC `max_mod_rpcs_in_flight=50` 

### `# 7. Verify tunings`
<a name="_7_verify_tunings"></a>
+ 验证所有已应用的调优。
+ 报告每个参数成功或发出警告。

### `# 8. Setup persistence`
<a name="_8_setup_persistence"></a>
+ 在这一部分中还必须根据环境调整值。
+ 自动检测操作系统版本（AL2023），确定要应用的 `Systemd` 服务。
+ 系统启动。
+  `Systemd` 会启动 `lustre-tunings` 服务（由于 `WantedBy=multi-user.target`）。
+ 服务会运行 `apply_lustre_tunings.sh`，这将：
  + 检查文件系统是否已挂载。
  + 如果未挂载，则将挂载文件系统。
  + 等待挂载成功（最长五分钟）。
  + 成功挂载后应用调优参数。
+ 在重新启动之前，设置一直处于活动状态。
+ 服务会在脚本完成后退出。
  + Systemd 将服务标记为“活动（已退出）”。
+ 下次重启时会重复此过程。

## 创建启动模板
<a name="_create_a_launch_template"></a>

1. 通过以下网址打开 Amazon EC2 控制台：[https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)。

1. 选择**启动模板**。

1. 选择**Create launch template**（创建启动模板）。

1. 在**高级详细信息**中，找到**用户数据**部分。

1. 粘贴下面的脚本，并根据需要更新任何内容。
**重要**  
在 `# 5. Mount FSx filesystem` 部分中以及在 `# 8. Setup persistence` 部分 `apply_lustre_tunings.sh` 步骤的 `setup_persistence()` 函数中，根据环境调整这些值：  

   ```
   FSX_DNS="<your-fsx-filesystem-dns>" # Needs to be adjusted.
   MOUNT_NAME="<your-mount-name>" # Needs to be adjusted.
   MOUNT_POINT="</your/mount/point>" # Needs to be adjusted.
   ```

   ```
   MIME-Version: 1.0
   Content-Type: multipart/mixed; boundary="==MYBOUNDARY=="
   --==MYBOUNDARY==
   Content-Type: text/x-shellscript; charset="us-ascii"
   #!/bin/bash
   exec 1> >(logger -s -t $(basename $0)) 2>&1
   # Function definitions
   check_success() {
       if [ $? -eq 0 ]; then
           echo "SUCCESS: $1"
       else
           echo "FAILED: $1"
           return 1
       fi
   }
   apply_tunings() {
       local NUM_CPUS=$(nproc)
       local LRU_SIZE=$((100 * NUM_CPUS))
       local params=(
           "ldlm.namespaces.*.lru_max_age=600000"
           "ldlm.namespaces.*.lru_size=$LRU_SIZE"
           "llite.*.max_cached_mb=64"
           "osc.*OST*.max_rpcs_in_flight=32"
           "mdc.*.max_rpcs_in_flight=64"
           "mdc.*.max_mod_rpcs_in_flight=50"
       )
       for param in "${params[@]}"; do
           lctl set_param $param
           check_success "Set ${param%%=*}"
       done
   }
   verify_param() {
       local param=$1
       local expected=$2
       local actual=$3
   
       if [ "$actual" == "$expected" ]; then
           echo "SUCCESS: $param is correctly set to $expected"
       else
           echo "WARNING: $param is set to $actual (expected $expected)"
       fi
   }
   verify_tunings() {
       local NUM_CPUS=$(nproc)
       local LRU_SIZE=$((100 * NUM_CPUS))
       local params=(
           "ldlm.namespaces.*.lru_max_age:600000"
           "ldlm.namespaces.*.lru_size:$LRU_SIZE"
           "llite.*.max_cached_mb:64"
           "osc.*OST*.max_rpcs_in_flight:32"
           "mdc.*.max_rpcs_in_flight:64"
           "mdc.*.max_mod_rpcs_in_flight:50"
       )
       echo "Verifying all parameters:"
       for param in "${params[@]}"; do
           name="${param%%:*}"
           expected="${param#*:}"
           actual=$(lctl get_param -n $name | head -1)
           verify_param "${name##*.}" "$expected" "$actual"
       done
   }
   setup_persistence() {
       # Create functions file
       cat << 'EOF' > /usr/local/bin/lustre_functions.sh
   #!/bin/bash
   apply_lustre_tunings() {
       local NUM_CPUS=$(nproc)
       local LRU_SIZE=$((100 * NUM_CPUS))
   
       echo "Applying Lustre performance tunings..."
       lctl set_param ldlm.namespaces.*.lru_max_age=600000
       lctl set_param ldlm.namespaces.*.lru_size=$LRU_SIZE
       lctl set_param llite.*.max_cached_mb=64
       lctl set_param osc.*OST*.max_rpcs_in_flight=32
       lctl set_param mdc.*.max_rpcs_in_flight=64
       lctl set_param mdc.*.max_mod_rpcs_in_flight=50
   }
   EOF
       # Create tuning script
       cat << 'EOF' > /usr/local/bin/apply_lustre_tunings.sh
   #!/bin/bash
   exec 1> >(logger -s -t $(basename $0)) 2>&1
   # Source the functions
   source /usr/local/bin/lustre_functions.sh
   # FSx details
   FSX_DNS="<your-fsx-filesystem-dns>" # Needs to be adjusted.
   MOUNT_NAME="<your-mount-name>" # Needs to be adjusted.
   MOUNT_POINT="</your/mount/point>" # Needs to be adjusted.
   # Function to check if Lustre is mounted
   is_lustre_mounted() {
       mount | grep -q "type lustre"
   }
   # Function to mount Lustre
   mount_lustre() {
       echo "Mounting Lustre filesystem..."
       mkdir -p ${MOUNT_POINT}
       mount -t lustre ${FSX_DNS}@tcp:/${MOUNT_NAME} ${MOUNT_POINT}
       return $?
   }
   # Main execution
   # Try to mount if not already mounted
   if ! is_lustre_mounted; then
       echo "Lustre filesystem not mounted, attempting to mount..."
       mount_lustre
   fi
   # Wait for successful mount (up to 5 minutes)
   for i in {1..30}; do
       if is_lustre_mounted; then
           echo "Lustre filesystem mounted, applying tunings..."
           apply_lustre_tunings
           exit 0
       fi
       echo "Waiting for Lustre filesystem to be mounted... (attempt $i/30)"
       sleep 10
   done
   echo "Timeout waiting for Lustre filesystem mount"
   exit 1
   EOF
       # Create systemd service
       cat << 'EOF' > /etc/systemd/system/lustre-tunings.service
   [Unit]
   Description=Apply Lustre Performance Tunings
   After=network.target remote-fs.target
   StartLimitIntervalSec=0
   [Service]
   Type=oneshot
   ExecStart=/usr/local/bin/apply_lustre_tunings.sh
   RemainAfterExit=yes
   Restart=on-failure
   RestartSec=30
   [Install]
   WantedBy=multi-user.target
   EOF
       chmod +x /usr/local/bin/lustre_functions.sh
       chmod +x /usr/local/bin/apply_lustre_tunings.sh
       systemctl enable lustre-tunings.service
       systemctl start lustre-tunings.service
   }
   echo "Starting FSx for Lustre configuration..."
   # 1. Install Lustre client
   if grep -q 'VERSION="2"' /etc/os-release; then
       amazon-linux-extras install -y lustre
   elif grep -q 'VERSION="2023"' /etc/os-release; then
       dnf install -y lustre-client
   fi
   check_success "Install Lustre client"
   # 2. Apply network and RPC tunings
   export PATH=$PATH:/usr/sbin
   echo "Applying network and RPC tunings..."
   if ! grep -q "options ptlrpc ptlrpcd_per_cpt_max" /etc/modprobe.d/modprobe.conf; then
       echo "options ptlrpc ptlrpcd_per_cpt_max=64" | tee -a /etc/modprobe.d/modprobe.conf
       echo "options ksocklnd credits=2560" | tee -a /etc/modprobe.d/modprobe.conf
   fi
   # 3. Load Lustre modules
   modprobe lustre
   check_success "Load Lustre modules" || exit 1
   # 4. Lustre Network Initialization
   lctl network up
   check_success "Initialize Lustre networking" || exit 1
   # 5. Mount FSx filesystem
   FSX_DNS="<your-fsx-filesystem-dns>" # Needs to be adjusted.
   MOUNT_NAME="<your-mount-name>" # Needs to be adjusted.
   MOUNT_POINT="</your/mount/point>" # Needs to be adjusted.
   if [ ! -z "$FSX_DNS" ] && [ ! -z "$MOUNT_NAME" ]; then
       mkdir -p $MOUNT_POINT
       mount -t lustre ${FSX_DNS}@tcp:/${MOUNT_NAME} ${MOUNT_POINT}
       check_success "Mount FSx filesystem"
   fi
   # 6. Apply tunings
   apply_tunings
   # 7. Verify tunings
   verify_tunings
   # 8. Setup persistence
   setup_persistence
   echo "FSx for Lustre configuration completed."
   --==MYBOUNDARY==--
   ```

1. 创建 Amazon EKS 节点组时，请选择此启动模板。有关更多信息，请参阅 [为集群创建托管式节点组](create-managed-node-group.md)。

## 相关信息
<a name="_related_information"></a>
+  [部署适用于 Lustre 的 FSx 驱动程序](fsx-csi-create.md) 
+  [优化节点上的适用于 Lustre 的 Amazon FSx 性能（EFA）](fsx-csi-tuning-efa.md) 
+  [适用于 Lustre 的 Amazon FSx 性能](https://docs.aws.amazon.com/fsx/latest/LustreGuide/performance.html) 

# 将适用于 NetApp ONTAP 的 FSx 与高性能应用程序存储结合使用
<a name="fsx-ontap"></a>

NetApp Trident 使用符合容器存储接口（CSI）的驱动程序提供动态存储编排。该服务允许 Amazon EKS 集群管理适用于 NetApp ONTAP 的 Amazon FSx 文件系统提供支持的持久卷（PV）的生命周期。请注意，适用于 NetApp ONTAP 的 Amazon FSx CSI 驱动程序与 Amazon EKS 混合节点功能不兼容。要开始使用，请参阅 NetApp Trident 文档中的 [Use Trident with Amazon FSx for NetApp ONTAP](https://docs.netapp.com/us-en/trident/trident-use/trident-fsx.html)。

Amazon FSx for NetApp ONTAP 是一种存储服务，允许您在云中启动和运行完全托管的 ONTAP 文件系统。ONTAP 是 NetApp 的文件系统技术，提供了一套采用广泛的数据访问和数据管理功能。FSx for ONTAP 提供本地 NetApp 文件系统的功能、性能和 API，具有完全托管式 AWS 服务的灵活性、可扩展性和简单性。有关更多信息，请参阅[《FSx for ONTAP 用户指南》](https://docs.aws.amazon.com/fsx/latest/ONTAPGuide/what-is-fsx-ontap.html)。

**重要**  
如果您将适用于 NetApp ONTAP 的 Amazon FSx 和 Amazon EBS CSI 驱动程序结合使用来预置 EBS 卷，则必须在 `multipath.conf` 文件中指定不要使用 EBS 设备。有关支持的方法，请参阅[配置文件黑名单](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/7/html/dm_multipath/config_file_blacklist#config_file_blacklist)。见下列。  

```
 defaults {
        user_friendly_names yes
        find_multipaths no
      }
      blacklist {
        device {
          vendor "NVME"
          product "Amazon Elastic Block Store"
        }
      }
```

# 将适用于 OpenZFS 的 Amazon FSx 与数据存储结合使用
<a name="fsx-openzfs-csi"></a>

Amazon FSx for OpenZFS 是一项完全托管式的文件存储服务，可让您轻松地将数据从本地 ZFS 或其他基于 Linux 的文件服务器移动到 AWS。您可以在不更改应用程序代码或数据管理方式的情况下执行此操作。它基于开源 OpenZFS 文件系统提供高度可靠、可扩展、高效且功能丰富的文件存储。它将这些功能与完全托管式 AWS 服务的灵活性、可扩展性和简单性相结合。有关更多信息，请参阅《Amazon FSx for OpenZFS 用户指南》[https://docs.aws.amazon.com/fsx/latest/OpenZFSGuide/what-is-fsx.html](https://docs.aws.amazon.com/fsx/latest/OpenZFSGuide/what-is-fsx.html)。

适用于 OpenZFS 的 FSx 容器存储接口（CSI）驱动程序提供了一个 CSI 接口，从而方便 Amazon EKS 集群管理适用于 OpenZFS 的 FSx 卷的生命周期。请注意，适用于 OpenZFS 的 Amazon FSx CSI 驱动程序与 Amazon EKS 混合节点功能不兼容。要将适用于 OpenZFS 的 FSx CSI 驱动程序部署到 Amazon EKS 集群，请参阅 GitHub 上的 [aws-fsx-openzfs-csi-driver](https://github.com/kubernetes-sigs/aws-fsx-openzfs-csi-driver)。

# 使用 Amazon File Cache 减少延迟
<a name="file-cache-csi"></a>

Amazon File Cache 是 AWS 上一个完全托管的高速缓存，用于处理文件数据，无论数据存储在何处。Amazon File Cache 会在首次访问数据时自动将数据加载到缓存中，并在不使用时释放数据。有关更多信息，请参阅《[Amazon File Cache 用户指南](https://docs.aws.amazon.com/fsx/latest/FileCacheGuide/what-is.html)》。

Amazon File Cache Storage Interface (CSI) 驱动程序提供了一个 CSI 接口，允许 Amazon EKS 集群管理 Amazon 文件缓存的生命周期。请注意，Amazon File Cache CSI 驱动程序与 Amazon EKS 混合节点功能不兼容。要将 Amazon File Cache CSI 驱动程序部署到您的 Amazon EKS 集群，请参阅 GitHub 上的 [aws-file-cache-csi-driver](https://github.com/kubernetes-sigs/aws-file-cache-csi-driver)。

# 使用适用于 Amazon S3 的 Mountpoint CSI 驱动程序访问适用于 Amazon S3 对象
<a name="s3-csi"></a>

借助[适用于 Amazon S3 的 Mountpoint 容器存储接口（CSI）驱动程序](https://github.com/awslabs/mountpoint-s3-csi-driver)，您的 Kubernetes 应用程序可以通过文件系统接口访问 Amazon S3 对象，从而在不更改任何应用程序代码的情况下实现高聚合吞吐量。基于[适用于 Amazon S3 的 Mountpoint](https://github.com/awslabs/mountpoint-s3) 构建的 CSI 驱动程序，将 Amazon S3 存储桶以卷的形式呈现，可供 Amazon EKS 和自主管理型 Kubernetes 集群中的容器访问。

## 注意事项
<a name="s3-csi-considerations"></a>
+ 适用于 Amazon S3 的 Mountpoint CSI 驱动程序目前与基于 Windows 的容器映像不兼容。
+ 适用于 Amazon S3 的 Mountpoint CSI 驱动程序目前与 Amazon EKS 混合节点功能不兼容。
+ 适用于 Amazon S3 的 Mountpoint CSI 驱动程序不支持 AWS Fargate，但支持在 Amazon EC2 中运行的容器（无论是采用 Amazon EKS 还是自定义 Kubernetes 安装）。
+ 适用于 Amazon S3 的 Mountpoint CSI 驱动程序仅支持静态预置。不支持动态预置或创建新存储桶。
**注意**  
静态预调配是指使用现有的 Amazon S3 存储桶，该存储桶被指定为 `PersistentVolume` 对象中 `volumeAttributes` 中的 `bucketName`。有关更多信息，请参阅 GitHub 上的 [Static Provisioning](https://github.com/awslabs/mountpoint-s3-csi-driver/blob/main/examples/kubernetes/static_provisioning/README.md)。
+ 使用适用于 Amazon S3 的 Mountpoint CSI 驱动程序挂载的卷，不支持所有 POSIX 文件系统功能。有关文件系统行为的详细信息，请参阅 GitHub 上的 [Mountpoint for Amazon S3 file system behavior](https://github.com/awslabs/mountpoint-s3/blob/main/doc/SEMANTICS.md)。

有关部署此驱动程序的详细信息，请参阅[部署适用于 Amazon S3 的 Mountpoint 驱动程序](s3-csi-create.md)。有关移除此驱动程序的详细信息，请参阅[移除适用于 Amazon S3 的 Mountpoint Amazon EKS 附加组件](removing-s3-csi-eks-add-on.md)。

# 部署适用于 Amazon S3 的 Mountpoint 驱动程序
<a name="s3-csi-create"></a>

借助[适用于 Amazon S3 的 Mountpoint 容器存储接口（CSI）驱动程序](https://github.com/awslabs/mountpoint-s3-csi-driver)，您的 Kubernetes 应用程序可以通过文件系统接口访问 Amazon S3 对象，从而在不更改任何应用程序代码的情况下实现高聚合吞吐量。

此过程将演示如何部署[适用于 Amazon S3 的 Mountpoint CSI Amazon EKS 驱动程序](s3-csi.md)。在继续操作之前，请查看[注意事项](s3-csi.md#s3-csi-considerations)。

## 先决条件
<a name="s3-csi-prereqs"></a>
+ 适用于集群的现有 AWS Identity and Access Management（IAM）OpenID Connect（OIDC）提供者。要确定您是否已经拥有一个或是否要创建一个，请参阅[为集群创建 IAM OIDC 提供商](enable-iam-roles-for-service-accounts.md)。
+ 您的设备或 AWS CloudShell 上安装并配置了 2.12.3 或更高版本的 AWS CLI。
+ 您的设备或 AWS CloudShell 上安装了 `kubectl` 命令行工具。该版本可以与集群的 Kubernetes 版本相同，或者最多早于或晚于该版本一个次要版本。例如，如果您的集群版本为 `1.29`，则可以将 `kubectl` 的 `1.28`、`1.29` 或 `1.30` 版本与之配合使用。要安装或升级 `kubectl`，请参阅 [设置 `kubectl` 和 `eksctl`](install-kubectl.md)。

## 步骤 1：创建 IAM policy
<a name="s3-create-iam-policy"></a>

适用于 Amazon S3 的 Mountpoint CSI 驱动程序需要 Amazon S3 权限才能与文件系统交互。本节将介绍如何创建 IAM 策略来授予必要的权限。

以下示例策略遵循 Mountpoint 的 IAM 权限建议。您也可以使用 AWS 托管式策略 [AmazonS3FullAccess](https://console.aws.amazon.com/iam/home?#/policies/arn:aws:iam::aws:policy/AmazonS3FullAccess$jsonEditor)，但此托管式策略授予的权限超出了 Mountpoint 所需的权限。

有关 Mountpoint 建议权限的更多信息，请参阅 GitHub 上的 [Mountpoint IAM permissions](https://github.com/awslabs/mountpoint-s3/blob/main/doc/CONFIGURATION.md#iam-permissions)。

1. 通过 https://console.aws.amazon.com/iam/ 打开 IAM 控制台。

1. 在左侧导航窗格中，选择 **Policies（策略）**。

1. 在**策略**页面上，选择**创建策略**。

1. 对于**策略编辑器**，选择 **JSON**。

1. 在**策略编辑器**下，复制并粘贴以下内容：
**重要**  
将 `amzn-s3-demo-bucket1` 替换为您自己的 Amazon S3 存储桶名称。

   ```
   {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
           {
               "Sid": "MountpointFullBucketAccess",
               "Effect": "Allow",
               "Action": [
                   "s3:ListBucket"
               ],
               "Resource": [
                   "arn:aws:s3:::amzn-s3-demo-bucket1"
               ]
           },
           {
               "Sid": "MountpointFullObjectAccess",
               "Effect": "Allow",
               "Action": [
                   "s3:GetObject",
                   "s3:PutObject",
                   "s3:AbortMultipartUpload",
                   "s3:DeleteObject"
               ],
               "Resource": [
                   "arn:aws:s3:::amzn-s3-demo-bucket1/*"
               ]
           }
      ]
   }
   ```

   与 Amazon S3 Express One Zone 存储类一起推出的目录存储桶，使用不同于一般用途存储桶的身份验证机制。您应该使用 `s3express:CreateSession` 操作，而非使用 `s3:*` 操作。有关目录存储桶的更多信息，请参阅*《Amazon S3 用户指南》*中的[目录存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/directory-buckets-overview.html)。

   以下是您将对目录存储桶使用的最低权限策略的示例。

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "s3express:CreateSession",
               "Resource": "arn:aws:s3express:us-west-2:111122223333:bucket/amzn-s3-demo-bucket1--usw2-az1--x-s3"
           }
       ]
   }
   ```

1. 选择**下一步**。

1. 在**查看和创建**页面上，为您的策略命名。此示例演练使用名称 `AmazonS3CSIDriverPolicy`。

1. 选择**创建策略**。

## 步骤 2：创建 IAM 角色
<a name="s3-create-iam-role"></a>

适用于 Amazon S3 的 Mountpoint CSI 驱动程序需要 Amazon S3 权限才能与文件系统交互。本节将介绍如何创建 IAM 角色来委派这些权限。要创建此角色，您可以使用以下工具之一：
+  [eksctl](#eksctl_s3_store_app_data) 
+  [AWS 管理控制台](#console_s3_store_app_data) 
+  [AWS CLI](#awscli_s3_store_app_data) 

**注意**  
在上一节中创建了 IAM 策略 `AmazonS3CSIDriverPolicy`。

### eksctl
<a name="eksctl_s3_store_app_data"></a>

 **使用 `eksctl` 创建适用于 Amazon S3 的 Mountpoint CSI 驱动程序 IAM 角色** 

要创建 IAM 角色和 Kubernetes 服务账户，请运行以下命令。这些命令还会将 `AmazonS3CSIDriverPolicy` IAM 策略附加到角色，使用 IAM 角色的 Amazon 资源名称（ARN）对 Kubernetes 服务账户 (`s3-csi-controller-sa`) 进行注释，并将 Kubernetes 服务账户名称添加到 IAM 角色的信任策略。

```
CLUSTER_NAME=my-cluster
REGION=region-code
ROLE_NAME=AmazonEKS_S3_CSI_DriverRole
POLICY_ARN=AmazonEKS_S3_CSI_DriverRole_ARN
eksctl create iamserviceaccount \
    --name s3-csi-driver-sa \
    --namespace kube-system \
    --cluster $CLUSTER_NAME \
    --attach-policy-arn $POLICY_ARN \
    --approve \
    --role-name $ROLE_NAME \
    --region $REGION \
    --role-only
```

### AWS 管理控制台
<a name="console_s3_store_app_data"></a>

1. 通过 https://console.aws.amazon.com/iam/ 打开 IAM 控制台。

1. 在左侧导航窗格中，选择 **Roles**（角色）。

1. 在 **Roles**（角色）页面上，选择 **Create role**（创建角色）。

1. 在 **Select trusted entity**（选择受信任的实体）页面上，请执行以下操作：

   1. 在 **Trusted entity type**（受信任的实体类型）部分中，选择 **Web identity**（Web 身份）。

   1. 对于 **Identity provider**（身份提供商），为您的集群选择 **OpenID Connect provider URL**（OpenID Connect 提供程序 URL）（如 Amazon EKS 中的 **Overview**（概述）下所示）。

      如果未显示 URL，请查看[先决条件](#s3-csi-prereqs)部分。

   1. 对于 **Audience (受众)**，请选择 `sts.amazonaws.com`。

   1. 选择**下一步**。

1. 在 **Add permissions**（添加权限）页面上，请执行以下操作：

   1. 在**筛选策略**框中，输入 AmazonS3CSIDriverPolicy。
**注意**  
在上一节中创建了此策略。

   1. 选中搜索返回的 `AmazonS3CSIDriverPolicy` 结果左侧的复选框。

   1. 选择**下一步**。

1. 在 **Name, review, and create**（命名、查看和创建）页面中，请执行以下操作：

   1. 在**角色名称**中为角色输入唯一名称，例如 AmazonEKS\$1S3\$1CSI\$1DriverRole。

   1. 在**添加标签（可选）**下，将标签作为键值对附加，以将元数据添加到角色。有关在 IAM 中使用标签的更多信息，请参阅《IAM 用户指南》** 中的[标记 IAM 资源](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags.html)。

   1. 选择**创建角色**。

1. 创建角色后，在控制台中选择角色以将其打开进行编辑。

1. 选择 **Trust relationships**（信任关系）选项卡，然后选择 **Edit trust policy**（编辑信任策略）。

1. 该行看起来类似于以下行：

   ```
   "oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com"
   ```

   在上一行末尾添加逗号，然后在逗号后添加下一行。将 *region-code* 替换为您的集群所在的 AWS 区域。将 *EXAMPLED539D4633E53DE1B71EXAMPLE* 替换为您的集群的 OIDC 提供者 ID。

   ```
   "oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:kube-system:s3-csi-driver-sa"
   ```

1. 确保将 `Condition` 运算符设置为 `"StringEquals"`。

1. 选择 **Update policy**（更新策略）以完成操作。

### AWS CLI
<a name="awscli_s3_store_app_data"></a>

1. 查看集群的 OIDC 提供者 URL。将 *my-cluster* 替换为您的集群的名称。如果命令的输出为 `None`，请查看[先决条件](#s3-csi-prereqs)。

   ```
   aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text
   ```

   示例输出如下。

   ```
   https://oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE
   ```

1. 创建 IAM 角色，向 Kubernetes 服务账户授予 `AssumeRoleWithWebIdentity` 操作权限。

   1. 将以下内容复制到名为 `aws-s3-csi-driver-trust-policy.json` 的文件中。请将 *111122223333* 替换为您的账户 ID。将 *EXAMPLED539D4633E53DE1B71EXAMPLE* 和 *region-code* 替换为上一步中返回的值。

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "Federated": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
              "StringEquals": {
                "oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:kube-system:s3-csi-driver-sa",
                "oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com"
              }
            }
          }
        ]
      }
      ```

   1. 创建角色。您可以将 *AmazonEKS\$1S3\$1CSI\$1DriverRole* 更改为其它名称，但如果更改，请确保在后续步骤中也做出相应更改。

      ```
      aws iam create-role \
        --role-name AmazonEKS_S3_CSI_DriverRole \
        --assume-role-policy-document file://"aws-s3-csi-driver-trust-policy.json"
      ```

1. 使用以下命令将之前创建的 IAM 策略附加到角色。

   ```
   aws iam attach-role-policy \
     --policy-arn arn:aws:iam::aws:policy/AmazonS3CSIDriverPolicy \
     --role-name AmazonEKS_S3_CSI_DriverRole
   ```
**注意**  
在上一节中创建了 IAM 策略 `AmazonS3CSIDriverPolicy`。

1. 如果您将驱动程序作为 Amazon EKS 附加组件安装，则跳过此步骤。对于驱动程序自主管理型安装，请创建 Kubernetes 服务账户并使用创建的 IAM 角色的 ARN 进行注释。

   1. 将以下内容保存到名为 `mountpoint-s3-service-account.yaml` 的文件中。请将 *111122223333* 替换为您的账户 ID。

      ```
      ---
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        labels:
          app.kubernetes.io/name: aws-mountpoint-s3-csi-driver
        name: mountpoint-s3-csi-controller-sa
        namespace: kube-system
        annotations:
          eks.amazonaws.com/role-arn: arn:aws:iam::111122223333:role/AmazonEKS_S3_CSI_DriverRole
      ```

   1. 在集群上创建 Kubernetes 服务账户。使用您创建的名为 *AmazonEKS\$1S3\$1CSI\$1DriverRole* 的 IAM 角色对 Kubernetes 服务账户 (`mountpoint-s3-csi-controller-sa`) 进行注释。

      ```
      kubectl apply -f mountpoint-s3-service-account.yaml
      ```
**注意**  
在此过程中部署插件后，系统会创建一个名为 `s3-csi-driver-sa` 的服务账户，并将其配置为使用该服务账户。

## 第 3 步：安装适用于 Amazon S3 的 Mountpoint CSI 驱动程序
<a name="s3-install-driver"></a>

您可以通过 Amazon EKS 附加组件，安装适用于 Amazon S3 的 Mountpoint CSI 驱动程序。您可以使用以下工具将附加组件添加到您的集群。
+  [eksctl](#eksctl_s3_add_store_app_data) 
+  [AWS 管理控制台](#console_s3_add_store_app_data) 
+  [AWS CLI](#awscli_s3_add_store_app_data) 

您也可以将适用于 Amazon S3 的 Mountpoint CSI 驱动程序作为自主管理型安装进行安装。有关执行自主管理型安装的说明，请参阅 GitHub 上的 [Installation](https://github.com/awslabs/mountpoint-s3-csi-driver/blob/main/docs/install.md#deploy-driver)。

从 `v1.8.0` 开始，您可以为 CSI 驱动程序的容器组（pod）配置可容忍的污点。为此，要么使用 `node.tolerations` 指定一组要容忍的自定义污点，要么使用 `node.tolerateAllTaints` 容忍所有污点。有关更多信息，请参阅 Kubernetes 文档中的 [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)。

### eksctl
<a name="eksctl_s3_add_store_app_data"></a>

 **使用 `eksctl` 添加 Amazon S3 CSI 附加组件** 

运行如下命令。将 *my-cluster* 替换为您的集群的名称，将 *111122223333* 替换为您的账户 ID，并将 *AmazonEKS\$1S3\$1CSI\$1DriverRole* 替换为[之前创建的 IAM 角色](#s3-create-iam-role)的名称。

```
eksctl create addon --name aws-mountpoint-s3-csi-driver --cluster my-cluster \
  --service-account-role-arn arn:aws:iam::111122223333:role/AmazonEKS_S3_CSI_DriverRole --force
```

如果您删除 *--force* 选项，并且任何 Amazon EKS 附加组件设置与您的现有设置冲突，那么更新 Amazon EKS 附加组件将会失败，而且您会收到一条帮助您解决冲突的错误消息。在指定此选项之前，请确保 Amazon EKS 附加组件不会管理您需要管理的设置，因为这些设置会被此选项覆盖。有关此设置其他选项的更多信息，请参阅 `eksctl` 文档中的 [Addons](https://eksctl.io/usage/addons/)（附加组件）。有关 Amazon EKS kubernetes 字段管理的更多信息，请参阅[确定可以为 Amazon EKS 附加组件自定义的字段](kubernetes-field-management.md)。

您可以通过配置文件对 `eksctl` 进行自定义。有关更多信息，请参阅 `eksctl` 文档中的[使用配置值](https://eksctl.io/usage/addons/#working-with-configuration-values)。以下示例演示了如何容忍所有污点。

```
# config.yaml
...

addons:
- name: aws-mountpoint-s3-csi-driver
  serviceAccountRoleARN: arn:aws:iam::111122223333:role/AmazonEKS_S3_CSI_DriverRole
  configurationValues: |-
    node:
      tolerateAllTaints: true
```

### AWS 管理控制台
<a name="console_s3_add_store_app_data"></a>

1. 打开 [Amazon EKS 控制台](https://console.aws.amazon.com/eks/home#/clusters)。

1. 在左侧导航窗格中，选择**集群**。

1. 选择要为其配置适用于 Amazon S3 的 Mountpoint CSI 附加组件的集群名称。

1. 选择**附加组件**选项卡。

1. 选择**获取更多附加组件**。

1. 在**选择附加组件**页面上，执行以下操作：

   1. 在 **Amazon EKS 附加组件**部分中，选中**适用于 Amazon S3 的 Mountpoint CSI 驱动程序**复选框。

   1. 选择**下一步**。

1. 在**配置选定的附加组件设置**页面上，执行以下操作：

   1. 选择您想使用的**版本**。

   1. 对于**选择 IAM 角色**，选择要将适用于 Amazon S3 的 Mountpoint CSI 驱动程序 IAM 策略附加到的 IAM 角色的名称。

   1. （可选）展开**可选配置设置**后，更新**冲突解决方法**。如果选择**覆盖**，则可能用 Amazon EKS 附加组件设置覆盖现有附加组件的一个或多个设置。如果不启用此选项，并且与现有设置存在冲突，则操作将失败。您可以使用生成的错误消息对冲突进行故障排除。在选择此选项之前，请确保 Amazon EKS 附加组件不会管理您需要自行管理的设置。

   1. （可选）展开**可选配置设置**后，在**配置值**字段中配置容忍度。

   1. 选择**下一步**。

1. 在**查看和添加**页面上，选择**创建**。附加组件安装完成后，您将看到已安装的附加组件。

### AWS CLI
<a name="awscli_s3_add_store_app_data"></a>

 **使用 AWS CLI 添加适用于 Amazon S3 的 Mountpoint CSI 附加组件** 

运行如下命令。将 *my-cluster* 替换为您的集群的名称，将 *111122223333* 替换为您的账户 ID，并将 *AmazonEKS\$1S3\$1CSI\$1DriverRole* 替换为之前创建的 IAM 角色的名称。

```
aws eks create-addon --cluster-name my-cluster --addon-name aws-mountpoint-s3-csi-driver \
  --service-account-role-arn arn:aws:iam::111122223333:role/AmazonEKS_S3_CSI_DriverRole
```

您可以使用 `--configuration-values` 标志自定义命令。以下替代示例演示了如何容忍所有污点。

```
aws eks create-addon --cluster-name my-cluster --addon-name aws-mountpoint-s3-csi-driver \
  --service-account-role-arn arn:aws:iam::111122223333:role/AmazonEKS_S3_CSI_DriverRole \
  --configuration-values '{"node":{"tolerateAllTaints":true}}'
```

## 第 4 步：配置适用于 Amazon S3 的 Mountpoint
<a name="s3-configure-mountpoint"></a>

在大多数情况下，您可以仅使用存储桶名称来配置适用于 Amazon S3 的 Mountpoint。有关配置适用于 Amazon S3 的 Mountpoint 的说明，请参阅 GitHub 上的 [Configuring Mountpoint for Amazon S3](https://github.com/awslabs/mountpoint-s3/blob/main/doc/CONFIGURATION.md)。

## 第 5 步：部署示例应用程序
<a name="s3-sample-app"></a>

您可以将静态预置部署到现有 Amazon S3 存储桶上的驱动程序。有关更多信息，请参阅 GitHub 上的 [Static provisioning](https://github.com/awslabs/mountpoint-s3-csi-driver/blob/main/examples/kubernetes/static_provisioning/README.md)。

# 移除适用于 Amazon S3 的 Mountpoint Amazon EKS 附加组件
<a name="removing-s3-csi-eks-add-on"></a>

您可以通过两种方法来移除[适用于 Amazon S3 的 Mountpoint CSI 驱动程序](s3-csi.md)。
+  **将附加组件保留在您的集群上** - 此方法将移除 Amazon EKS 对任何设置的管理。还移除 Amazon EKS 通知您更新以及在您启动更新后自动更新 Amazon EKS 附加组件的功能。但是，此方法会保留集群上的附加组件软件。此选项会将附加组件作为自行管理安装使用，而不是作为 Amazon EKS 附加组件使用。使用此方法，附加组件不停机。此过程中的命令使用此选项。
+  **从集群中完全删除附加组件** - 我们建议只有当集群中没有资源依赖于附加组件时，才从集群移除 Amazon EKS 附加组件。要执行此选项，请从您在此过程中使用的命令中删除 `--preserve`。

如果附加组件有与其关联的 IAM 账户，则不会移除该 IAM 账户。

您可以使用以下工具移除 Amazon S3 CSI 附加组件：
+  [eksctl](#eksctl_s3_remove_store_app_data) 
+  [AWS 管理控制台](#console_s3_remove_store_app_data) 
+  [AWS CLI](#awscli_s3_remove_store_app_data) 

## eksctl
<a name="eksctl_s3_remove_store_app_data"></a>

 **使用 `eksctl` 移除 Amazon S3 CSI 附加组件** 

将 *my-cluster* 替换为您的集群的名称，然后运行以下命令。

```
eksctl delete addon --cluster my-cluster --name aws-mountpoint-s3-csi-driver --preserve
```

## AWS 管理控制台
<a name="console_s3_remove_store_app_data"></a>

1. 打开 [Amazon EKS 控制台](https://console.aws.amazon.com/eks/home#/clusters)。

1. 在左侧导航窗格中，选择**集群**。

1. 选择要为其移除 Amazon EBS CSI 附加组件的集群名称。

1. 选择**附加组件**选项卡。

1. 选择**适用于 Amazon S3 的 Mountpoint CSI 驱动程序**。

1. 选择**移除 **。

1. 在**删除：aws-mountpoint-s3-csi-driver** 确认对话框中，执行以下操作：

   1. 如果希望 Amazon EKS 停止管理附加组件设置，请选择**在集群上保留**。如果要在集群上保留附加组件软件，请执行此操作。这样您可以自行管理附加组件的所有设置。

   1. 输入 `aws-mountpoint-s3-csi-driver`。

   1. 选择**移除**。

## AWS CLI
<a name="awscli_s3_remove_store_app_data"></a>

 **使用 AWS CLI 移除 Amazon S3 CSI 附加组件** 

将 *my-cluster* 替换为您的集群的名称，然后运行以下命令。

```
aws eks delete-addon --cluster-name my-cluster --addon-name aws-mountpoint-s3-csi-driver --preserve
```

# 为 CSI 卷启用快照功能
<a name="csi-snapshot-controller"></a>

可借助快照功能创建数据的时间点副本。要在 Kubernetes 中使用此功能，您不仅需要具有支持快照的 CSI 驱动程序（例如 Amazon EBS CSI 驱动程序），同时还需要 CSI 快照控制器。快照控制器可作为 Amazon EKS 托管式附加组件使用，也可以作为自行管理型安装使用。

以下是使用 CSI 快照控制器时需要考虑的一些事项。
+ 快照控制器必须与具有快照功能的 CSI 驱动程序一起安装。有关 Amazon EBS CSI 驱动程序的安装说明，请参阅 [将 Kubernetes 卷存储与 Amazon EBS 结合使用](ebs-csi.md)。
+ Kubernetes 不支持通过 CSI 迁移提供的卷的快照，例如使用 `StorageClass` 和预置器 `kubernetes.io/aws-ebs` 的 Amazon EBS 卷。创建卷时必须使用引用 CSI 驱动程序预置器 `ebs.csi.aws.com` 的 `StorageClass` 创建卷。
+ Amazon EKS 自动模式不包括快照控制器。EKS 自动模式的存储功能与快照控制器兼容。

我们建议通过 Amazon EKS 托管的插件安装 CSI 快照控制器。此附加组件包括在 Amazon EKS 上创建和管理快照所需的自定义资源定义（CRD）。要将 Amazon EKS 附加组件添加到您的集群，请参阅 [创建 Amazon EKS 附加组件](creating-an-add-on.md)。有关附加组件的更多信息，请参阅 [Amazon EKS 附加组件](eks-add-ons.md)。

或者，如果您想对 CSI 快照控制器进行自主管理型安装，请在 GitHub 上参阅上游 Kubernetes `external-snapshotter` 中的 [Usage](https://github.com/kubernetes-csi/external-snapshotter/blob/master/README.md#usage)。