使用卷属性类修改 Kubernetes 上的 Amazon EBS 卷

作者: pmm |

这篇文章由刘凯文(高级 PMT)、Jens-Uwe Walther(高级 STAM-Containers)和 Drew Sirenko(软件开发工程师)共同撰写。

导言

在这篇文章中,我们将探讨如何在不造成应用程序停机的情况下修改 Kubernetes 上的 Amazon 弹性区块存储(Amazon EBS)卷。了解如何使用 VolumeAttributesClass API 以及 Amazon EBS 容器存储接口 (CSI) 驱动来调整预置性能、迁移到 gp3 卷并自动化数据备份工作流程。

使用持久存储(例如数据分析、数据库或视频编码和解码)的现代容器化应用程序需要多种存储特性,例如低延迟、高吞吐量等。Amazon EBS 非常适合这些工作负载。EBS 卷提供不同的存储类型、IOPS 和吞吐量等可配置的存储属性,以及无需停机即可修改这些属性的能力。

如果您在 Kubernetes 上部署有状态容器工作负载,则可以使用 Amazon EBS CSI 驱动程序代表您预置和管理 EBS 卷。当您创建具有指定大小和存储类别 (SC) 的永久卷声明 (PVC) 资源时,Kubernetes 会使用 Amazon EBS CSI 驱动程序,通过代表您创建、附加和格式化 EBS 卷来部署具有必要存储空间的工作负载。

过去,在 Kubernetes 中更改卷的存储特性是一项离线操作,需要集群运营商创建另一个 SC,然后迁移到新的 PVC 和永久卷 (PV) 资源。此过程导致应用程序停机并影响了可用性。这就是为什么亚马逊云科技在 2023 年发布了 k8s 边车的卷修改器,通过对 PVC 应用注解,可以在线更新卷的类型和性能特征。尽管向用户提供解决方案很重要,但亚马逊云科技与其他存储提供商合作创建了批量修改解决方案,该解决方案可作为原生 Kubernetes API 使用。在过去的一年中,亚马逊云科技与 Kubernetes 社区合作发布了 VolumeAttributesClass Kubernetes 增强功能,该增强功能已在 Kubernetes 1.31 中进入测试版。尽管该功能在上游 Kubernetes 中默认处于禁用状态,但它会在您的 Amazon Elastic Kubernetes Service (Amazon EKS) 1.31 集群中自动为您启用。

从 Amazon EKS 1.31 开始,您可以使用 VolumeAttributesClass (VAC) 功能来修改 EBS 卷的卷类型、IOPS 或吞吐量,而无需使用 k8s 边车的卷修改器。此外,您可以使用 VAC 在卷中添加、编辑和删除亚马逊云科技资源标签。当您升级到 1.35.0 或更高版本时,Amazon EBS CSI 驱动程序默认启用此功能。

使用 Amazon EKS 1.31 和 Amazon EBS CSI 驱动程序 1.35.0,你已经可以开始使用 VAC 来代替 PVC 注解了。在接下来的两节中,我们将介绍 VolumeAttributesClasses,并向您展示如何在集群上启用该功能。然后,我们将介绍使用 VAC 修改卷的三种常见工作流程:

  1. 调整卷的吞吐量和每秒输入输出操作数 (IOPS) 性能特征。
  2. 与 gp2 卷相比,迁移到 EBS gp3 卷的每 GB 价格最多可降低 20%。
  3. 使用 Amazon 数据生命周期管理器修改您的 EBS 卷资源标签,以自动执行数据备份工作流程。

解决方案概述

集群操作员可以依靠 Amazon EBS CSI 驱动程序以声明方式管理其永久卷。您可以通过创建具有特定大小、SC 和 VAC 的 PVC 资源来为工作负载请求永久存储。

VAC 由其名称、CSI 驱动程序的驱动程序名称以及特定于存储提供商(例如 Amazon EBS)的可变参数列表组成。

可以在 VAC 资源中指定可变的 EBS 卷参数,例如吞吐量、IOPS、卷类型和亚马逊云科技资源标签:

apiVersion: storage.k8s.io/v1beta1
kind: VolumeAttributesClass
metadata:
  name: ebs-blog-gp3-standard-performance
driverName: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
  tagSpecification_1: "performance=standard"

您可以使用以下 spec.volumeAttributesClassName 字段向 PVC 添加 VAC:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-blog-overview
spec:
  ...
  volumeAttributesClassName: ebs-blog-gp3-standard-performance

使用在 VAC 和 SC 中指定的参数来配置卷,VAC 参数优先于任何冲突的参数。PVC 的 VAC 还会覆盖所有基于注解的修改,并防止将来基于注解的修改。

这种单独的 VAC 资源有利于在运行集群的团队和向集群部署应用程序的团队之间分配职责的组织。集群操作员可以创建集群范围的 SC 和 VAC 对象,然后应用程序开发人员可以在其命名空间 PVC 资源中使用这些对象。

Prerequisites

在 Amazon EKS 1.31 或更高版本中,测试版 VolumeAttributesClass 功能门和 storage.k8s.io/v1beta1 API 组会在集群的控制平面组件上自动启用。此外,你必须使用 Amazon EBS CSI 驱动版本 v1.35.0 或更高版本,该版本由 Amazon EKS 托管插件 v1.35.0-eksbuild.2 或 Helm chart v2.35.1 安装。

如果您运行自管理(例如 KOps)Kubernetes v1.31 集群,则必须在 kube-apiserver、kube-scheduler 和 kube-controller-manager 上启用 VolumeAttributesClass 功能门,并通过 kube-apiserver 运行时配置启用 storage.k8s.io/v1beta1 API 组。

有关要求的完整列表,请参阅 Kubernetes VolumeAttributesClass 文档。

要通过 VAC 修改 Amazon EBS 资源标签,请确保将以下 Amazon Identity and Access Management (IAM) 政策附加到 Amazon EBS CSI 驱动程序使用的角色上:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CreateTags"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:volume/*",
        "arn:aws:ec2:*:*:snapshot/*"
      ]
    }
  ]
}

动手实践

以下步骤将引导您完成此解决方案。

预置卷并提高其性能

默认情况下,Amazon EKS 1.31 不带有 SC。我们必须创建以下 SC:

$ kubectl apply -f - <<EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-blog-sc
provisioner: ebs.csi.aws.com
allowVolumeExpansion: true
EOF

以下是两个示例 VAC 资源,每种资源都有不同的卷服务质量参数:

$ kubectl apply -f - <<EOF
apiVersion: storage.k8s.io/v1beta1
kind: VolumeAttributesClass
metadata:
  name: ebs-blog-gp3-standard-performance
driverName: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
---
apiVersion: storage.k8s.io/v1beta1
kind: VolumeAttributesClass
metadata:
  name: ebs-blog-gp3-increased-performance
driverName: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "4000"
  throughput: "130"
EOF

使用标准性能 VAC 调配卷:

$ kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-blog-claim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-blog-sc
  volumeAttributesClassName: ebs-blog-gp3-standard-performance
  resources:
    requests:
      storage: 10Gi
EOF

为了获得更高的性能,你可以修补 PVC 以指向新的 ebs-blog-gp3-increased-performance VAC:

$ kubectl patch pvc ebs-blog-claim -p '{"spec": { "volumeAttributesClassName": "ebs-blog-gp3-increased-performance" }}'

Amazon EBS CSI 驱动程序观察到 PVC 当前和所需的 VAC 不同,会修改 EBS 容量,并将 PV 资源更新到新的 VAC。

根据 Amazon EBS 文档,您每六小时只能进行一次卷修改。因此,你应该将随着 VAC 更改而增加的 PVC 存储大小合并到一个 Kubernetes 补丁中:

$ kubectl patch pvc ebs-blog-claim --type json -p '[{"op": "replace", "path": "/spec/volumeAttributesClassName", "value": "ebs-blog-gp3-increased-performance" }, {"op": "replace", "path": "/spec/resources/requests/storage", "value": "11Gi"}]'

否则,您会在 PVC 资源上观察到以下故障事件:

VolumeResizeFailed: "pvc-716766d1-58d5-411b-8d4a-7671ef9894e9" by resizer "ebs.csi.aws.com" failed… VolumeModificationRateExceeded: You've reached the maximum modification rate per volume limit. Wait at least 6 hours between modifications per EBS volume.

通过迁移到 gp3 卷来节省成本

VolumeAttributesClasses 可用于在没有 VAC 的情况下创建的现有 PersistentVolumeClaims。这对于从 gp2 卷迁移到 gp3 卷特别有用。EBS gp3 卷允许您独立于存储大小配置 IOPS 和吞吐量。在使用 gp2 卷的任何用例中,您都可以迁移到 gp3 卷,并且由于这种独立性,可以节省高达 20% 的成本。如果您正在寻找更高的性能,则可以将 gp3 卷扩展到 1,000 MIB/s,比 gp2 卷的最大吞吐量高四倍。

在这里,我们创建了一个最初依赖于 gp2 卷的有状态工作负载:

$ kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-blog-migration
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-blog-migration
  resources:
    requests:
      storage: 1Gi
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-blog-migration
provisioner: ebs.csi.aws.com
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer
parameters:
  type: gp2
---
apiVersion: v1
kind: Pod
metadata:
  name: ebs-blog-migration-app
spec:
  containers:
  - name: ebs-blog-app
    image: centos
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo $(date -u) >> /data/out.txt; sleep 5; done"]
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: ebs-blog-migration
EOF

要将此卷迁移到 gp3,请先将 VAC 资源应用到您的集群:

$ kubectl apply -f - <<EOF
apiVersion: storage.k8s.io/v1beta1
kind: VolumeAttributesClass
metadata:
  name: ebs-blog-gp3 
driverName: ebs.csi.aws.com
parameters:
  type: gp3
EOF

然后修补其关联的 PVC

$ kubectl patch pvc ebs-blog-migration -p '{"spec": {"volumeAttributesClassName": "ebs-blog-gp3"}}'

请注意,从 Kubernetes 版本 1.31 开始,您无法通过 VAC 修改引用树内 SC 的卷。确保与您修改的卷关联的 SC 引用的是配置器 ebs.csi.aws.com,而不是 kubernetes.io/aws-ebs

工作流程修改标签

为了便于管理 EBS 卷,您可以使用标签。标签是您分配给亚马逊云科技资源的键值对,使您能够按用途、所有者或环境对它们进行分类。如果您的账户中有许多卷,则标签可以帮助您识别特定卷或对相关资源进行分组。Amazon EBS CSI 驱动程序允许您通过 tagSpecification VAC 参数添加、替换和清除卷资源标签。

除组织外,卷标还可用于 Amazon 数据生命周期管理器政策,以安全地备份您的 EBS 卷。Amazon EBS 快照捕获卷在特定时间点的状态,允许在数据丢失或损坏时进行恢复。要自动创建、保留和删除这些快照,您可以创建针对具有特定资源标签的卷的 Amazon 数据生命周期管理器卷政策。

例如,以下策略创建与 ebs-blog-daily-backup VAC 关联的任何卷的每日快照:

$ aws dlm get-lifecycle-policies
{
    "Policies": [
        {
            "PolicyId": "policy-045203fd0b8e2bf79",
            "Description": "This policy creates daily backups of my K8s PVs",
            "State": "ENABLED",
            "Tags": {
                "backup-interval": "daily"
            },
            "PolicyType": "EBS_SNAPSHOT_MANAGEMENT",
            "DefaultPolicy": false
        }
    ]
}

以下是 VAC 示例,它将为策略的目标标签设置资源标签:

$ kubectl apply -f - <<EOF
apiVersion: storage.k8s.io/v1beta1
kind: VolumeAttributesClass
metadata:
  name: ebs-blog-daily-backup 
driverName: ebs.csi.aws.com
parameters:
  tagSpecification_1: "backup-interval=daily"
EOF

清理

为避免产生更多费用,请删除您为这些示例预置的所有示例 Kubernetes 和亚马逊云科技资源。

删除有状态工作负载示例资源:

kubectl delete pod ebs-blog-migration-app
kubectl delete pvc ebs-blog-claim
kubectl delete pvc ebs-blog-migration
kubectl delete vac ebs-blog-gp3
kubectl delete vac ebs-blog-gp3-increased-performance
kubectl delete vac ebs-blog-gp3-standard-performance
kubectl delete vac ebs-blog-daily-backup 
kubectl delete sc ebs-blog-sc
kubectl delete sc ebs-blog-migration

您可以通过 Amazon Elastic Compute Cloud (Amazon EC2) 控制台确认删除 EBS 卷。

结论

在这篇文章中,我们探讨了如何使用 VolumeAttributesClasses 修改 Kubernetes 上的 Amazon EBS 卷。这项新功能通过更新卷类型、IOPS 和吞吐量,帮助您在不停机应用程序的情况下调整有状态工作负载的性能特征。此外,通过修改资源标签以匹配您的 Amazon 数据生命周期管理器政策,实现数据备份工作流程自动化。

访问 Amazon EBS 产品页面、Amazon EKS 产品页面和 GitHub 上的开源项目,详细了解如何将 EBS 卷用于有状态工作负载。

有关基于注解的修改、VAC 和 SC 之间相互作用的更多信息,请阅读 Amazon EBS CSI 驱动程序常见问题解答。

感谢您阅读这篇文章,请随时在评论部分留下问题或在我们的 GitHub 项目上提交功能请求。


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。