

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 存储
<a name="cost-opt-storage"></a>

## 概览
<a name="_overview"></a>

在某些情况下，您可能需要运行需要在短期或长期基础上保留数据的应用程序。对于此类用例，可以由 Pod 定义和挂载卷，这样它们的容器就可以利用不同的存储机制。Kubernetes 支持不同类型的[卷](https://kubernetes.io/docs/concepts/storage/volumes/)用于临时存储和永久存储。存储的选择在很大程度上取决于应用程序要求。每种方法都有成本影响，下面详细介绍的做法将帮助您在 EKS 环境中为需要某种形式存储的工作负载实现成本效益。

## 短暂卷
<a name="_ephemeral_volumes"></a>

临时卷适用于需要临时本地卷但不需要在重启后保留数据的应用程序。这方面的例子包括对暂存空间、缓存和只读输入数据（如配置数据和机密）的要求。[你可以在这里找到 Kubernetes 临时卷的更多细节。](https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/)大多数临时卷（例如 emptyDir、ConfigMap、downwardAPI、secret、hostpath）都由本地连接的可写入设备（通常是根磁盘）或 RAM 提供支持，因此选择最具成本效益和性能的主机卷非常重要。

### 使用 EBS 卷
<a name="_using_ebs_volumes"></a>

 *我们建议从 [gp3](https://aws.amazon.com/ebs/general-purpose/) 作为主机根卷开始。*它是Amazon EBS提供的最新通用固态硬盘容量，与gp2卷相比，每GB的价格也更低（最高可达20％）。

### 使用亚马逊 EC2 实例存储
<a name="_using_amazon_ec2_instance_stores"></a>

 [Amazon EC2 实例存储](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html)为您的 EC2 实例提供临时块级存储。 EC2 实例存储提供的存储可通过物理连接到主机的磁盘进行访问。与 Amazon EBS 不同，您只能在实例启动时附加实例存储卷，而且这些卷仅在实例的生命周期内存在。它们不能分离并重新连接到其他实例。您可以在此处了解有关 Amazon EC2 实例存储的[更多信息](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html)。*实例存储容量不收取任何额外费用。*这使得它们（实例存储卷）比具有大 EBS 卷的普通 EC2 实例*更具成本效益*。

要在 Kubernetes 中使用本地存储卷，您应该使用 [Amazon EC2 用户数据](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-add-user-data.html)对磁盘进行分区、配置和格式化，以便可以按照 pod 规范安装卷。[HostPath](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath)或者，您可以利用[本地永久卷静态配置器](https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner)来简化本地存储管理。本地永久卷静态配置器允许您通过标准 Kubernetes PersistentVolumeClaim (PVC) 接口访问本地实例存储卷。此外，它还会配置 PersistentVolumes (PVs)，其中包含节点亲和性信息，将 Pod 调度到正确的节点。尽管它使用 Kubernetes PersistentVolumes，但 EC2 实例存储卷本质上是短暂的。写入临时磁盘的数据仅在实例的生命周期内可用。当实例终止时，数据也会终止。有关更多详细信息，请参阅此[博客](https://aws.amazon.com/blogs/containers/eks-persistent-volumes-for-instance-store/)。

请记住，在使用 Amazon EC2 实例存储卷时，总的 IOPS 限制与主机共享，并将 Pod 绑定到特定的主机。在采用 Amazon EC2 实例存储卷之前，您应该仔细检查您的工作负载要求。

## 永久卷
<a name="_persistent_volumes"></a>

Kubernetes 通常与运行无状态应用程序相关联。但是，在某些情况下，您可能需要运行微服务，这些微服务需要将一个请求中的永久数据或信息保留到下一个请求。数据库是此类用例的常见示例。但是，Pod 及其中的容器或进程本质上是短暂的。要在 Pod 的生命周期之后保留数据，您可以使用定义 PVs 对独立于 Pod 的特定位置的存储的访问权限。*与 PVs 之相关的成本在很大程度上取决于所使用的存储类型以及应用程序的使用方式。*

[此处列出了支持 PVs Amazon EKS 上的 Kubernetes 的不同类型的存储选项。](https://docs.aws.amazon.com/eks/latest/userguide/storage.html)下面介绍的存储选项是亚马逊 EBS、Amazon EFS、Amazon for Lustre、Ama FSx zon for ONTA FSx P NetApp 。

### 亚马逊 Elastic Block Store (EBS) Volumes
<a name="_amazon_elastic_block_store_ebs_volumes"></a>

Amazon EBS 卷可以作为 Kubernetes 使用， PVs 以提供块级存储卷。它们非常适合依赖随机读取和写入的数据库，以及执行长时间、连续读取和写入的吞吐量密集型应用程序。[Amazon Elastic Block Store 容器存储接口 (CSI) 驱动程序](https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html)允许 Amazon EKS 集群管理永久卷的 Amazon EBS 卷的生命周期。容器存储接口支持并促进了 Kubernetes 与存储系统之间的交互。将 CSI 驱动程序部署到您的 EKS 集群后，您可以通过原生 Kubernetes 存储资源访问其功能，例如永久卷 (PVs)、永久卷声明 (PVCs) 和存储类别 ()。SCs此[链接](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/tree/master/examples/kubernetes)提供了如何使用亚马逊 EBS CSI 驱动程序与亚马逊 EBS 卷进行交互的实际示例。

#### 选择合适的音量
<a name="_choosing_the_right_volume"></a>

 *我们建议使用最新一代的块存储 (gp3)，因为它在价格和性能之间提供了适当的平衡*。它还允许您独立于卷大小扩展卷 IOPS 和吞吐量，而无需配置额外的块存储容量。如果您目前正在使用 gp2 卷，我们强烈建议您迁移到 gp3 卷。博客文章[将 Amazon EKS 集群从 gp2 迁移到 gp3 EBS 卷解释了如何使用 CSI 卷](https://aws.amazon.com/blogs/containers/migrating-amazon-eks-clusters-from-gp2-to-gp3-ebs-volumes/)快照功能从亚马逊 EKS 集群上的 *gp3 上的 gp* *2* 迁移，并使用需要应用程序停机的 [CSI](https://kubernetes.io/docs/concepts/storage/volume-snapshots/) 卷快照功能进行备份和恢复。

Amazon EBS 允许在线更改卷特征，例如卷大小、IOPS 和吞吐量。[https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/](https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/)

当您的应用程序需要更高的性能并且需要的卷大于单个 [gp3 卷所能支持的容量](https://aws.amazon.com/ebs/general-purpose/)时，您应该考虑使用 [io2](https://aws.amazon.com/ebs/provisioned-iops/) block express。这种类型的存储非常适合规模最大、最 I/O 密集和任务关键型部署，例如 SAP HANA 或其他具有低延迟要求的大型数据库。请记住，实例的 EBS 性能受实例性能限制的限制，因此并非所有实例都支持 io2 block express 卷。您可以在本[文档](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/provisioned-iops.html)中查看支持的实例类型和其他注意事项。

 *一个 gp3 卷最多可以支持最大 16,000 个 IOPS、 MiB/s 最大吞吐量 1,000、最大 16TiB。最新一代的预配置 IOPS 固态硬盘卷，可提供高达 256,000 IOPS、4,000 MiB/s、吞吐量和 64TiB。*

在这些选项中，您应该根据应用程序的需求量身定制存储性能和成本。

#### 随着时间的推移进行监控和优化
<a name="_monitor_and_optimize_over_time"></a>

重要的是要了解应用程序的基准性能并监控所选卷的基准性能，以检查其是否满足您的要求 requirements/expectations 或是否过度配置（例如，未充分利用预配置 IOPS 的情况）。

与其从一开始就分配大卷，不如在积累数据时逐渐增加卷的大小。您可以使用 Amazon Elastic Block Store CSI 驱动程序 () aws-ebs-csi-driver 中的卷[大小调整](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/tree/master/examples/kubernetes/resizing)功能动态调整卷大小。*请记住，您只能增加 EBS 卷的大小。*

要识别和移除任何悬挂的 EBS 卷，您可以使用 AW [S trusted Advisor 的成本优化类别](https://docs.aws.amazon.com/awssupport/latest/user/cost-optimization-checks.html)。此功能可帮助您识别未连接的卷或一段时间内写入活动非常低的卷。有一个名为 [Popeye](https://github.com/derailed/popeye) 的云原生开源只读工具，它可以扫描实时 Kubernetes 集群，并报告已部署资源和配置的潜在问题。例如，它可以扫描未使用的 PVs 和 PVCs 并检查它们是否已绑定或是否存在任何卷装入错误。

要深入了解监控，请参阅 [EKS 成本优化可观察性指南](https://docs.aws.amazon.com/eks/latest/best-practices/cost-opt-observability.html)。

你可以考虑的另一个选择是 [AWS Compute Optimizer Amazon EBS](https://docs.aws.amazon.com/compute-optimizer/latest/ug/view-ebs-recommendations.html) 交易量建议。该工具可自动识别所需的最佳卷配置和正确的性能级别。例如，根据过去 14 天的最大利用率，它可以用于与预配置 IOPS、卷大小和 EBS 卷类型有关的最佳设置。它还量化了根据其建议可能节省的每月成本。您可以查看此[博客](https://aws.amazon.com/blogs/storage/cost-optimizing-amazon-ebs-volumes-using-aws-compute-optimizer/)以获取更多详细信息。

#### 备份保留政策
<a name="_backup_retention_policy"></a>

您可以通过拍摄 point-in-time快照来备份 Amazon EBS 卷上的数据。Amazon EBS CSI 驱动程序支持卷快照。您可以使用此[处](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/examples/kubernetes/snapshot/README.md)概述的步骤学习如何创建快照和恢复 EBS PV。

后续快照是增量备份，这意味着仅保存设备上在最近一次快照后发生更改的块。由于无需复制数据，这将最大限度缩短创建快照所需的时间和增加存储成本节省。但是，在没有适当的保留策略的情况下增加旧 EBS 快照的数量可能会在大规模运营时造成意想不到的成本。如果您通过 AWS API 直接备份亚马逊 EBS 卷，则可以利用亚马逊[数据生命周期管理器 (DLM)，它为亚马逊](https://aws.amazon.com/ebs/data-lifecycle-manager/)弹性区块存储 (EBS) Elastic Block Store 快照和 EBS 支持的亚马逊系统映像 () 提供基于策略的自动生命周期管理解决方案 ()。AMIs通过控制台，可以更轻松地自动创建、保留和删除 EBS 快照和 AMIs。

**注意**  
目前无法通过亚马逊 EBS CSI 驱动程序使用亚马逊 DLM。

在 Kubernetes 环境中，你可以利用名为 [Velero](https://velero.io/) 的开源工具来备份 EBS 永久卷。在安排任务以使备份过期时，您可以设置 TTL 标志。以下是Velero的[指南](https://velero.io/docs/v1.12/how-velero-works/#set-a-backup-to-expire)作为示例。

### Amazon Elastic File System (EFS)
<a name="_amazon_elastic_file_system_efs"></a>

 [Amazon Elastic File System (EFS)](https://aws.amazon.com/efs/) 是一个无服务器、完全弹性的文件系统，允许您使用标准文件系统接口和文件系统语义为各种工作负载和应用程序共享文件数据。工作负载和应用程序的示例包括 Wordpress 和 Drupal、JIRA 和 Git 等开发者工具，以及 Jupyter 等共享笔记本系统以及主目录。

Amazon EFS 的主要优势之一是，它可以由分布在多个节点和多个可用区的多个容器进行安装。另一个好处是，您只需为使用的存储空间付费。EFS 文件系统将在您添加和删除文件时自动增长和缩小，从而无需进行容量规划。

要在 Kubernetes 中使用 Amazon EFS，你需要使用亚马逊弹性文件系统 Elastic File System 容器存储接口 (CSI) 驱动程序。[aws-efs-csi-driver](https://github.com/kubernetes-sigs/aws-efs-csi-driver)目前，驱动程序可以动态创建[接入点](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html)。但是，必须先配置 Amazon EFS 文件系统，并将其作为输入提供给 Kubernetes 存储类参数。

#### 选择正确的 EFS 存储类别
<a name="_choosing_the_right_efs_storage_class"></a>

Amazon EFS 提供[四种存储类别](https://docs.aws.amazon.com/efs/latest/ug/storage-classes.html)。

两个标准存储类别：
+ 亚马逊 EFS 标准
+  [亚马逊 EFS 标准——不频繁访问（EFS 标准-IA）](https://aws.amazon.com/blogs/aws/optimize-storage-cost-with-reduced-pricing-for-amazon-efs-infrequent-access/)

两个单区域存储类别：
+  [亚马逊 EFS One Zone](https://aws.amazon.com/blogs/aws/new-lower-cost-one-zone-storage-classes-for-amazon-elastic-file-system/) 
+ 亚马逊 EFS 单区-不频繁访问 (EFS 单区-IA)

不频繁访问 (IA) 存储类针对并非每天都访问的文件进行了成本优化。借助 Amazon EFS 生命周期管理，您可以将生命周期策略期间（7、14、30、60 或 90 天）未被访问的文件移动到 IA 存储类别，与 *EFS 标准和 EFS One Zone 存储类别相比，存储成本可分别降低多达 92%*。

借助 EFS Intelligent-Tiering，生命周期管理可以监控文件系统的访问模式，并自动将文件移动到最佳存储类别。

**注意**  
aws-efs-csi-driver 目前无法控制更改存储类别、生命周期管理或智能分层。应在 AWS 控制台中手动设置或通过 EFS 进行设置 APIs。

**注意**  
aws-efs-csi-driver 与基于 Windows 的容器镜像不兼容。

**注意**  
启用 *vol-metrics-opt-in*（发出音量指标）时存在已知的内存问题，这是因为该[DiskUsage](https://github.com/kubernetes/kubernetes/blob/ee265c92fec40cd69d1de010b477717e4c142492/pkg/volume/util/fs/fs.go#L66)功能消耗的内存量与文件系统的大小成正比。*目前，我们建议在大型文件系统上禁用 vol-metrics-opt-in* *`--`选项，以免消耗太多内存。以下是 github 问题[链接](https://github.com/kubernetes-sigs/aws-efs-csi-driver/issues/1104)，了解更多详情。*

### 亚马逊 f FSx or Lustre
<a name="_amazon_fsx_for_lustre"></a>

Lustre 是一种高性能并行文件系统，通常用于需要高达数百的吞吐量 GB/s 和亚毫秒的每次操作延迟的工作负载。它用于机器学习训练、财务建模、HPC 和视频处理等场景。[Amazon FSx for Lustre](https://aws.amazon.com/fsx/lustre/) 提供完全托管的共享存储，具有可扩展性和性能，并与 Amazon S3 无缝集成。

你可以使用 Amazon EKS 的 for Lustre [CSI 驱动程序或 AWS 上 FSx 自行管理的 Kubernetes 集群，使用由 for Lustre FSx 提供](https://github.com/kubernetes-sigs/aws-fsx-csi-driver)的 Kubernetes 永久存储卷。有关更多详细信息和示例，请参阅 [Amazon EKS 文档](https://docs.aws.amazon.com/eks/latest/userguide/fsx-csi.html)。

#### 链接到亚马逊 S3
<a name="_link_to_amazon_s3"></a>

建议将驻留在 Amazon S3 上的高度持久的长期数据存储库与 for Lustre 文件系统关联起来。 FSx 链接后，大型数据集将根据需要从 Amazon S3 延迟加载到 FSx Lustre 文件系统。您也可以将分析和结果运行回 S3，然后删除 Lustre 文件系统。

#### 选择正确的部署和存储选项
<a name="_choosing_the_right_deployment_and_storage_options"></a>

FSx for Lustre 提供了不同的部署选项。第一个选项叫做 s *cratch*，它不复制数据，而第二个选项叫做 persi *st* ent，顾名思义，它可以保留数据。

第一个选项（*从头开始*）可用于*降低临时短期数据处理的成本*。永久部署选项*专为长期存储而设计*，可自动复制 AWS 可用区域内的数据。它还支持固态硬盘和硬盘存储。

你可以在 lustre 文件系统的 Kubernetes FSx 的参数下配置所需的部署类型。 StorageClass以下是提供示例模板的[链接](https://github.com/kubernetes-sigs/aws-fsx-csi-driver/tree/master/examples/kubernetes/dynamic_provisioning#edit-storageclass)。

**注意**  
对于延迟敏感型工作负载或需要最高 IOPS/吞吐量级别的工作负载，您应该选择 SSD 存储。对于以吞吐量为重点且对延迟不敏感的工作负载，您应该选择 HDD 存储。

#### 启用数据压缩
<a name="_enable_data_compression"></a>

也可以通过将 “LZ4” 指定为数据压缩类型，在文件系统上启用数据压缩。启用后，所有新写入的文件将在写入磁盘之前自动压缩 Lustre，并在读取时解压缩。 FSx LZ4 数据压缩算法是无损的，因此可以从压缩的数据中完全重建原始数据。

你可以在 for lustre 文件系统的 Kubernet FSx es 的参数 LZ4 下配置数据压缩类型。 StorageClass当该值设置为 NONE（默认值）时，压缩功能处于禁用状态。此[链接](https://github.com/kubernetes-sigs/aws-fsx-csi-driver/tree/master/examples/kubernetes/dynamic_provisioning#edit-storageclass)提供示例模板。

**注意**  
Amazon FSx for Lustre 与基于 Windows 的容器镜像不兼容。

### FSx 适用于 NetApp ONTAP 的亚马逊
<a name="_amazon_fsx_for_netapp_ontap"></a>

 [Amazon FSx f NetApp or ONTAP](https://aws.amazon.com/fsx/netapp-ontap/) 是一个完全托管的共享存储，建立在 ONTAP 文件系统 NetApp之上。 FSx for ONTAP 提供功能丰富、快速、灵活的共享文件存储，可通过在 AWS 或本地运行的 Linux、Windows 和 macOS 计算实例进行广泛访问。

Amazon FSx NetApp for ONTAP 支持两个存储层：*1/主层*和 *2/容量池*层。

*主层*是基于固态硬盘的高性能预配置层，用于存放对延迟敏感的活跃数据。完全弹性的*容量池层*针对不经常访问的数据进行了成本优化，可随着数据分层到该层而自动扩展，并提供几乎无限的 PB 容量。您可以在容量池存储上启用数据压缩和重复数据删除，从而进一步减少数据消耗的存储容量。 NetApp基于策略的本机 FabricPool 功能可持续监控数据访问模式，自动在存储层之间双向传输数据以优化性能和成本。

NetApp的 Astra Trident 使用 CSI 驱动程序提供动态存储编排，该驱动程序允许 Amazon EKS 集群管理亚马逊支持的 FSx 适用于 NetApp ONTAP 文件 PVs 系统的永久卷的生命周期。要开始使用，请参阅 [Astra Trident 文档中的在亚马逊 FSx 上使用 Astra Trident for NetApp ONTAP](https://docs.netapp.com/us-en/trident/trident-use/trident-fsx.html)。

## 其他考虑因素
<a name="_other_considerations"></a>

### 最小化容器镜像的大小
<a name="_minimize_the_size_of_container_image"></a>

部署容器后，容器镜像将作为多层缓存在主机上。通过减小图像的大小，可以减少主机上所需的存储量。

通过从一开始就使用精简版的基础映像，例如暂存映像或[无发行版](https://github.com/GoogleContainerTools/distroless)容器镜像（仅包含您的应用程序及其运行时依赖项），*除了可以减少攻击面积和缩短图像提取时间等其他附带优势外，还可以降低存储成本*。

您还应该考虑使用开源工具，例如 [Slim.ai](https://www.slim.ai/docs/quickstart)，它提供了一种简单、安全的方法来创建最少的图像。

多层包、工具、应用程序依赖关系、库可以很容易地膨胀容器镜像的大小。通过使用多阶段构建，您可以有选择地将工件从一个阶段复制到另一个阶段，将最终图像中不需要的所有内容排除在外。[您可以在此处查看更多图像构建最佳实践。](https://docs.docker.com/get-started/09_image_best/)

需要考虑的另一件事是将缓存的图像保留多长时间。当使用一定数量的磁盘时，您可能需要从图像缓存中清理陈旧的图像。这样做将有助于确保有足够的空间供主机操作。默认情况下，[kubelet](https://kubernetes.io/docs/reference/generated/kubelet) 每五分钟对未使用的图像执行一次垃圾回收，每分钟对未使用的容器执行一次垃圾回收。

 *要为未使用的容器和镜像垃圾收集配置选项，请使用[配置文件](https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/)调整 kubelet，并使用[https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/)资源类型更改与垃圾收集相关的参数。*

[你可以在 Kubernetes 文档中了解更多相关信息。](https://kubernetes.io/docs/concepts/architecture/garbage-collection/#containers-images)