在 Azure Kubernetes 服务 (AKS) 中动态创建永久性卷并将其用于 Azure 磁盘

永久性卷表示已经过预配可以用于 Kubernetes Pod 的存储块。 永久性卷可供一个或多个 Pod 使用,并可动态或静态预配。 本文介绍如何使用 Azure 磁盘动态创建永久性卷,以供 Azure Kubernetes 服务 (AKS) 群集中的单个 Pod 使用。

注意

Azure 磁盘只能使用“访问模式”类型 ReadWriteOnce 进行装载,这使其只可供 AKS 中的一个节点使用。 如果需要在多个节点之间共享永久性卷,请使用 Azure 文件存储

有关 Kubernetes 卷的详细信息,请参阅 AKS 中应用程序的存储选项

开始之前

本文假设你已有一个版本不低于 1.21 的 AKS 群集。 如果需要 AKS 群集,请参阅使用 Azure CLI 的 AKS 快速入门、使用 Azure PowerShell 的 AKS 快速入门或使用 Azure 门户的 AKS 快速入门。

还需安装并配置 Azure CLI 2.0.59 或更高版本。 运行 az --version 即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

Azure 磁盘 CSI 驱动程序存在每个节点 32 个卷的限制。 卷计数因节点/节点池的大小而异。 运行以下命令以确定可为每个节点分配的卷数:

kubectl get CSINode <nodename> -o yaml

内置存储类

存储类用于定义使用永久性卷动态创建存储单位的方式。 有关 Kubernetes 存储类的详细信息,请参阅 Kubernetes 存储类

每个 AKS 群集包含四个预先创建的存储类,其中两个配置为使用 Azure 磁盘:

  • default 存储类可预配标准 SSD Azure 磁盘。
    • 标准存储由标准 SSD 提供支持,可以在交付可靠性能的同时提供经济高效的存储。
  • managed-csi-premium 存储类可预配高级 Azure 磁盘。
    • 高级磁盘由基于 SSD 的高性能、低延迟磁盘提供支持。 完美适用于运行生产工作负荷的 VM。 如果群集中的 AKS 节点使用高级存储,请选择 managed-premium 类。

如果使用默认存储类之一,则创建存储类后将无法更新卷大小。 若要能够在创建存储类后更新卷大小,请将行 allowVolumeExpansion: true 添加到其中一个默认存储类,或者也可以创建自己的自定义存储类。 不支持减小 PVC 的大小(以防数据丢失)。 可以使用 kubectl edit sc 命令编辑现有存储类。

例如,如果要使用大小为 4 TiB 的磁盘,需要创建一个定义 cachingmode: None 的存储类,因为磁盘缓存不支持 4 TiB 及更大的磁盘

有关存储类和创建自己的存储类的详细信息,请参阅 AKS 中应用程序的存储选项

使用 kubectl get sc 命令查看预先创建的存储类。 以下示例显示了 AKS 群集中可用的预先创建存储类:

kubectl get sc

该命令的输出类似于以下示例:

NAME                PROVISIONER                AGE
default (default)   disk.csi.azure.com         1h
managed-csi         disk.csi.azure.com         1h

注意

永久卷声明在 GiB 中指定,但 Azure 托管磁盘由 SKU 针对特定大小计费。 这些 SKU 的范围从用于 S4 或 P4 磁盘的 32 GiB 到用于 S80 或 P80 磁盘的 32 TiB(预览版)。 高级托管磁盘的吞吐量和 IOPS 性能取决于 SKU 和 AKS 群集中节点的实例大小。 有关详细信息,请参阅托管磁盘的定价和性能

创建永久性卷声明

永久卷声明 (PVC) 用于基于存储类自动预配存储。 在这种情况下,PVC 可以使用预先创建的存储类之一创建标准或高级 Azure 托管磁盘。

创建名为 azure-pvc.yaml 的文件,并将其复制到以下清单中。 该声明请求名为 azure-managed-disk、大小为 5 GB、具有 ReadWriteOnce 访问权限的磁盘。 managed-csi 存储类指定为存储类。

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

提示

若要创建使用高级存储的磁盘,请使用 storageClassName: managed-csi-premium 而不是 managed-csi。

使用 kubectl apply 命令创建永久性卷声明,并指定 azure-pvc.yaml 文件:

kubectl apply -f azure-pvc.yaml

该命令的输出类似于以下示例:

persistentvolumeclaim/azure-managed-disk created

使用永久性卷

创建永久性卷声明并成功预配磁盘以后,即可创建可以访问磁盘的 Pod。 以下清单创建的基本 NGINX Pod 使用名为 azure-managed-disk 的永久性卷声明将 Azure 磁盘装载到 /mnt/azure 路径。 对于 Windows Server 容器,请使用 Windows 路径约定指定 mountPath,例如“D:”。

创建名为 azure-pvc-disk.yaml 的文件,并将其复制到以下清单中。

kind: Pod
apiVersion: v1
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 250m
        memory: 256Mi
    volumeMounts:
    - mountPath: "/mnt/azure"
      name: volume
  volumes:
    - name: volume
      persistentVolumeClaim:
        claimName: azure-managed-disk

使用 kubectl apply 命令创建 Pod,如以下示例所示:

kubectl apply -f azure-pvc-disk.yaml

pod/mypod created

现在你有一个正在运行的 Pod,其中 Azure 磁盘被装载到 /mnt/azure 目录中。 通过 kubectl describe pod mypod 检查 Pod 时可以看到此配置,如以下精简示例所示:

kubectl describe pod mypod

该命令的输出类似于以下示例:

[...]
Volumes:
  volume:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  azure-managed-disk
    ReadOnly:   false
  default-token-smm2n:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-smm2n
    Optional:    false
[...]
Events:
  Type    Reason                 Age   From                               Message
  ----    ------                 ----  ----                               -------
  Normal  Scheduled              2m    default-scheduler                  Successfully assigned mypod to aks-nodepool1-79590246-0
  Normal  SuccessfulMountVolume  2m    kubelet, aks-nodepool1-79590246-0  MountVolume.SetUp succeeded for volume "default-token-smm2n"
  Normal  SuccessfulMountVolume  1m    kubelet, aks-nodepool1-79590246-0  MountVolume.SetUp succeeded for volume "pvc-faf0f176-8b8d-11e8-923b-deb28c58d242"
[...]

备份永久性卷

若要备份持久卷中的数据,请为该卷的托管磁盘创建快照。 然后,可以使用此快照创建还原的磁盘,并通过还原数据的方式附加到 Pod。

首先,使用 kubectl get pvc 命令获取卷名称,例如,获取 PVC 名称 azure-managed-disk

$ kubectl get pvc azure-managed-disk

NAME                 STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
azure-managed-disk   Bound     pvc-faf0f176-8b8d-11e8-923b-deb28c58d242   5Gi        RWO            managed-premium   3m

此卷名称构成了基础 Azure 磁盘名称。 使用 az disk list 查询磁盘 ID 并提供 PVC 卷名称,如以下示例所示:

az disk list --query '[].id | [?contains(@,`pvc-faf0f176-8b8d-11e8-923b-deb28c58d242`)]' -o tsv

/subscriptions/<guid>/resourceGroups/MC_MYRESOURCEGROUP_MYAKSCLUSTER_chinaeast2/providers/MicrosoftCompute/disks/kubernetes-dynamic-pvc-faf0f176-8b8d-11e8-923b-deb28c58d242

运行 az snapshot create,使用磁盘 ID 创建快照磁盘。 以下示例在 AKS 群集所在的同一资源组 (MC_myResourceGroup_myAKSCluster_chinaeast2) 中创建名为 pvcSnapshot 的快照。 如果在 AKS 群集无权访问的资源组中创建快照和还原磁盘,可能会遇到权限问题。

az snapshot create \
    --resource-group MC_myResourceGroup_myAKSCluster_chinaeast2 \
    --name pvcSnapshot \
    --source /subscriptions/<guid>/resourceGroups/MC_myResourceGroup_myAKSCluster_chinaeast2/providers/MicrosoftCompute/disks/kubernetes-dynamic-pvc-faf0f176-8b8d-11e8-923b-deb28c58d242

根据磁盘上的数据量,可能需要花费几分钟时间来创建快照。

还原并使用快照

若要还原磁盘并将其用于 Kubernetes Pod,请在使用 az disk create 创建磁盘时,将快照用作源。 如果以后需要访问原始数据快照,此操作可保留原始资源。 以下示例基于名为 pvcSnapshot 的快照创建名为 pvcRestored 的磁盘:

az disk create --resource-group MC_myResourceGroup_myAKSCluster_chinaeast2 --name pvcRestored --source pvcSnapshot

若要使用包含 Pod 的已还原磁盘,请指定清单中磁盘的 ID。 使用 az disk show 命令获取磁盘 ID。 以下示例获取上一步骤中创建的 pvcRestored 的磁盘 ID:

az disk show --resource-group MC_myResourceGroup_myAKSCluster_chinaeast2 --name pvcRestored --query id -o tsv

创建名为 azure-restored.yaml 的 Pod 清单,并指定上一步骤中获取的磁盘 URI。 以下示例创建一个基本的 NGINX Web 服务器,其中的 mnt/azure 处已将还原的磁盘装载为卷:

kind: Pod
apiVersion: v1
metadata:
  name: mypodrestored
spec:
  containers:
  - name: mypodrestored
    image: mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 250m
        memory: 256Mi
    volumeMounts:
    - mountPath: "/mnt/azure"
      name: volume
  volumes:
    - name: volume
      azureDisk:
        kind: Managed
        diskName: pvcRestored
        diskURI: /subscriptions/<guid>/resourceGroups/MC_myResourceGroupAKS_myAKSCluster_chinaeast2/providers/Microsoft.Compute/disks/pvcRestored

使用 kubectl apply 命令创建 Pod,如以下示例所示:

$ kubectl apply -f azure-restored.yaml

该命令的输出类似于以下示例:

pod/mypodrestored created

可以使用 kubectl describe pod mypodrestored 查看 Pod 详细信息,例如,以下精简示例显示了卷信息:

kubectl describe pod mypodrestored

该命令的输出类似于以下示例:

[...]
Volumes:
  volume:
    Type:         AzureDisk (an Azure Data Disk mount on the host and bind mount to the pod)
    DiskName:     pvcRestored
    DiskURI:      /subscriptions/19da35d3-9a1a-4f3b-9b9c-3c56ef409565/resourceGroups/MC_myResourceGroupAKS_myAKSCluster_chinaeast2/providers/Microsoft.Compute/disks/pvcRestored
    Kind:         Managed
    FSType:       ext4
    CachingMode:  ReadWrite
    ReadOnly:     false
[...]

使用 Azure 标记

有关使用 Azure 标记的详细信息,请参阅在 Azure Kubernetes 服务 (AKS) 中使用 Azure 标记

后续步骤

如需相关的最佳做法,请参阅在 AKS 中存储和备份的最佳做法

详细了解使用 Azure 磁盘的 Kubernetes 永久性卷。