在 Azure Kubernetes 服务 (AKS) 中通过 Azure 磁盘创建并使用卷

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

注意

Azure 磁盘只能使用“访问模式”类型 ReadWriteOnce 进行装载,这使其只可供 AKS 中的一个节点使用。 当多个 Pod 在同一节点上运行时,此访问模式仍允许多个 Pod 访问卷。 有关详细信息,请参阅 Kubernetes PersistentVolume 访问模式

本文介绍如何:

  • 通过安装容器存储接口 (CSI) 驱动程序并动态创建一个或多个要附加到 Pod 的 Azure 托管磁盘来使用动态永久性卷 (PV)。
  • 通过创建一个或多个 Azure 托管磁盘来使用静态 PV,或者使用现有 Azure 托管磁盘并将其附加到 Pod。

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

准备阶段

  • 需要一个 Azure 存储帐户

  • 确保已安装且已配置 Azure CLI 版本 2.0.59。 运行 az --version 即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

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

    kubectl get CSINode <nodename> -o yaml
    

动态预配卷

本部分为想要预配一个或多个永久性卷的群集管理员提供指导,这些卷中包含供工作负荷使用的 Azure 磁盘存储的详细信息。 永久性卷声明 (PVC) 使用存储类对象来动态预配 Azure 磁盘存储容器。

动态 PersistentVolume 的存储类参数

下表包含可用于为 PersistentVolumeClaim 定义自定义存储类的参数。

名称 含义 可用值 必需 默认值
skuName Azure 磁盘存储帐户类型(别名:storageAccountType Standard_LRSPremium_LRSStandardSSD_LRSPremiumV2_LRSUltraSSD_LRSPremium_ZRSStandardSSD_ZRS StandardSSD_LRS
fsType 文件系统类型 ext4ext3ext2xfsbtrfs(适用于 Linux)、ntfs(适用于 Windows) ext4(适用于 Linux),ntfs(适用于 Windows)
cachingMode Azure 数据磁盘主机缓存设置 NoneReadOnlyReadWrite ReadOnly
resourceGroup 指定 Azure 磁盘的资源组 现有资源组名称 如果为空,驱动程序将使用与当前 AKS 群集相同的资源组名称
DiskIOPSReadWrite UltraSSD 磁盘 IOPS 能力 (最低:2 IOPS/GiB) 100~160000 500
DiskMBpsReadWrite UltraSSD 磁盘吞吐量能力(最低:0.032/GiB) 1~2000 100
LogicalSectorSize 超级磁盘的逻辑扇区大小(以字节为单位)。 支持的值为 512 和 4096。 4096 是默认值。 5124096 4096
标记 Azure 磁盘标记 标记格式:key1=val1,key2=val2 ""
diskEncryptionSetID 用于启用静态加密的磁盘加密集的 ResourceId 格式:/subscriptions/{subs-id}/resourceGroups/{rg-name}/providers/Microsoft.Compute/diskEncryptionSets/{diskEncryptionSet-name} ""
diskEncryptionType 磁盘加密集的加密类型。 EncryptionAtRestWithCustomerKey(默认),EncryptionAtRestWithPlatformAndCustomerKeys ""
writeAcceleratorEnabled Azure 磁盘上的写入加速器 truefalse ""
networkAccessPolicy NetworkAccessPolicy 属性,用于防止生成磁盘或快照的 SAS URI AllowAllDenyAllAllowPrivate AllowAll
diskAccessID 用于在磁盘上使用专用终结点的 DiskAccess 资源的 Azure 资源 ID ``
enableBursting 启用按需突发超出磁盘的预配性能目标。 按需突发应仅应用于高级版磁盘,同时磁盘大小 > 512 GB。 不支持超级磁盘和共享磁盘。 默认情况下,突发处于禁用状态。 truefalse false
useragent 用于客户使用情况归因的用户代理 生成的用户代理格式为 driverName/driverVersion compiler/version (OS-ARCH)
subscriptionID 指定在其中创建 Azure 磁盘的 Azure 订阅 ID。 Azure 订阅 ID 如果不为空,则必须提供 resourceGroup
--- 以下参数仅适用于 v2 --- --- ---
maxShares 磁盘允许的共享磁盘装载总数。 将该值设置为 2 或 2 以上可启用附件副本。 支持的值取决于磁盘大小。 有关支持的值,请参阅共享 Azure 托管磁盘 1
maxMountReplicaCount 要维护的副本附件数。 该值必须在 [0..(maxShares - 1)] 范围内 如果 accessModeReadWriteMany,则默认值为 0。 否则默认值为 maxShares - 1

内置存储类

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

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

  1. default 存储类可预配标准 SSD Azure 磁盘。
    • 标准 SSD 支持标准存储,并可以在交付可靠性能的同时提供经济高效的存储。
  2. managed-csi-premium 存储类可预配高级 Azure 磁盘。
    • 基于 SSD 的高性能、低延迟磁盘支持高级磁盘。 它们非常适合运行生产工作负载的 VM。 在 AKS 上使用 Azure 磁盘 CSI 驱动程序时,还可以使用 managed-csi 存储类,该类由标准 SSD 本地冗余存储 (LRS) 提供支持。

不支持减小 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 托管磁盘。

  1. 创建名为 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。

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

    kubectl apply -f azure-pvc.yaml
    

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

    persistentvolumeclaim/azure-managed-disk created
    

使用永久性卷

创建永久性卷声明后,必须验证其状态为“Pending”。 状态“Pending”指示它已准备好供 Pod 使用。

  1. 使用 kubectl describe pvc 命令检查 PVC 的状态。

    kubectl describe pvc azure-managed-disk
    

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

    Name:            azure-managed-disk
    Namespace:       default
    StorageClass:    managed-csi
    Status:          Pending
    [...]
    
  2. 创建名为 azure-pvc-disk.yaml 的文件,并将其复制到以下清单中。 以下清单创建的基本 NGINX Pod 使用名为 azure-managed-disk 的永久性卷声明将 Azure 磁盘装载到路径 /mnt/azure。 对于 Windows Server 容器,请使用 Windows 路径约定指定 mountPath,例如“D:”。

    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
              readOnly: false
      volumes:
        - name: volume
          persistentVolumeClaim:
            claimName: azure-managed-disk
    
  3. 使用 kubectl apply 命令创建 Pod。

     kubectl apply -f azure-pvc-disk.yaml
    

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

    pod/mypod created
    
  4. 现在你有一个正在运行的 Pod,其中 Azure 磁盘被装载到 /mnt/azure 目录中。 使用 kubectl describe 命令检查 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。

  1. 使用 kubectl get 命令为特定项(例如名为 azure-managed-disk 的 PVC)获取卷名:

    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
    
  2. 此卷名称构成了基础 Azure 磁盘名称。 使用 [az disk list][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_China East 2/providers/MicrosoftCompute/disks/kubernetes-dynamic-pvc-faf0f176-8b8d-11e8-923b-deb28c58d242
    
  3. 运行 [az snapshot create][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
    

还原并使用快照

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

    az disk create --resource-group MC_myResourceGroup_myAKSCluster_chinaeast2 --name pvcRestored --source pvcSnapshot
    
  2. 若要使用包含 Pod 的已还原磁盘,请指定清单中磁盘的 ID。 使用 [az disk show][az-disk-show] 命令获取磁盘 ID。 以下示例获取上一步骤中创建的 pvcRestored 的磁盘 ID:

    az disk show --resource-group MC_myResourceGroup_myAKSCluster_chinaeast2 --name pvcRestored --query id -o tsv
    
  3. 创建名为 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
    
  4. 使用 kubectl apply 命令创建 Pod,如以下示例所示:

     kubectl apply -f azure-restored.yaml
    

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

    pod/mypodrestored created
    
  5. 可以使用 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 标记

静态预配卷

本部分为想要创建一个或多个永久性卷的群集管理员提供指导,这些卷中包含供工作负荷使用的 Azure 磁盘存储的详细信息。

PersistentVolume 的静态预配参数

下表包含可用于定义 PersistentVolume 的参数。

名称 含义 可用值 必需 默认值
volumeHandle Azure 磁盘 URI /subscriptions/{sub-id}/resourcegroups/{group-name}/providers/microsoft.compute/disks/{disk-id} 空值
volumeAttributes.fsType 文件系统类型 ext4ext3ext2xfsbtrfs(适用于 Linux)、ntfs(适用于 Windows) ext4(适用于 Linux)、ntfs(适用于 Windows)
volumeAttributes.partition 现有磁盘的分区号(仅在 Linux 上受支持) 123 空(无分区)
- 确保分区格式类似于 -part1
volumeAttributes.cachingMode 磁盘主机缓存设置 NoneReadOnlyReadWrite ReadOnly

创建 Azure 磁盘

创建用于 AKS 的 Azure 磁盘时,可以在节点资源组中创建磁盘资源。 此方法允许 AKS 群集访问和管理磁盘资源。 如果想要在单独的资源组中创建磁盘,则必须向群集的 Azure Kubernetes 服务 (AKS) 托管标识授予磁盘资源组的 Contributor 角色。

  1. 使用 az aks show 命令标识资源组名称并添加 --query nodeResourceGroup 参数。

    az aks show --resource-group myResourceGroup --name myAKSCluster --query nodeResourceGroup -o tsv
    
    # Output
    MC_myResourceGroup_myAKSCluster_eastus
    
  2. 使用 az disk create 命令创建磁盘。 指定节点资源组名称和磁盘资源名称,例如 myAKSDisk。 以下示例创建一个 20GiB 的磁盘,并在创建后输出磁盘的 ID。 如果需要创建与 Windows Server 容器一起使用的磁盘,请添加 --os-type windows 参数以正确格式化该磁盘。

    az disk create \
      --resource-group MC_myResourceGroup_myAKSCluster_chinaeast2 \
      --name myAKSDisk \
      --size-gb 20 \
      --query id --output tsv
    

    注意

    Azure 磁盘依据特定大小的 SKU 收取费用。 这些 SKU 的范围为 32 GiB(适用于 S4 或 P4 磁盘)到 32 TiB(适用于 S80 或 P80 磁盘),属于预览版。 高级托管磁盘的吞吐量和 IOPS 性能取决于 SKU 和 AKS 群集中节点的实例大小。 请参阅托管磁盘的定价和性能

    在命令成功完成后将显示磁盘资源 ID,如以下示例输出中所示。 在下一部分中使用此磁盘 ID 来装载磁盘。

    /subscriptions/<subscriptionID>/resourceGroups/MC_myAKSCluster_myAKSCluster_chinaeast2/providers/Microsoft.Compute/disks/myAKSDisk
    

将磁盘作为卷进行装载

  1. 使用 PersistentVolume 创建 pv-azuredisk.yaml 文件。 使用上一步骤中的磁盘资源 ID 更新 volumeHandle。 对于 Windows Server 容器,请将参数 fsType 指定为 ntfs。

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv-azuredisk
    spec:
      capacity:
        storage: 20Gi
      accessModes:
        - ReadWriteOnce
      persistentVolumeReclaimPolicy: Retain
      storageClassName: managed-csi
      csi:
        driver: disk.csi.azure.com
        volumeHandle: /subscriptions/<subscriptionID>/resourceGroups/MC_myAKSCluster_myAKSCluster_chinaeast2/providers/Microsoft.Compute/disks/myAKSDisk
        volumeAttributes:
          fsType: ext4
    
  2. 创建一个 pvc-azuredisk.yaml 文件,其中包含使用 PersistentVolume 的 PersistentVolumeClaim。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-azuredisk
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 20Gi
      volumeName: pv-azuredisk
      storageClassName: managed-csi
    
  3. 使用 kubectl apply 命令创建 PersistentVolumePersistentVolumeClaim,并引用已创建的两个 YAML 文件。

    kubectl apply -f pv-azuredisk.yaml
    kubectl apply -f pvc-azuredisk.yaml
    
  4. 使用 kubectl get pvc 命令验证 PersistentVolumeClaim 是否已创建并绑定到 PersistentVolume

    kubectl get pvc pvc-azuredisk
    

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

    NAME            STATUS   VOLUME         CAPACITY    ACCESS MODES   STORAGECLASS   AGE
    pvc-azuredisk   Bound    pv-azuredisk   20Gi        RWO                           5s
    
  5. 创建 azure-disk-pod.yaml 文件以引用 PersistentVolumeClaim。 对于 Windows Server 容器,请使用 Windows 路径约定指定 mountPath,例如“D:”。

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      nodeSelector:
        kubernetes.io/os: linux
      containers:
      - image: mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine
        name: mypod
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 250m
            memory: 256Mi
        volumeMounts:
          - name: azure
            mountPath: /mnt/azure
      volumes:
        - name: azure
          persistentVolumeClaim:
            claimName: pvc-azuredisk
    
  6. 使用 kubectl apply 命令应用配置并装载卷。

    kubectl apply -f azure-disk-pod.yaml
    

清理资源

完成本文中创建的资源后,可以使用 kubectl delete 命令将其删除。

# Remove the pod
kubectl delete -f azure-pvc-disk.yaml

# Remove the persistent volume claim
kubectl delete -f azure-pvc.yaml

后续步骤