你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
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 磁盘。
默认情况下,使用本地 NVMe 磁盘时,Azure 容器存储会创建 通用临时卷 。 对于需要 永久性卷声明的用例,可以在永久性卷声明模板中添加批注 localdisk.csi.acstor.io/accept-ephemeral-storage: "true" 。
数据条带化
为了最大程度地提高性能,Azure 容器存储会根据每个 VM 自动对所有可用的本地 NVMe 磁盘中的数据进行条带化。 条带化是一种将数据分成小块并同时在多个磁盘之间均匀写入的技术,这会增加吞吐量并提高整体 I/O 性能。 此行为默认处于启用状态,不能禁用。
由于性能会在这些条带化设备间聚合,因此暴露更多 NVMe 驱动器的更大规格虚拟机,能显著释放更高的 IOPS(每秒输入/输出操作数)和带宽。 选择更大的 VM 系列可使工作负荷受益于额外的聚合吞吐量,而无需进行额外的配置。
例如, Lsv3 系列 从Standard_L8s_v3(约 40 万 IOPS 和 2,000 MB/秒)上的单个 1.92 TB NVMe 驱动器(约 380 万 IOPS 和 20,000 MB/秒)扩展到 Standard_L80s_v3 10 个 NVMe 驱动器(约 380 万 IOPS 和 20,000 MB/秒)。
Prerequisites
如果没有 Azure 订阅,请在开始之前创建一个免费帐户。
本文需要 Azure CLI 的最新版本(2.77.0 或更高版本)。 请参阅如何安装 Azure CLI。 避免使用 Azure Cloud Shell,因为
az upgradeCloud Shell 中不可用。 请务必使用管理权限运行本文中的命令。查看安装说明 并确保正确安装 Azure 容器存储。
需要 Kubernetes 命令行客户端。
kubectl可以通过运行az aks install-cli命令在本地安装它。检查 Azure 容器存储区域是否支持你的目标区域。
选择一个支持本地 NVMe 的 VM 类型
本地 NVMe 磁盘仅适用于某些类型的 VM,例如 存储优化 VM 或 GPU 加速 VM。 如果计划使用本地 NVMe 容量,请选择以下 VM 大小之一。
运行以下命令来获取与节点池一起使用的 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
注意
在 Azure 容器存储(版本 2.x.x)中,现在可以使用少于三个节点的群集。
创建和附加通用临时卷
如果尚未这样做, 请安装 Azure 容器存储。
按照以下步骤使用 Azure 容器存储创建和附加通用临时卷。
1.创建存储类
与需要创建自定义存储池资源的以前版本不同,Azure 容器存储(版本 2.x.x)使用标准 Kubernetes 存储类。
按照以下步骤使用本地 NVMe 创建存储类。
使用最喜爱的文本编辑器创建 YAML 清单文件,例如
code storageclass.yaml。粘贴以下代码并保存文件。
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: local provisioner: localdisk.csi.acstor.io reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer allowVolumeExpansion: true应用 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 使用通用临时卷。
使用最喜爱的文本编辑器创建 YAML 清单文件,例如
code fiopod.yaml。粘贴以下代码并保存文件。
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应用 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)使用新的批注 localdisk.csi.acstor.io/accept-ephemeral-storage: "true",而不是以前的 acstor.azure.com/accept-ephemeral-storage: "true"。
1.创建存储类(如果尚未创建)
如果尚未这样做, 请安装 Azure 容器存储。
如果未在上一部分中创建使用本地 NVMe 的存储类,请立即创建一个:
使用最喜爱的文本编辑器创建 YAML 清单文件,例如
code storageclass.yaml。粘贴以下代码并保存文件。
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: local provisioner: localdisk.csi.acstor.io reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer allowVolumeExpansion: true应用 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