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

基于容器的应用程序通常需要访问数据并将数据保存在外部数据卷中。 如果多个 Pod 需要并发访问同一存储卷,可使用 Azure Blob 存储通过 blobfuse 或网络文件系统 (NFS) 进行连接。

本文介绍如何安装容器存储接口 (CSI) 驱动程序,并动态创建 Azure Blob 存储容器以附加到 AKS 中的 Pod。

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

准备阶段

动态预配参数

名称 步骤 示例 必需 默认值
skuName 指定 Azure 存储帐户类型(别名:storageAccountType)。 Standard_LRSPremium_LRSStandard_GRSStandard_RAGRS Standard_LRS
location 指定 Azure 位置。 chinaeast2 如果为空,驱动程序将使用与当前群集相同的位置名称。
resourceGroup 指定 Azure 资源组名称。 myResourceGroup 如果为空,驱动程序将使用与当前群集相同的资源组名称。
storageAccount 指定 Azure 存储帐户名称。 storageAccountName - 否,针对 blobfuse 装载
- 是,针对 NFSv3 装载。
- 对于 blobfuse 装载:如果为空,驱动程序将在同一资源组中查找与 skuName 匹配的合适存储帐户。 如果提供存储帐户名称,则必须存在存储帐户。
- 对于 NFSv3 装载,必须提供存储帐户名称。
protocol 指定 blobfuse 装载或 NFSv3 装载。 fusenfs fuse
containerName 指定现有容器(目录)名称。 container 如果为空,驱动程序会创建一个新的容器名称,对于 blobfuse 以 pvc-fuse 开头,对于 NFS v3 以 pvc-nfs 开头。
containerNamePrefix 指定驱动程序创建的 Azure 存储目录前缀。 my 只能包含小写字母、数字、连字符,且字符长度不能超过 21 个字符。
server 指定 Azure 存储帐户域名。 现有存储帐户 DNS 域名,例如 <storage-account>.privatelink.blob.core.chinacloudapi.cn 如果为空,驱动程序将使用默认 <storage-account>.blob.core.chinacloudapi.cn 或其他主权云存储帐户 DNS 域名。
allowBlobPublicAccess 允许或禁止公共访问驱动程序创建的存储帐户的所有 Blob 或容器。 truefalse false
storageEndpointSuffix 指定 Azure 存储终结点后缀。 core.chinacloudapi.cn 如果为空,驱动程序将根据云环境使用默认存储终结点后缀。
标记 [tags][az-tags] 将在新的存储帐户中创建。 标记格式:“foo=aaa,bar=bbb” ""
matchTags 驱动程序尝试查找合适的存储帐户时匹配标记。 truefalse false
--- 以下参数仅适用于 blobfuse --- --- ---
subscriptionID 指定要创建 blob 存储目录的 Azure 订阅 ID。 Azure 订阅 ID 如果不为空,则必须提供 resourceGroup
storeAccountKey 指定 Kubernetes 机密的存储帐户密钥。

请注意:
false 表示驱动程序使用 kubelet 标识获取帐户密钥。
truefalse true
secretName 指定用于存储帐户密钥的机密名称。
secretNamespace 指定用于存储帐户密钥的机密的命名空间。 defaultkube-system 等。 Pvc 命名空间
isHnsEnabled 为 Azure DataLake 存储帐户启用 Hierarchical namespace truefalse false
--- 以下参数仅适用于 NFS 协议 --- --- ---
mountPermissions 指定装载的文件夹权限。 默认为 0777。 如果设置为 0,驱动程序在装载后将不执行 chmod 0777

使用内置存储类创建永久性卷声明

永久性卷声明 (PVC) 使用存储类对象来动态预配 Azure Blob 存储容器。 可使用以下 YAML,通过内置存储类创建具有 ReadWriteMany 访问权限的永久性卷,其大小为 5 GB。 有关访问模式的详细信息,请参阅 Kubernetes 永久性卷文档。

  1. 创建名为 blob-nfs-pvc.yaml 的文件,并将其复制到以下 YAML 中。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: azure-blob-storage
      annotations:
            volume.beta.kubernetes.io/storage-class: azureblob-nfs-premium
    spec:
      accessModes:
      - ReadWriteMany
      storageClassName: my-blobstorage
      resources:
        requests:
          storage: 5Gi
    
  2. 使用 kubectl create 命令创建永久性卷声明:

    kubectl create -f blob-nfs-pvc.yaml
    

完成后,将创建 Blob 存储容器。 可以使用 kubectl get 命令查看 PVC 的状态:

kubectl get pvc azure-blob-storage

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

NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS                AGE
azure-blob-storage   Bound    pvc-b88e36c5-c518-4d38-a5ee-337a7dda0a68   5Gi        RWX            azureblob-nfs-premium       92m

使用永久性卷声明

以下 YAML 创建的 Pod 使用永久性卷声明 azure-blob-storage 将 Azure Blob 存储装载到 /mnt/blob 路径。

  1. 创建名为 blob-nfs-pv 的文件,并将其复制到以下 YAML 中。 请确保 claimName 与上一步骤中创建的 PVC 匹配。

    kind: Pod
    apiVersion: v1
    metadata:
      name: mypod
    spec:
      containers:
      - name: mypod
        image: mcr.azk8s.cn/oss/nginx/nginx:1.17.3-alpine
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 250m
            memory: 256Mi
        volumeMounts:
        - mountPath: "/mnt/blob"
          name: volume
      volumes:
        - name: volume
          persistentVolumeClaim:
            claimName: azure-blob-storage
    
  2. 使用 kubectl apply 命令创建 Pod:

    kubectl apply -f blob-nfs-pv.yaml
    
  3. Pod 处于运行状态后,运行以下命令创建名为 test.txt 的新文件。

    kubectl exec mypod -- touch /mnt/blob/test.txt
    
  4. 若要验证磁盘是否已正确装载,请运行以下命令并验证输出是否出现 test.txt 文件:

    kubectl exec mypod -- ls /mnt/blob
    

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

    test.txt
    

创建自定义存储类

默认存储类适合最常见的方案,但并非适合所有方案。 在某些情况下,你可能想要使用自己的参数来自定义自己的存储类。 为进行演示,给出了两个示例。 一个基于使用 NFS 协议,另一个使用 blobfuse。

使用 NFS 协议的存储类

在此示例中,以下清单使用 NFS 协议配置装载 Blob 存储容器。 使用它添加 tag 参数。

  1. 创建名为 blob-nfs-sc.yaml 的文件,并粘贴以下示例清单:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: azureblob-nfs-premium
    provisioner: blob.csi.azure.com
    parameters:
      protocol: nfs
      tags: environment=Development
    volumeBindingMode: Immediate
    mountOptions:
      - nconnect=8  # only supported on linux kernel version >= 5.3
    
  2. 使用 kubectl apply 命令创建存储类:

    kubectl apply -f blob-nfs-sc.yaml
    

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

    storageclass.storage.k8s.io/blob-nfs-premium created
    

使用 blobfuse 的存储类

在此示例中,以下清单使用 blobfuse 配置并装载 Blob 存储容器。 使用它更新 skuName 参数。

  1. 创建名为 blobfuse-sc.yaml 的文件,并粘贴以下示例清单:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: azureblob-fuse-premium
    provisioner: blob.csi.azure.com
    parameters:
      skuName: Standard_GRS  # available values: Standard_LRS, Premium_LRS, Standard_GRS, Standard_RAGRS
    reclaimPolicy: Delete
    volumeBindingMode: Immediate
    allowVolumeExpansion: true
    mountOptions:
      - -o allow_other
      - --file-cache-timeout-in-seconds=120
      - --use-attr-cache=true
      - --cancel-list-on-mount-seconds=10  # prevent billing charges on mounting
      - -o attr_timeout=120
      - -o entry_timeout=120
      - -o negative_timeout=120
      - --log-level=LOG_WARNING  # LOG_WARNING, LOG_INFO, LOG_DEBUG
      - --cache-size-mb=1000  # Default will be 80% of available memory, eviction will happen beyond that.
    
  2. 使用 kubectl apply 命令创建存储类:

    kubectl apply -f blobfuse-sc.yaml
    

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

    storageclass.storage.k8s.io/blob-fuse-premium created
    

后续步骤