你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

Azure Kubernetes 服务 (AKS) 中的应用程序存储选项

在 Azure Kubernetes 服务 (AKS) 中运行的应用程序可能需要存储和检索数据。 虽然某些应用程序工作负载可以在不需要的已清空节点上使用本地快速存储,但其他工作负载需要在 Azure 平台中更常规的数据卷上持久的存储。

多个 pod 可能需要:

  • 共享相同的数据卷。
  • 重新附加数据卷(如果在不同节点上重新计划 pod)。

你也可能需要收集敏感数据或应用程序配置信息并将其存储到 Pod 中。

本文介绍为 AKS 中的应用程序提供存储的核心概念:

此图显示 Azure Kubernetes 服务 (AKS) 群集中的应用程序存储选项。

默认 OS 磁盘大小调整

在创建新群集或向现有群集添加新节点池时,OS 磁盘大小默认由 vCPU 数确定。 vCPU 数量根据 VM SKU 来决定。 下表列出了每个 VM SKU 的默认 OS 磁盘大小:

VM SKU 核心 (vCPU) 默认 OS 磁盘层 预配的 IOPS 预配吞吐量 (Mbps)
1 - 7 P10/128G 500 100
8 - 15 P15/256G 1100 125
16 - 63 P20/512G 2300 150
64+ P30/1024G 5000 200

重要

仅当不支持临时 OS 磁盘且未指定默认 OS 磁盘大小时,才在新的群集或节点池上使用默认 OS 磁盘大小调整。 默认 OS 磁盘大小可能会影响群集的性能或成本。 创建群集或节点池后,无法更改 OS 磁盘大小。 此默认磁盘大小会影响 2022 年 7 月或之后创建的群集或节点池。

临时 OS 磁盘

默认情况下,Azure 会自动将虚拟机的操作系统磁盘复制到 Azure 存储,以避免在 VM 重定位到另一台主机时丢失数据。 但是,由于容器并未设计为保留本地状态,因此该行为提供的价值有限且存在一些缺点。 这些缺点包括但不限于节点预配速度变慢和读/写延迟变高。

相比而言,临时 OS 磁盘只存储在主机上,就像临时磁盘一样。 使用此配置,可以获得更低的读/写延迟,以及更快的节点扩展和群集升级。

备注

当不显式请求用于 OS 的 Azure 托管磁盘时,在可能的情况下,AKS 会针对给定的节点池配置默认为临时 OS。

Azure VM 文档中提供了临时 OS 磁盘的大小要求和建议。 以下是一些一般尺寸注意事项:

  • 如果选择使用默认 OS 磁盘大小为 100 GiB 的 AKS 默认 VM 大小 Standard_DS2_v2 SKU,则默认 VM 大小支持临时 OS,但缓存大小只有 86 GiB。 若不显式指定该配置,则默认为托管磁盘。 若请求了临时 OS,你会收到验证错误。

  • 如果请求 OS 磁盘大小为 60 GiB 的同一 Standard_DS2_v2 SKU,则此配置将默认为临时 OS。 请求的 60 GiB 大小小于最大 86 GiB 缓存大小。

  • 如果选择 OS 磁盘大小为 100 GB 的 Standard_D8s_v3 SKU,则此 VM 大小支持临时 OS,并且具有 200 GiB 的缓存空间。 如果未指定 OS 磁盘类型,则默认情况下,节点池会收到临时 OS。

最新一代 VM 系列没有专用缓存,而只有临时存储。 例如,如果选择 Standard_E2bds_v5 VM 大小,默认 OS 磁盘大小为 100 GiB,则它支持临时 OS 磁盘,但只有 75 GB 的临时存储。 如果你不显式指定它,此配置默认为 OS 托管磁盘。 若请求了临时 OS 磁盘,你会收到验证错误。

  • 如果请求 OS 磁盘大小为 60 GiB 的同一 Standard_E2bds_v5 VM 大小,则此配置将默认为临时 OS 磁盘。 请求的 60 GiB 大小小于 75 GiB 的最大临时存储。

  • 如果选择 OS 磁盘大小为 100 GiB 的 Standard_E4bds_v5 SKU,则此 VM 大小支持临时 OS,并且具有 150 GiB 的临时存储空间。 如果你未指定 OS 磁盘类型,则默认情况下,Azure 会将临时 OS 磁盘预配到节点池。

客户管理的密钥

可以在 AKS 群集上使用自己的密钥管理临时 OS 磁盘的加密。 有关详细信息,请参阅在 AKS 上将客户管理的密钥与 Azure 磁盘配合使用

Kubernetes 通常将各个 pod 视为短暂的可处置资源。 应用程序可使用不同的方法来使用和保持数据。 表示一种跨 Pod 和应用程序生命周期存储、检索及保存数据的方法。

传统卷作为 Azure 存储支持的 Kubernetes 资源进行创建。 你可以手动创建数据卷以直接分配给 Pod,也可以让 Kubernetes 自动创建它们。 数据卷可以使用:Azure 磁盘Azure 文件存储Azure NetApp 文件Azure Blob

注意

根据所使用的 VM SKU,Azure 磁盘 CSI 驱动程序可能具有每节点的卷限制。 对于某些高性能 VM(例如,16 核),上限为每个节点 64 个卷。 若要确定每个 VM SKU 的限制,请查看提供的每个 VM SKU 的“最大数据磁盘数”列。 有关提供的 VM SKU 及其相应的详细容量限制的列表,请参阅常规用途虚拟机大小

为帮助确定 Azure 文件存储与 Azure NetApp 文件哪个最适合你的工作负载,请查看 Azure 文件存储和 Azure NetApp 文件比较一文中提供的信息。

Azure 磁盘

使用 Azure 磁盘可创建 Kubernetes DataDisk 资源。 磁盘类型包括:

  • 高级 SSD(适用于大多数工作负载)
  • 超级磁盘
  • 标准 SSD
  • 标准 HDD

提示

对于大部分生产和开发工作负载,请使用高级 SSD。

由于 Azure 磁盘是以 ReadWriteOnce 的形式装载的,因此仅可用于单个节点。 对于可由多个节点上的 Pod 同时访问的存储卷,请使用 Azure 文件存储。

Azure 文件

使用 Azure 文件存储装载服务器消息块 (SMB) 3.1.1 版共享或网络文件系统 (NFS) 4.1 版共享。 借助 Azure 文件存储可跨多个节点和 Pod 共享数据,并且可以使用以下功能:

  • 由高性能 SSD 支持的 Azure 高级存储
  • 由普通 HDD 支持的 Azure 标准存储

Azure NetApp 文件

  • 超级存储
  • 高级存储
  • 标准存储

Azure Blob 存储

使用 Azure Blob 存储创建 Blob 存储容器,并使用 NFS v3.0 协议或 BlobFuse 装载它。

  • 块 Blob

卷类型

Kubernetes 卷不仅仅表示用于存储和检索信息的传统磁盘。 Kubernetes 卷还可以用于将数据注入 Pod 以供容器使用。

Kubernetes 中常见的卷类型包括:

emptyDir

通常用作 Pod 的临时空间。 Pod 中的所有容器都可以访问卷上的数据。 写入此卷类型的数据仅在 Pod 的生命周期内持续保存。 删除 Pod 后,卷也会删除。 此卷通常使用基础本地节点磁盘存储,但它也可以仅存在于节点的内存中。

secret

可以使用 secret 卷将敏感数据注入 Pod,例如密码。

  1. 使用 Kubernetes API 创建机密。
  2. 定义 pod 或部署,并请求特定机密。
    • 机密只会提供给具有需要它们的计划 pod 的节点。
    • 机密存储在 tmpfs 中,而不是写入磁盘
  3. 删除节点上最后一个需要机密的 Pod 后,会从节点的 tmpfs 中删除机密。
    • 机密存储在给定的命名空间内,并且只能由同一命名空间中的 Pod 访问。

configMap

可以使用 configMap 将键值对属性注入 Pod,例如应用程序配置信息。 将应用程序配置信息定义为 Kubernetes 资源(可在部署 pod 的新实例时轻松更新并应用于它们)。

例如使用机密:

  1. 使用 Kubernetes API 创建 ConfigMap。
  2. 在定义 pod 或部署时请求 ConfigMap。
    • ConfigMap 存储在给定命名空间内,并且只能由同一命名空间中的 Pod 访问。

永久性卷

作为 Pod 生命周期的一部分定义和创建的卷仅在删除 Pod 之前存在。 如果在维护事件期间(尤其是在 StatefulSets 中)于另一台主机上重新计划 Pod,则 Pod 通常会预期其存储会被保留。 永久性卷 (PV) 是由 Kubernetes API 创建和管理的存储资源,可以在单个 Pod 的生命周期之外存在。

可以使用以下 Azure 存储服务来提供永久性卷:

部分所述,选择 Azure 磁盘还是 Azure 文件存储通常取决于对并发访问数据或性能层的需求。

此图显示 Azure Kubernetes 服务 (AKS) 群集中的永久性卷。

可以让群集管理员静态创建永久性卷,也可以通过 Kubernetes API 服务器动态创建卷。 如果 Pod 进行了计划并请求当前不可用的存储,则 Kubernetes 可以创建基础 Azure 磁盘或文件存储并将其附加到 Pod。 动态预配使用存储类来标识需要创建的资源类型

重要

Windows Pod 和 Linux Pod 无法共享永久性卷,因为两种操作系统之间的文件系统支持有区别。

如果需要完全托管的解决方案来对数据进行块级访问,请考虑使用 Azure 容器存储,而不是 CSI 驱动程序。 Azure 容器存储与 Kubernetes 集成,支持动态和自动预配永久性卷。 Azure 容器存储支持将 Azure 磁盘、临时磁盘和 Azure 弹性 SAN(预览版)作为备份存储,为 Kubernetes 群集上运行的有状态应用程序提供了灵活性和可伸缩性。

存储类

若要定义不同的存储层(例如高级和标准),可创建存储类

存储类还定义了回收策略。 当你删除永久性卷时,回收策略会控制基础 Azure 存储资源的行为。 可删除基础资源,也可保留基础存储资源以便与未来的 Pod 配合使用。

对于使用 Azure 容器存储的群集,你将看到名为 acstor-<storage-pool-name> 的其他存储类。 还会创建内部存储类。

对于使用容器存储接口 (CSI) 驱动程序的群集,将创建以下额外的存储类:

存储类 说明
managed-csi 使用 Azure Standard SSD 本地冗余存储 (LRS) 创建托管磁盘。 回收策略确保在删除使用基础 Azure 磁盘的持久卷时会删除该磁盘。 存储类还会将永久性卷配置为可扩展。 可以编辑永久性卷声明以指定新大小。 从 Kubernetes 版本 1.29 开始,在跨多个可用性区域部署的 Azure Kubernetes 服务 (AKS) 群集中,此存储类利用 Azure 标准 SSD 区域冗余存储 (ZRS) 来创建托管磁盘。
managed-csi-premium 使用 Azure 高级本地冗余存储 (LRS) 创建托管磁盘。 同样,回收策略确保在删除使用基础 Azure 磁盘的持久卷时会删除该磁盘。 同样,此存储类也允许扩展永久卷。 从 Kubernetes 版本 1.29 开始,在跨多个可用性区域部署的 Azure Kubernetes 服务 (AKS) 群集中,此存储类利用 Azure 高级区域冗余存储 (ZRS) 来创建托管磁盘。
azurefile-csi 使用 Azure 标准存储创建 Azure 文件共享。 回收策略确保在删除使用基础 Azure 文件共享的永久卷时会删除该文件共享。
azurefile-csi-premium 使用 Azure 高级存储创建 Azure 文件共享。 回收策略确保在删除使用基础 Azure 文件共享的永久卷时会删除该文件共享。
azureblob-nfs-premium 使用 Azure 高级存储创建 Azure Blob 存储容器并使用 NFS v3 协议进行连接。 回收策略确保在删除使用基础 Azure Blob 存储容器的永久卷时会删除该文件共享。
azureblob-fuse-premium 使用 Azure 高级存储创建 Azure Blob 存储容器并使用 BlobFuse 进行连接。 回收策略确保在删除使用基础 Azure Blob 存储容器的永久卷时会删除该文件共享。

除非为永久性卷指定存储类,否则将使用默认存储类。 请求永久性卷时,请确保卷使用你需要的适当存储。

重要

从 Kubernetes 版本 1.21 开始,AKS 默认使用 CSI 驱动程序,并且启用了 CSI 迁移。 尽管现有的树内永久性卷继续正常运行,但从版本 1.26 开始,AKS 将不再支持使用树内驱动程序创建的卷以及为文件和磁盘预配的存储。

default 类将与 managed-csi 相同。

从 Kubernetes 版本 1.29 开始,跨多个可用性区域部署 Azure Kubernetes 服务 (AKS) 群集时,AKS 现在利用区域冗余存储 (ZRS) 在内置存储类中创建托管磁盘。 ZRS 确保在所选区域中的多个 Azure 可用性区域之间同步复制 Azure 托管磁盘。 此冗余策略可增强应用程序的复原能力,并保护数据免受数据中心故障的影响。

但是,请务必注意,与本地冗余存储 (LRS) 相比,区域冗余存储 (ZRS) 的成本更高。 如果优先考虑成本优化,则可以将 skuname 参数设置为 LRS,创建新的存储类。 然后,可以在永久性卷声明 (PVC) 中使用这个新存储类。

你可以使用 kubectl 来创建用于满足其他需求的存储类。 以下示例使用高级托管磁盘并指定在删除 Pod 时应该保留基础 Azure 磁盘

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-premium-retain
provisioner: disk.csi.azure.com
parameters:
  skuName: Premium_ZRS
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

注意

AKS 会协调默认存储类,并将覆盖你对这些存储类所做的任何更改。

有关存储类的详细信息,请参阅 Kubernetes 中的 StorageClass

永久性卷声明

永久性卷声明 (PVC) 会请求特定存储类、访问模式和大小的存储。 如果根据定义的存储类没有现有资源可以实现声明,Kubernetes API 服务器可动态预配基础 Azure 存储资源。

卷连接到 Pod 后,Pod 定义即会包含装载。

此图显示 Azure Kubernetes 服务 (AKS) 群集中的永久性卷声明。

可用存储资源分配给请求存储的 Pod 后,永久性卷就会绑定到永久性卷声明。 永久性卷会一对一映射到声明。

以下示例 YAML 清单显示使用 managed-premium 存储类并请求 5Gi Azure 磁盘的永久性卷声明

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: azure-managed-disk
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: managed-premium-retain
  resources:
    requests:
      storage: 5Gi

创建 pod 定义时,还需指定:

  • 用于请求所需存储的永久性卷声明。
  • 供应用程序用于读取和写入数据的卷装载

以下示例 YAML 清单说明如何使用先前的永久性卷声明来将卷装载到 /mnt/azure

kind: Pod
apiVersion: v1
metadata:
  name: nginx
spec:
  containers:
    - name: myfrontend
      image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine
      volumeMounts:
      - mountPath: "/mnt/azure"
        name: volume
  volumes:
    - name: volume
      persistentVolumeClaim:
        claimName: azure-managed-disk

若要在 Windows 容器中装载卷,请指定驱动器号和路径。 例如:

...      
      volumeMounts:
      - mountPath: "d:"
        name: volume
      - mountPath: "c:\k"
        name: k-dir
...

后续步骤

有关相关的最佳做法,请参阅 AKS 中存储和备份的最佳做法AKS 存储注意事项

有关 Azure 容器存储的详细信息,请参阅以下文章:

有关使用 CSI 驱动程序的详细信息,请参阅以下文章:

有关核心 Kubernetes 和 AKS 概念的详细信息,请参阅以下文章: