你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
将 Azure 容器存储与本地 NVMe 和卷复制功能配合使用
Azure 容器存储是一项基于云的卷管理、部署和业务流程服务,专为容器原生构建。 本文介绍了如何配置 Azure 容器存储,以使用带有本地 NVMe 和卷复制功能的临时磁盘作为 Kubernetes 工作负载的后端存储。 最后,你将得到一个使用本地 NVMe 作为其存储的 Pod。 复制在不同节点上跨卷复制数据,并在副本丢失时还原卷,从而为临时磁盘提供复原能力。
什么是临时磁盘?
当应用程序需要亚毫秒存储延迟时,可以将临时磁盘与 Azure 容器存储配合使用以满足性能要求。 临时意味着磁盘部署在托管 AKS 群集的本地虚拟机 (VM) 上,而不是保存到 Azure 存储服务。 如果停止/解除分配 VM,这些磁盘上的数据将会丢失。
有两种类型的临时磁盘可用:本地 NVMe 和临时 SSD。 NVMe 专为存储和 CPU 之间的高速数据传输而设计。 当应用程序需要比临时 SSD 更高的 IOPS 或吞吐量,或者需要更多的存储空间时,可以选择 NVMe。 请注意,Azure 容器存储仅支持本地 NVMe 的同步数据复制。
由于这些磁盘的临时特性,Azure 容器存储在使用临时磁盘时默认支持使用通用临时卷。 不过,即使数据不具有持久性,某些用例也可能需要持久卷;例如,如果希望使用现有的 YAML 文件或部署模板,而这些文件或模板已硬编码为使用持久卷,并且工作负载支持应用程序级复制以实现持久性,就会出现这种情况。 在这种情况下,可以更新 Azure 容器存储安装,并在持久卷声明定义中添加注释 acstor.azure.com/accept-ephemeral-storage=true
,以支持从临时磁盘存储池创建持久卷。
先决条件
如果没有 Azure 订阅,请在开始之前创建一个免费帐户。
本文需要 Azure CLI 的最新版本(2.35.0 或更高版本)。 请参阅如何安装 Azure CLI。 如果你在 Azure Cloud Shell 中使用 Bash 环境,则表示已安装最新版本。 如果你打算在本地(而不是 Azure Cloud Shell 中)运行命令,请务必使用管理员权限运行命令。 有关详细信息,请参阅开始使用 Azure Cloud Shell。
你将需要 Kubernetes 命令行客户端
kubectl
。 如果你使用的是 Azure Cloud Shell,则它已安装,或者可以通过运行az aks install-cli
命令在本地安装它。如果尚未安装 Azure 容器存储,请按照将 Azure 容器存储与 Azure Kubernetes 服务配合使用中的说明进行操作。
检查 Azure 容器存储区域是否支持你的目标区域。
选择一个支持本地 NVMe 的 VM 类型
临时磁盘仅在某些类型的 VM 中可用。 如果你打算使用本地 NVMe,则需要一个存储优化 VM,例如 standard_l8s_v3。
运行以下命令来获取与节点池一起使用的 VM 类型。 将 <resource group>
和 <cluster name>
替换为自己的值。 无需为 PoolName
或 VmSize
提供值,因此请如下所示保留查询。
az aks nodepool list --resource-group <resource group> --cluster-name <cluster name> --query "[].{PoolName:name, VmSize:vmSize}" -o table
下面是输出的示例。
PoolName VmSize
---------- ---------------
nodepool1 standard_l8s_v3
我们建议每个 VM 至少有四个虚拟 CPU (vCPU),每个节点池至少有三个节点。
创建和附加通用临时卷
按照以下步骤创建并附加通用临时卷。
1.创建带有卷复制功能的存储池
首先,通过在 YAML 清单文件中定义存储池来创建存储池,这是 Kubernetes 群集的存储的逻辑分组。
如果使用 az aks create
或 az aks update
命令启用 Azure 容器存储,你可能已有存储池。 使用 kubectl get sp -n acstor
获取存储池的列表。 如果已有要使用的存储池,可以跳过本部分,然后转到显示可用的存储类。
按照以下步骤使用本地 NVMe 和复制创建存储池。 Azure 容器存储目前支持三个副本和五个副本配置。 如果指定三个副本,则 AKS 群集中必须至少有三个节点。 如果指定五个副本,则必须至少有五个节点。
注意
由于临时磁盘存储池会占用所有可用的 NVMe 磁盘,因此必须先删除任何现有的本地 NVMe 存储池,然后再创建新存储池。
使用最喜爱的文本编辑器创建 YAML 清单文件,例如
code acstor-storagepool.yaml
。粘贴以下代码并保存文件。 存储池名称值可以是所需的任何内容。
apiVersion: containerstorage.azure.com/v1 kind: StoragePool metadata: name: ephemeraldisk-nvme namespace: acstor spec: poolType: ephemeralDisk: diskType: nvme replicas: 3
应用 YAML 清单文件以创建存储池。
kubectl apply -f acstor-storagepool.yaml
存储池创建完成后,将会看到如下消息:
storagepool.containerstorage.azure.com/ephemeraldisk-nvme created
还可以运行此命令来检查存储池的状态。 将
<storage-pool-name>
替换为存储池名称值。 在本示例中,该值为 ephemeraldisk-nvme。kubectl describe sp <storage-pool-name> -n acstor
创建存储池后,Azure 容器存储将使用命名约定 acstor-<storage-pool-name>
代表你创建存储类。
2.显示可用的存储类
当存储池可供使用时,必须选择存储类来定义在创建和部署卷时如何动态创建存储。
运行 kubectl get sc
以显示可用的存储类。 应会看到名为 acstor-<storage-pool-name>
的存储类。
$ kubectl get sc | grep "^acstor-"
acstor-azuredisk-internal disk.csi.azure.com Retain WaitForFirstConsumer true 65m
acstor-ephemeraldisk-nvme containerstorage.csi.azure.com Delete WaitForFirstConsumer true 2m27s
重要
请勿使用标记为内部的存储类。 它是 Azure 容器存储正常运行所需的内部存储类。
3.使用通用临时卷部署 Pod
使用 Fio(灵活 I/O 测试器)创建 Pod 来进行基准测试和工作负载模拟 - Fio 使用通用临时卷。
使用最喜爱的文本编辑器创建 YAML 清单文件,例如
code acstor-pod.yaml
。粘贴以下代码并保存文件。
kind: Pod apiVersion: v1 metadata: name: fiopod spec: nodeSelector: acstor.azure.com/io-engine: acstor containers: - name: fio image: nixery.dev/shell/fio args: - sleep - "1000000" volumeMounts: - mountPath: "/volume" name: ephemeralvolume volumes: - name: ephemeralvolume ephemeral: volumeClaimTemplate: metadata: labels: type: my-ephemeral-volume spec: accessModes: [ "ReadWriteOnce" ] storageClassName: acstor-ephemeraldisk-nvme # replace with the name of your storage class if different resources: requests: storage: 1Gi
更改卷的存储大小时,请确保该大小应小于单个节点临时磁盘的可用容量。 请参阅检查节点临时磁盘容量。
应用 YAML 清单文件以部署 Pod。
kubectl apply -f acstor-pod.yaml
应该会看到与下面类似的输出:
pod/fiopod created
检查 Pod 是否正在运行,以及临时卷声明是否已成功绑定到 Pod:
kubectl describe pod fiopod kubectl describe pvc fiopod-ephemeralvolume
检查 fio 测试以查看其当前状态:
kubectl exec -it fiopod -- fio --name=benchtest --size=800m --filename=/volume/test --direct=1 --rw=randrw --ioengine=libaio --bs=4k --iodepth=16 --numjobs=8 --time_based --runtime=60
现在,你已部署了一个 Pod,它使用带有卷复制功能的本地 NVMe,并且可以用于 Kubernetes 工作负载。
创建并附加永久性卷
若要从临时磁盘存储池创建持久卷,必须在持久卷声明 (PVC) 中包含注释作为保障措施,以确保即使数据是临时的,你也打算使用持久卷。 此外,在创建持久卷声明之前,需要在群集上启用 --ephemeral-disk-volume-type
标记,并将其设置为 PersistentVolumeWithAnnotation
值。
按照以下步骤创建并附加永久性卷。
1.更新 Azure 容器存储安装
运行以下命令来更新 Azure 容器存储安装,以允许从临时磁盘存储池创建持久卷。
az aks update -n <cluster-name> -g <resource-group> --enable-azure-container-storage ephemeralDisk --storage-pool-option NVMe --ephemeral-disk-volume-type PersistentVolumeWithAnnotation
2.创建带有卷复制功能的存储池
按照以下步骤使用本地 NVMe 和复制创建存储池。 Azure 容器存储目前支持三个副本和五个副本配置。 如果指定三个副本,则 AKS 群集中必须至少有三个节点。 如果指定五个副本,则必须至少有五个节点。
注意
由于临时磁盘存储池会占用所有可用的 NVMe 磁盘,因此必须先删除任何现有的本地 NVMe 存储池,然后再创建新存储池。
使用最喜爱的文本编辑器创建 YAML 清单文件,例如
code acstor-storagepool.yaml
。粘贴以下代码并保存文件。 存储池名称值可以是所需的任何内容。 将副本数设置为 3 或 5。
apiVersion: containerstorage.azure.com/v1 kind: StoragePool metadata: name: ephemeraldisk-nvme namespace: acstor spec: poolType: ephemeralDisk: diskType: nvme replicas: 3
应用 YAML 清单文件以创建存储池。
kubectl apply -f acstor-storagepool.yaml
存储池创建完成后,将会看到如下消息:
storagepool.containerstorage.azure.com/ephemeraldisk-nvme created
还可以运行此命令来检查存储池的状态。 将
<storage-pool-name>
替换为存储池名称值。 在本示例中,该值为 ephemeraldisk-nvme。kubectl describe sp <storage-pool-name> -n acstor
创建存储池后,Azure 容器存储将使用命名约定 acstor-<storage-pool-name>
代表你创建存储类。
3.显示可用的存储类
当存储池可供使用时,必须选择存储类来定义在创建和部署卷时如何动态创建存储。
运行 kubectl get sc
以显示可用的存储类。 应会看到名为 acstor-<storage-pool-name>
的存储类。
$ kubectl get sc | grep "^acstor-"
acstor-azuredisk-internal disk.csi.azure.com Retain WaitForFirstConsumer true 65m
acstor-ephemeraldisk-nvme containerstorage.csi.azure.com Delete WaitForFirstConsumer true 2m27s
重要
请勿使用标记为内部的存储类。 它是 Azure 容器存储正常运行所需的内部存储类。
4.创建永久性卷声明
永久卷声明 (PVC) 用于基于存储类自动预配存储。 按照以下步骤使用新的存储类创建 PVC。
使用最喜爱的文本编辑器创建 YAML 清单文件,例如
code acstor-pvc.yaml
。粘贴以下代码并保存文件。 PVC
name
值可以是所需的任何内容。apiVersion: v1 kind: PersistentVolumeClaim metadata: name: ephemeralpvc annotations: acstor.azure.com/accept-ephemeral-storage: "true" spec: accessModes: - ReadWriteOnce storageClassName: acstor-ephemeraldisk-nvme # replace with the name of your storage class if different resources: requests: storage: 100Gi
更改卷的存储大小时,请确保该大小应小于单个节点临时磁盘的可用容量。 请参阅检查节点临时磁盘容量。
应用 YAML 清单文件以创建 PVC。
kubectl apply -f acstor-pvc.yaml
此时会看到与下面类似的输出:
persistentvolumeclaim/ephemeralpvc created
可以通过运行以下命令来验证 PVC 的状态:
kubectl describe pvc ephemeralpvc
创建 PVC 后,即可供 Pod 使用。
5.部署 Pod 并附加永久性卷
使用 Fio(灵活 I/O 测试器)创建 Pod 以进行基准测试和工作负载模拟,并为永久性卷指定装载路径。 对于 claimName,可使用创建永久性卷声明时使用的名称值。
使用最喜爱的文本编辑器创建 YAML 清单文件,例如
code acstor-pod.yaml
。粘贴以下代码并保存文件。
kind: Pod apiVersion: v1 metadata: name: fiopod spec: nodeSelector: acstor.azure.com/io-engine: acstor volumes: - name: ephemeralpv persistentVolumeClaim: claimName: ephemeralpvc containers: - name: fio image: nixery.dev/shell/fio args: - sleep - "1000000" volumeMounts: - mountPath: "/volume" name: ephemeralpv
应用 YAML 清单文件以部署 Pod。
kubectl apply -f acstor-pod.yaml
应该会看到与下面类似的输出:
pod/fiopod created
检查 Pod 是否正在运行,以及永久性卷声明是否已成功绑定到 Pod:
kubectl describe pod fiopod kubectl describe pvc ephemeralpvc
检查 fio 测试以查看其当前状态:
kubectl exec -it fiopod -- fio --name=benchtest --size=800m --filename=/volume/test --direct=1 --rw=randrw --ioengine=libaio --bs=4k --iodepth=16 --numjobs=8 --time_based --runtime=60
现在,你已部署了一个 Pod,它使用带有卷复制功能的本地 NVMe,并且可以用于 Kubernetes 工作负载。
管理卷和存储池
在本部分中,你将了解如何检查临时磁盘的可用容量、如何分离和重新附加永久性卷、如何扩展或删除存储池,以及如何优化性能。
检查节点临时磁盘容量
在单个节点上分配临时卷。 配置临时卷的大小时,大小应小于单个节点临时磁盘的可用容量。
运行以下命令,检查单个节点临时磁盘的可用容量。
$ kubectl get diskpool -n acstor
NAME CAPACITY AVAILABLE USED RESERVED READY AGE
ephemeraldisk-nvme-diskpool-jaxwb 75660001280 75031990272 628011008 560902144 True 21h
ephemeraldisk-nvme-diskpool-wzixx 75660001280 75031990272 628011008 560902144 True 21h
ephemeraldisk-nvme-diskpool-xbtlj 75660001280 75031990272 628011008 560902144 True 21h
在此示例中,单个节点临时磁盘的可用容量为 75031990272
字节或 69 GiB。
分离并重新附加永久性卷
要分离永久性卷,请删除永久卷附加到的 Pod。
kubectl delete pods <pod-name>
要重新附加永久性卷,只需在 YAML 清单文件中引用永久性卷声明名称,如部署 Pod 并附加永久性卷中所述。
要检查永久性卷声明绑定到哪个永久性卷,请运行:
kubectl get pvc <persistent-volume-claim-name>
展开存储池
你可以扩展由本地 NVMe 支持的存储池,以实现快速纵向扩展且无需停机。 目前不支持收缩存储池。
由于临时磁盘支持的存储池使用 AKS 群集节点上的本地存储资源 (VM),因此展开存储池需要将另一个节点添加到群集。 按照这些说明展开存储池。
运行以下命令,将节点添加到 AKS 群集。 将 、 和 替换为自己的值
<cluster-name>
<nodepool name>
<resource-group-name>
。 若要获取节点池的名称,请运行kubectl get nodes
。az aks nodepool add --cluster-name <cluster name> --name <nodepool name> --resource-group <resource group> --node-vm-size Standard_L8s_v3 --node-count 1 --labels acstor.azure.com/io-engine=acstor
运行
kubectl get nodes
,你将看到节点已添加到群集。运行
kubectl get sp -A
,应看到存储池的容量已增加。
删除存储池
如果要删除存储池,请运行以下命令。 将 <storage-pool-name>
替换为存储池名称。
kubectl delete sp -n acstor <storage-pool-name>
优化使用本地 NVMe 时的性能
根据工作负载的性能要求,可以从三个不同的性能层中进行选择:基本、标准和高级。 这些层提供不同的 IOPS 范围,你的选择将影响 Azure 容器存储组件在安装节点中使用的 vCPU 数量。 如果不更新性能层,则默认配置是“标准”。
单区域复制
层 | vCPU 的数量 | 100% 读取 IOPS | 100% 写入 IOPS |
---|---|---|---|
Basic |
VM 核心总数的 12.5% | 最多 120,000 | 最多 45,000 |
Standard (默认值) |
VM 核心总数的 25% | 最多 220,000 | 最多 90,000 |
Premium |
VM 核心总数的 50% | 最多 550,000 | 最多 180,000 |
多区域复制
层 | vCPU 的数量 | 100% 读取 IOPS | 100% 写入 IOPS |
---|---|---|---|
Basic |
VM 核心总数的 12.5% | 最多 120,000 | 最多 45,000 |
Standard (默认值) |
VM 核心总数的 25% | 最多 220,000 | 最多 90,000 |
Premium |
VM 核心总数的 50% | 最多 550,000 | 最多 180,000 |
注意
RAM 和巨页消耗将在所有层中保持一致:1 GiB 的 RAM 和 2 GiB 的巨页。
确定最符合需求的性能层后,可以运行以下命令来更新 Azure 容器存储安装的性能层。 将 <performance tier>
替换为基本、标准或高级。
az aks update -n <cluster-name> -g <resource-group> --enable-azure-container-storage <storage-pool-type> --ephemeral-disk-nvme-perf-tier <performance-tier>