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

将 Azure 容器存储(版本 1.x.x)与本地 NVMe 配合使用

Azure 容器存储是一种基于云的卷管理、部署和编排服务,专为容器原生构建。 本文介绍如何配置 Azure 容器存储(版本 1.x.x),以使用本地 NVMe 作为瞬态磁盘,为 Kubernetes 工作负载提供后端存储。 最后,你将有一个 Pod,该 Pod 使用本地 NVMe 作为存储。

重要

本文介绍 Azure 容器存储(版本 1.x.x)中提供的特性和功能。 Azure 容器存储(版本 2.x.x) 现已推出。 如果已在使用 Azure 容器存储(版本 2.x.x),请参阅 本文 来配置本地 NVMe。

什么是临时磁盘?

当应用程序需要亚毫秒存储延迟且不需要数据持续性时,可以将临时磁盘与 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。 请参阅 如何安装 Azure CLI。 如果在 Azure Cloud Shell 中使用 Bash 环境,则可能已安装最新版本。 如果计划在本地而不是 Azure Cloud Shell 中运行命令,请确保使用管理权限运行这些命令。 有关详细信息,请参阅 Azure Cloud Shell 入门

  • 需要 Kubernetes 命令行客户端。 kubectl 如果使用的是 Azure Cloud Shell,则已安装它,或者可以通过运行 az aks install-cli 命令在本地安装它。

  • 检查 Azure 容器存储区域中是否支持目标区域。

选择支持本地 NVMe 的 VM 类型

本地 NVMe 磁盘仅适用于某些类型的 VM,例如 存储优化的 VM SKUGPU 加速 VM SKU。 如果计划使用本地 NVMe 容量,请选择其中一个 VM SKU。

运行以下命令以获取与节点池一起使用的 VM 类型。 将 <resource group><cluster name> 替换为自己的值。 无需为PoolNameVmSize提供值,因此请保持查询如下所示。

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 createaz aks update命令启用了 Azure 容器存储,则可能已有存储池。 使用 kubectl get sp -n acstor 获取存储池的列表。 如果已有要使用的存储池,则可以跳过本部分,并继续 显示可用的存储类

按照以下步骤使用本地 NVMe 创建存储池。

  1. 使用你喜欢的文本编辑器创建 YAML 清单文件,例如 code acstor-storagepool.yaml

  2. 粘贴以下代码并保存文件。 存储池 名称 值可以是所需的任何值。

    apiVersion: containerstorage.azure.com/v1
    kind: StoragePool
    metadata:
      name: ephemeraldisk-nvme
      namespace: acstor
    spec:
      poolType:
        ephemeralDisk:
          diskType: nvme
    
  3. 应用 YAML 清单文件来创建存储池。

    kubectl apply -f acstor-storagepool.yaml 
    

    存储池创建完成后,会看到如下所示的消息:

    storagepool.containerstorage.azure.com/ephemeraldisk-nvme created
    

    还可以运行此命令来检查存储池的状态。 将<storage-pool-name>替换为您的存储池名称值。 对于此示例,该值将为 临时disk-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 使用通用临时卷。

  1. 使用你喜欢的文本编辑器创建 YAML 清单文件,例如 code acstor-pod.yaml

  2. 粘贴以下代码并保存文件。

    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
    

    更改卷的存储大小时,请确保该大小应小于单个节点临时磁盘的可用容量。 请参阅 检查节点临时磁盘容量

  3. 应用 YAML 清单文件来部署 Pod。

    kubectl apply -f acstor-pod.yaml
    

    应该会看到与下面类似的输出:

    pod/fiopod created
    
  4. 检查 Pod 是否正在运行,以及临时卷声明是否已成功绑定到 Pod:

    kubectl describe pod fiopod
    kubectl describe pvc fiopod-ephemeralvolume
    
  5. 检查 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
    

现在,你已部署了一个使用本地 NVMe 作为其存储的 Pod,并可用于 Kubernetes 工作负载。

创建和附加持久性存储卷

若要从临时磁盘存储池中创建持久卷,必须在持久卷声明(PVCs)中包含注释,以此作为保障措施,以确保即使数据是临时的,您仍然打算使用持久卷。 此外,在创建持久卷声明之前,需要在群集上启用 --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.创建存储池

通过在 YAML 清单文件中定义存储池,为 Kubernetes 集群创建一个逻辑存储分组。

如果使用az aks createaz aks update命令启用了 Azure 容器存储,则可能已有存储池。 使用 kubectl get sp -n acstor 获取存储池的列表。 如果已有要使用的存储池,则可以跳过本部分,并继续 显示可用的存储类

按照以下步骤使用本地 NVMe 创建存储池。

  1. 使用你喜欢的文本编辑器创建 YAML 清单文件,例如 code acstor-storagepool.yaml

  2. 粘贴以下代码并保存文件。 存储池 名称 值可以是所需的任何值。

    apiVersion: containerstorage.azure.com/v1
    kind: StoragePool
    metadata:
      name: ephemeraldisk-nvme
      namespace: acstor
    spec:
      poolType:
        ephemeralDisk:
          diskType: nvme
    
  3. 应用 YAML 清单文件来创建存储池。

    kubectl apply -f acstor-storagepool.yaml 
    

    存储池创建完成后,会看到如下所示的消息:

    storagepool.containerstorage.azure.com/ephemeraldisk-nvme created
    

    还可以运行此命令来检查存储池的状态。 将<storage-pool-name>替换为您的存储池名称值。 对于此示例,该值将为 临时disk-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。

  1. 使用你喜欢的文本编辑器创建 YAML 清单文件,例如 code acstor-pvc.yaml

  2. 粘贴以下代码并保存文件。 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
    

    更改卷的存储大小时,请确保该大小应小于单个节点临时磁盘的可用容量。 请参阅 检查节点临时磁盘容量

  3. 应用 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,请使用创建持久存储卷声明时使用的 名称 值。

  1. 使用你喜欢的文本编辑器创建 YAML 清单文件,例如 code acstor-pod.yaml

  2. 粘贴以下代码并保存文件。

    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
    
  3. 应用 YAML 清单文件来部署 Pod。

    kubectl apply -f acstor-pod.yaml
    

    应该会看到与下面类似的输出:

    pod/fiopod created
    
  4. 检查 Pod 是否正在运行,以及永久性卷声明是否已成功绑定到 Pod:

    kubectl describe pod fiopod
    kubectl describe pvc ephemeralpvc
    
  5. 检查 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
    

现在,你已部署了使用本地 NVMe 的 Pod,并且可以将其用于 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。

扩展存储池

可以扩展本地 NVMe 支持的存储池,以便快速、无需停机即可纵向扩展。 目前不支持收缩存储池。

由于临时磁盘支持的存储池使用 AKS 群集节点上的本地存储资源(VM),因此扩展存储池需要将另一个节点添加到群集。 请遵循以下说明扩展存储池。

  1. 运行以下命令,将节点添加到 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
    
  2. 运行 kubectl get nodes ,你将看到节点已添加到群集。

  3. 运行 kubectl get sp -A ,应会看到存储池的容量已增加。

删除存储池

如果要删除存储池,请运行以下命令。 将 <storage-pool-name> 替换为存储池名称。

kubectl delete sp -n acstor <storage-pool-name>

使用本地 NVMe 时优化性能

根据工作负荷的性能要求,可以从三个不同的性能层中进行选择: 基本层、 标准层和 高级层。 你的选择将影响 Azure 容器存储组件在安装它的节点中消耗的 vCPU 数。 如果未更新性能层,则标准是默认配置。

这三个层提供不同的 IOPS 范围。 下表内容提供了关于这些级别的预期指导。 我们使用常用的基准测试工具 FIO 通过以下配置实现这些数字:

  • AKS:节点 SKU - Standard_L16s_v3
  • FIO:块大小 - 4 KiB; 队列深度 - 32; Numjobs - 分配给容器存储组件的核心数; 访问模式 - 随机; 工作集大小 - 32 GiB
vCPU 数 100% 读取 IOPS 100% 写入 IOPS
Basic VM 核心总数的 12.5% 最多12万 最多 90,000
Standard(默认值) 总 VM 核心的 25% 最多 220,000 最多 180,000
Premium VM 核心总数的 50% 最多 550,000 最多可达36万

注释

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>

另请参阅