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

将 Azure 容器存储与本地 NVMe 配合使用

Azure 容器存储是基于云的卷管理、部署和业务流程服务,专为容器原生构建。 本文介绍如何将 Azure 容器存储配置为将本地 NVMe 磁盘用作 Kubernetes 工作负荷的后端存储。 NVMe 专为存储和 CPU 之间的高速数据传输而设计,提供非常高的 IOPS 和吞吐量。

重要说明

本文适用于 Azure 容器存储(版本 2.x.x),目前仅支持本地 NVMe 磁盘来备份存储。 有关早期版本的详细信息,请参阅 Azure 容器存储(版本 1.x.x)文档

什么是本地 NVMe?

当应用程序需要亚毫秒存储延迟和非常高的吞吐量时,可以将本地 NVMe 与 Azure 容器存储配合使用以满足性能要求。 临时意味着磁盘部署在托管 AKS 群集的本地虚拟机 (VM) 上,而不是保存到 Azure 存储服务。 如果停止/解除分配 VM,这些磁盘上的数据将会丢失。 选择的 Azure VM 系列(例如 存储优化 VM)上提供了本地 NVMe 磁盘。

为了最大程度地提高性能,Azure 容器存储会根据每个 VM 自动对所有可用的本地 NVMe 磁盘中的数据进行条带化。 条带化是一种将数据分成小块并同时在多个磁盘之间均匀写入的技术,这会增加吞吐量并提高整体 I/O 性能。 此行为默认处于启用状态,不能禁用。

默认情况下,使用本地 NVMe 磁盘时,Azure 容器存储会创建 通用临时卷 。 对于需要 永久性卷声明的用例,可以在永久性卷声明模板中添加批注 localdisk.csi.acstor.io/accept-ephemeral-storage: "true"

Prerequisites

  • 如果没有 Azure 订阅,请在开始之前创建一个免费帐户

  • 本文需要 Azure CLI 的最新版本(2.77.0 或更高版本)。 请参阅如何安装 Azure CLI。 请勿使用 Azure Cloud Shell,因为 az upgrade Cloud Shell 中不可用。 请务必使用管理权限运行本文中的命令。

  • 你将需要 Kubernetes 命令行客户端 kubectl。 可以通过运行 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

注意

在 Azure 容器存储(版本 2.x.x)中,现在可以使用少于三个节点的群集。

创建和附加通用临时卷

按照以下步骤使用 Azure 容器存储创建和附加通用临时卷。

1.创建存储类

与需要创建自定义存储池资源的以前版本不同,Azure 容器存储(版本 2.x.x)使用标准 Kubernetes 存储类。 这是一项重大更改,可简化存储配置过程。

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

  1. 使用最喜爱的文本编辑器创建 YAML 清单文件,例如 code storageclass.yaml

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

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: local
    provisioner: localdisk.csi.acstor.io
    reclaimPolicy: Delete
    volumeBindingMode: WaitForFirstConsumer
    allowVolumeExpansion: true
    
  3. 应用 YAML 清单文件以创建存储池。

    kubectl apply -f storageclass.yaml
    

2.验证存储类

运行以下命令以验证是否已创建存储类:

kubectl get storageclass local

应看到如下输出:

NAME    PROVISIONER                RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
local   localdisk.csi.acstor.io    Delete          WaitForFirstConsumer   true                   10s

3. 部署具有通用临时卷的 Pod

创建使用 Fio(灵活 I/O 测试器)进行基准测试和工作负载的 pod,该 pod 使用通用临时卷。

  1. 使用最喜爱的文本编辑器创建 YAML 清单文件,例如 code fiopod.yaml

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

    kind: Pod
    apiVersion: v1
    metadata:
      name: fiopod
    spec:
      nodeSelector:
        "kubernetes.io/os": linux
      containers:
        - name: fio
          image: mayadata/fio
          args: ["sleep", "1000000"]
          volumeMounts:
            - mountPath: "/volume"
              name: ephemeralvolume
      volumes:
        - name: ephemeralvolume
          ephemeral:
            volumeClaimTemplate:
              spec:
                volumeMode: Filesystem
                accessModes: ["ReadWriteOnce"]
                storageClassName: local
                resources:
                  requests:
                    storage: 10Gi
    
  3. 应用 YAML 清单文件以部署 Pod。

    kubectl apply -f fiopod.yaml
    

4.验证部署并运行基准

检查 Pod 是否正在运行:

kubectl get pod fiopod

你应会看到 Pod 处于“正在运行”状态。 运行后,可以执行 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

使用临时存储注释创建和附加永久性卷

虽然建议将常规临时卷用于临时存储,但如果需要,Azure 容器存储还支持具有临时存储的永久性卷,以便与现有工作负荷兼容。

注意

在 Azure 容器存储(版本 2.x.x)中,批注已从acstor.azure.com/accept-ephemeral-storage: "true"localdisk.csi.acstor.io/accept-ephemeral-storage: "true"更改为 。 这反映了新的 CSI 驱动程序命名约定。

1.创建存储类(如果尚未创建)

如果尚未在上一部分创建使用本地 NVMe 的存储类,请立即创建一个:

  1. 使用最喜爱的文本编辑器创建 YAML 清单文件,例如 code storageclass.yaml

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

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: local
    provisioner: localdisk.csi.acstor.io
    reclaimPolicy: Delete
    volumeBindingMode: WaitForFirstConsumer
    allowVolumeExpansion: true
    
  3. 应用 YAML 清单文件以创建存储池。

    kubectl apply -f storageclass.yaml
    

2. 部署具有永久性卷的有状态集

如果需要使用与 Pod 生命周期无关的永久性卷声明,则必须添加 localdisk.csi.acstor.io/accept-ephemeral-storage: "true" 注释。 请注意,卷上的数据是节点的本地数据,如果删除该节点或 Pod 移动到另一个节点,则会丢失。

下面是使用永久性卷和临时存储注释的示例 StatefulSet:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: statefulset-lcd-lvm-annotation
  labels:
    app: busybox
spec:
  podManagementPolicy: Parallel
  serviceName: statefulset-lcd
  replicas: 10
  template:
    metadata:
      labels:
        app: busybox
    spec:
      nodeSelector:
        "kubernetes.io/os": linux
      containers:
        - name: statefulset-lcd
          image: mcr.microsoft.com/azurelinux/busybox:1.36
          command:
            - "/bin/sh"
            - "-c"
            - set -euo pipefail; trap exit TERM; while true; do date -u +"%Y-%m-%dT%H:%M:%SZ" >> /mnt/lcd/outfile; sleep 1; done
          volumeMounts:
            - name: persistent-storage
              mountPath: /mnt/lcd
  updateStrategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app: busybox
  volumeClaimTemplates:
    - metadata:
        name: persistent-storage
        annotations:
          localdisk.csi.acstor.io/accept-ephemeral-storage: "true"
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: local
        resources:
          requests:
            storage: 10Gi

保存并应用此 YAML 来创建具有永久性卷的 StatefulSet:

kubectl apply -f statefulset-pvc.yaml

管理存储

本部分介绍如何检查节点临时磁盘容量、扩展存储容量和删除存储资源。

检查节点临时磁盘容量

在单个节点上分配临时卷。 配置临时卷的大小时,大小应小于单个节点临时磁盘的可用容量。

确保已为 localdisk.csi.acstor.io 创建 StorageClass。 运行以下命令,检查每个节点的临时磁盘的可用容量。

kubectl get csistoragecapacities.storage.k8s.io -n kube-system -o custom-columns=NAME:.metadata.name,STORAGE_CLASS:.storageClassName,CAPACITY:.capacity,NODE:.nodeTopology.matchLabels."topology\.localdisk\.csi\.acstor\.io/node"

此时会看到与下面类似的输出:

NAME          STORAGE_CLASS   CAPACITY    NODE
csisc-2pkx4   local           1373172Mi   aks-storagepool-31410930-vmss000001
csisc-gnmm9   local           1373172Mi   aks-storagepool-31410930-vmss000000

如果遇到空容量输出,请确保已为 localdisk.csi.acstor.io 创建了 StorageClass。 csistoragecapacities.storage.k8s.io 资源仅在 localdisk.csi.acstor.io 的 StorageClass 存在后生成。

扩展存储容量

由于临时磁盘存储使用 AKS 群集节点上的本地资源,因此扩展存储容量需要将节点添加到群集。

若要将节点添加到群集,请运行以下命令。 将 <cluster-name><nodepool-name><resource-group><new-count> 替换为自定义值。

az aks nodepool scale --cluster-name <cluster-name> --name <nodepool-name> --resource-group <resource-group> --node-count <new-count>

删除存储资源

若要清理存储资源,必须先删除所有 PersistentVolumeClaims 和/或 PersistentVolumes。 删除 Azure 容器存储 StorageClass 不会自动移除现有的 PersistentVolumes/PersistentVolumeClaims。

若要删除名为 本地的存储类,请运行以下命令:

kubectl delete storageclass local

另请参阅