在 Azure Kubernetes 服务(AKS)中使用 Azure 文件创建和管理永久性卷(PV)

如果多个 Pod 需要对同一存储卷进行并发访问,则可以使用 Azure 文件存储使用 服务器消息块(SMB)NFS 协议进行连接。 本文介绍如何使用 Azure 文件动态和静态创建 Azure 文件共享,供 Azure Kubernetes 服务 (AKS) 群集中的多个 Pod 使用。

注释

Azure 文件 CSI 驱动程序仅允许使用基于密钥(NTLM v2)的身份验证来装载 SMB 文件共享,因此不支持 Azure 文件共享设置的最高安全设置。 另一方面,装载 NFS 文件共享不需要基于密钥的身份验证。

注释

建议在运行基准测试时使用 FIO。 有关详细信息,请参阅 基准测试工具和测试

先决条件

使用内置存储类通过 Azure 文件创建动态 PV

存储类用于定义使用永久性卷动态创建存储单位的方式。 在 节点资源组 中会自动创建一个存储帐户,以便与存储类配合使用,存储 Azure 文件共享。 在 AKS 上使用 CSI 驱动程序时,有两个额外的内置 StorageClasses,其使用了 Azure 文件 CSI 存储驱动程序(其他 CSI 存储类与群集一同创建,并列于内置默认存储类):

  • azurefile-csi:使用 Azure 标准存储创建 Azure 文件共享。
  • azurefile-csi-premium:使用Azure Premium Storage创建Azure文件共享。

这两个存储类的回收策略确保在删除相应的 PV 时,底层的 Azure 文件共享被删除。 这些存储类还会将文件共享配置为可扩展,你只需使用新的大小编辑永久性卷声明 (PVC) 即可。

可以为存储类定义中的参数选择以下 Azure 存储冗余 SKUskuname 之一:

  • Standard_LRS:标准本地冗余存储
  • Standard_GRS:标准异地冗余存储
  • Standard_ZRS:标准区域冗余存储
  • Standard_RAGRS:标准只读访问地理冗余存储
  • Standard_RAGZRS:标准读取访问地理区域冗余存储
  • Premium_LRS:高级本地冗余存储
  • Premium_ZRS:高级区域冗余存储

注释

Azure Files支持Azure高级文件共享。 最小文件共享容量为 100 GiB。 建议使用 Azure 高级文件共享而不是标准文件共享,因为高级文件共享为 I/O 密集型工作负荷提供更高的性能、低延迟磁盘支持。

使用 Azure 文件创建动态 PV 的自定义存储类

默认存储类适用于大多数方案。 在某些情况下,你可能想要使用自己的参数自定义自己的存储类。 例如,你可能想要配置 mountOptions 文件共享。

  1. 在以下示例清单中创建一个名为 azure-file-sc.yaml 并粘贴的文件:

    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      name: my-azurefile
    provisioner: file.csi.azure.com
    reclaimPolicy: Delete
    volumeBindingMode: Immediate
    allowVolumeExpansion: true
    mountOptions:
      - dir_mode=0640
      - file_mode=0640
      - uid=0
      - gid=0
      - mfsymlinks
      - cache=strict # https://linux.die.net/man/8/mount.cifs
      - nosharesock
    parameters:
      skuName: Standard_LRS
    
  2. 使用 kubectl apply 以下命令创建存储类:

    kubectl apply -f azure-file-sc.yaml
    

    输出应类似于以下示例输出:

    storageclass.storage.k8s.io/my-azurefile created
    

使用 Azure 文件存储动态 PV 的存储类参数

下表包含可用于使用 Azure 文件为永久性卷声明(PVC)定义自定义存储类的参数:

名称 含义 可用值 必需 默认值
accountAccessTier 存储帐户的访问层 标准帐户可以选择 HotCool,高级帐户只能选择 Premium 空白。 对不同的存储帐户类型使用默认设置。
accountQuota 限制帐户的配额。 默认情况下,可以指定最大配额(102400 GB)。 如果帐户超过指定的配额,驱动程序将跳过选择该帐户的步骤。 102400
allowBlobPublicAccess 允许或禁止对驱动程序创建的存储帐户中的所有 blob 或容器进行公共访问。 truefalse false
disableDeleteRetentionPolicy 指定是否禁用驱动程序创建的存储账户的DeleteRetentionPolicy。 truefalse false
folderName 在Azure文件共享中指定文件夹名称。 Azure文件共享中的现有文件夹名称。 如果文件共享中不存在文件夹名称,装载会失败。
getLatestAccount 确定是否根据创建时间获取最新的帐户密钥。 默认情况下,此驱动程序将获取第一个密钥。 truefalse false
location 指定 Azure 存储帐户的 Azure 区域。 例如,chinanorth3 如果为空,驱动程序将使用与当前 AKS 群集相同的位置名称。
matchTags 驱动程序在尝试查找合适的存储帐户时匹配标记。 truefalse false
networkEndpointType 为由驱动创建的存储帐户指定网络终结点类型。 如果指定了 privateEndpoint,则会为存储帐户创建专用终结点。 对于其他情况,默认会创建服务终结点。 "",privateEndpoint ""
protocol 指定文件共享协议。 smbnfs smb
requireInfraEncryption 指定服务是否对驱动程序创建的存储帐户中的静态数据应用由平台托管密钥的二次加密层。 truefalse false
resourceGroup 指定Azure磁盘的资源组。 现有资源组名称 如果为空,驱动程序将使用与当前 AKS 群集相同的资源组名称。
selectRandomMatchingAccount 确定是否随机选择匹配帐户。 默认情况下,驱动程序始终按字母顺序选择第一个匹配的帐户(注意:此驱动程序使用帐户搜索缓存,这会导致多个帐户之间的文件创建分布不均匀)。 truefalse false
server 指定Azure storage帐户服务器地址。 现有服务器地址,例如 accountname.privatelink.file.core.chinacloudapi.cn 如果为空,驱动程序使用默认的 accountname.file.core.chinacloudapi.cn 或其他主权云帐户地址。
shareAccessTier 文件共享的访问层 General purpose v2 帐户可以在 TransactionOptimized (默认值)、HotCool 之间进行选择。 仅适用于文件共享的高级存储帐户类型。 空白。 对不同的存储帐户类型使用默认设置。
shareName 指定Azure文件共享名称。 现有或新的Azure文件共享名称。 如果为空,驱动程序将生成Azure文件共享名称。
shareNamePrefix 指定Azure驱动程序创建的文件共享名称前缀。 共享名只能包含小写字母、数字、连字符,长度应少于 21 个字符。
skuName Azure Files 存储帐户类型(别名:storageAccountType Standard_LRS、、Standard_ZRSStandard_GRSStandard_RAGRS、、Standard_RAGZRSPremium_LRSPremium_ZRSStandardV2_LRSStandardV2_ZRSStandardV2_GRSStandardV2_GZRS、、 PremiumV2_LRSPremiumV2_ZRS Standard_LRS
高级帐户类型的最小文件共享大小为 100 GB。
ZRS 帐户类型在有限区域内受支持。
NFS 文件共享仅支持高级帐户类型。
标准 V2 SKU 名称适用于 预配的 Azure 文件存储 v2 模型
storageAccount 指定Azure storage帐户名称。 storageAccountName 如果未提供特定的存储帐户名称,驱动程序将查找与同一资源组中的帐户设置匹配的合适存储帐户。 如果驱动程序找不到匹配的存储帐户,则将创建新的存储帐户。 但是,如果指定了存储帐户名,则存储帐户必须已存在。
storageEndpointSuffix 指定 Azure 存储终结点后缀。 core.chinacloudapi.cncore.chinacloudapi.cn 如果为空,驱动程序会根据云环境使用默认的存储终结点后缀。 例如,core.chinacloudapi.cn
tags 标签是在新的存储帐户中创建的。 标记格式:“foo=aaa,bar=bbb” ""
--- 以下参数仅适用于 SMB 协议 --- --- ---
subscriptionID 指定创建Azure文件共享的Azure订阅 ID。 Azure 订阅 ID 如果不为空,则必须提供 resourceGroup
storeAccountKey 指定是否将存储帐户密钥存储为 Kubernetes 机密。 truefalse
false 表示驱动程序使用 kubelet 标识获取帐户密钥。
true
secretName 指定用于存储帐户密钥的机密名称。
secretNamespace 指定用于存储帐户密钥的机密的命名空间。

注意
如果未指定 secretNamespace,则会在 Pod 所在的同一命名空间中创建机密。
defaultkube-system 等。 PVC 命名空间,例如 csi.storage.k8s.io/pvc/namespace
useDataPlaneAPI 指定是否使用 数据平面 API 来创建、删除或调整文件共享的大小,这可以解决 SRP API 的限制问题,因为数据平面 API 几乎没有限制。不过,当存储账户上有防火墙或 Vnet 设置时,该方法可能会失败。 truefalse false
--- 以下参数仅适用于 NFS 协议 --- --- ---
mountPermissions 挂载的文件夹权限。 默认值为 0777。 如果设置为 0,则驱动程序在装载后不会执行 chmod 0777
rootSquashType 指定共享上的根压缩行为。 默认值为 NoRootSquash AllSquashNoRootSquashRootSquash
--- 以下参数仅适用于 VNet 设置(例如:NFS、专用终结点) --- --- ---
fsGroupChangePolicy 指示驱动程序如何更改卷的所有权。 Pod securityContext.fsGroupChangePolicy 将被忽略。 OnRootMismatch(默认)、AlwaysNone OnRootMismatch
subnetName 子网名称 代理节点的现有子网名称。 如果为空,驱动程序在 Azure 云配置文件中使用 subnetName 值。
vnetName 虚拟网络名称 现有虚拟网络名称。 如果为空,驱动程序将更新群集虚拟网络下的所有子网。
vnetResourceGroup 指定定义虚拟网络的 VNet 资源组。 现有资源组名称。 如果为空,驱动程序在 Azure 云配置文件中使用 vnetResourceGroup 值。

注释

如果存储帐户由驱动程序创建,则只需在存储类中指定 networkEndpointType: privateEndpoint 参数。 CSI 驱动程序将创建专用终结点和专用 DNS 区域(命名 privatelink.file.core.chinacloudapi.cn)以及帐户。 如果自带存储帐户,则需要为存储帐户 创建专用终结点 。 如果在网络隔离群集中使用 Azure 文件存储,则必须使用“networkEndpointType: privateEndpoint”创建自定义存储类。 可以使用以下示例清单作为参考:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: azurefile-csi
provisioner: file.csi.azure.com
allowVolumeExpansion: true
parameters:
  skuName: Premium_LRS  # available values: Premium_LRS, Premium_ZRS, Standard_LRS, Standard_GRS, Standard_ZRS, Standard_RAGRS, Standard_RAGZRS
  networkEndpointType: privateEndpoint
reclaimPolicy: Delete
volumeBindingMode: Immediate
mountOptions:
  - dir_mode=0777  # modify this permission if you want to enhance the security
  - file_mode=0777
  - mfsymlinks
  - cache=strict  # https://linux.die.net/man/8/mount.cifs
  - nosharesock  # reduce probability of reconnect race
  - actimeo=30  # reduce latency for metadata-heavy workload
  - nobrl  # disable sending byte range lock requests to the server and for applications which have challenges with posix locks

使用 Azure 文件创建 PVC

PVC 使用存储类对象动态预配 Azure 文件共享。 可以使用本部分中的示例 YAML 清单创建大小 为 100 GB 且具有 ReadWriteMany 访问权限的 PVC。 有关访问模式的详细信息,请参阅 Kubernetes PV 访问模式

  1. 创建一个名为azure-file-pvc.yaml的文件,并粘贴以下 YAML 内容。 请确保 storageClassName 的名称与您的现有存储类匹配。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: my-azurefile
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: my-azurefile
      resources:
        requests:
          storage: 100Gi
    

    注释

    如果使用 storage 类的 Premium_LRS SKU,则 storage 的最小值必须为 100Gi

  2. 使用 kubectl apply 命令创建 PVC。

    kubectl apply -f azure-file-pvc.yaml
    
  3. 使用 kubectl get 以下命令查看 PVC 的状态:

    kubectl get pvc my-azurefile
    

    输出应类似于以下示例输出,其中显示 PVC 处于 Bound 状态,并动态创建 PV 以满足声明:

    NAME           STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
    my-azurefile   Bound     pvc-aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb   100Gi       RWX            my-azurefile      5m
    

将 PVC 与 Pod 中的 Azure 文件配合使用

本节中的示例 YAML 清单创建了一个 Pod,Pod 使用 PVC my-azurefile 将 Azure Files 文件共享挂载到路径 /mnt/azure。 对于 Windows Server 容器,请使用 Windows 路径约定指定 mountPath,例如“D:”

  1. 创建一个名为 azure-pvc-files.yaml,并粘贴以下 YAML 的文件。 确保 claimName 匹配您现有 PVC 的名称。

    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: my-azurefile
    
  2. 使用 kubectl apply 命令创建 pod。

    kubectl apply -f azure-pvc-files.yaml
    
  3. 使用以下命令 kubectl describe 查看 Pod 的状态:

    kubectl describe pod mypod
    

    输出应类似于以下示例输出,其中显示了 Pod 正在运行,卷装载在正确的路径上。

    Containers:
      mypod:
        Container ID:   docker://BB22CC33DD44EE55FF66AA77BB88CC99DD00EE11
        Image:          mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine
        Image ID:       docker-pullable://nginx@sha256:AA11BB22CC33DD44EE55FF66AA77BB88CC99DD00
        State:          Running
          Started:      Fri, 01 Mar 2019 23:56:16 +0000
        Ready:          True
        Mounts:
          /mnt/azure from volume (rw)
          /var/run/secrets/kubernetes.io/serviceaccount from default-token-8rv4z (ro)
    [...]
    Volumes:
      volume:
        Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
        ClaimName:  my-azurefile
        ReadOnly:   false
    [...]
    

Azure 文件的装载选项

配置装载选项的位置(mountOptions)取决于是预配动态持久化卷还是静态持久化卷:

  • 如果要使用存储类动态预配卷,请在存储类对象(类型:StorageClass)上指定装载选项。
  • 如果要静态预配卷,请在 PV 对象上指定装载选项(类型:PersistentVolume)。
  • 如果要 将文件共享装载为内联卷,请在 Pod 对象上指定装载选项(类型:Pod)。

有关详细信息,请参阅装载选项

对于 Kubernetes 版本 1.13.0 及更高版本,fileModedirMode 的默认值为 0777。 以下示例设置 0777

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: my-azurefile
provisioner: file.csi.azure.com # replace with "kubernetes.io/azure-file" if aks version is less than 1.21
allowVolumeExpansion: true
mountOptions:
  - dir_mode=0777
  - file_mode=0777
  - uid=0
  - gid=0
  - mfsymlinks
  - cache=strict
  - actimeo=30
  - nobrl  # disable sending byte range lock requests to the server and for applications which have challenges with posix locks
parameters:
  skuName: Premium_LRS

以下存储类示例中提供了 SMB 共享的建议装载选项:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
    name: azurefile-csi
provisioner: file.csi.azure.com
allowVolumeExpansion: true
parameters:
    skuName: Premium_LRS  # available values: Premium_LRS, Premium_ZRS, Standard_LRS, Standard_GRS, Standard_ZRS, Standard_RAGRS, Standard_RAGZRS
reclaimPolicy: Delete
volumeBindingMode: Immediate
mountOptions:
    - dir_mode=0777  # modify this permission if you want to enhance the security
    - file_mode=0777 # modify this permission if you want to enhance the security
    - mfsymlinks    # support symbolic links
    - cache=strict  # https://linux.die.net/man/8/mount.cifs
    - nosharesock  # reduces probability of reconnect race
    - actimeo=30  # reduces latency for metadata-heavy workload
    - nobrl  # disable sending byte range lock requests to the server and for applications which have challenges with posix locks

如果使用高级(SSD)文件共享,并且工作负荷元数据繁重,请注册以使用 元数据缓存 功能来提高性能。

有关详细信息,请参阅 提高 SMB Azure 文件共享的性能

以下存储类示例中提供了建议的 NFS 共享装载选项:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
    name: azurefile-csi-nfs
provisioner: file.csi.azure.com
parameters:
    protocol: nfs
    skuName: Premium_LRS     # available values: Premium_LRS, Premium_ZRS
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true
mountOptions:
    - nconnect=4  # improves performance by enabling multiple connections to share
    - noresvport  # improves availability
    - actimeo=30  # reduces latency for metadata-heavy workloads

增加 预读大小 以提高读取吞吐量。

虽然 Azure Files 支持将 nconnect 最多设置为 16,但配置装载选项时建议使用最佳设置 nconnect=4。 目前,对于 nconnect 的 Azure 文件存储实现来说,超过 4 个通道不会带来增益。

使用 Azure Files 从 PVC 创建卷快照

Azure Files CSI 驱动程序支持创建持久卷的快照和基础文件共享。

  1. 使用以下命令创建卷快照类

    kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/deploy/example/snapshot/volumesnapshotclass-azurefile.yaml
    

    输出应类似于以下示例输出:

    volumesnapshotclass.snapshot.storage.k8s.io/csi-azurefile-vsc created
    
  2. 使用以下命令从之前在本教程中创建的动态 PVC 创建kubectl apply

    kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/deploy/example/snapshot/volumesnapshot-azurefile.yaml
    

    输出应类似于以下示例输出:

    volumesnapshot.snapshot.storage.k8s.io/azurefile-volume-snapshot created
    
  3. 使用 kubectl describe 命令查看卷快照的状态:

    kubectl describe volumesnapshot azurefile-volume-snapshot
    

    输出应类似于以下示例,其中表明卷快照尚未准备好使用,因为驱动程序仍在创建底层 Azure 文件共享的快照:

    Name:         azurefile-volume-snapshot
    Namespace:    default
    Labels:       <none>
    Annotations:  API Version:  snapshot.storage.k8s.io/v1beta1
    Kind:         VolumeSnapshot
    Metadata:
      Creation Timestamp:  2020-08-27T22:37:41Z
      Finalizers:
        snapshot.storage.kubernetes.io/volumesnapshot-as-source-protection
        snapshot.storage.kubernetes.io/volumesnapshot-bound-protection
      Generation:        1
      Resource Version:  955091
      Self Link:         /apis/snapshot.storage.k8s.io/v1beta1/namespaces/default/volumesnapshots/azurefile-volume-snapshot
      UID:               00aa00aa-bb11-cc22-dd33-44ee44ee44ee
    Spec:
      Source:
        Persistent Volume Claim Name:  pvc-azurefile
      Volume Snapshot Class Name:      csi-azurefile-vsc
    Status:
      Bound Volume Snapshot Content Name:  snapcontent-00aa00aa-bb11-cc22-dd33-44ee44ee44ee
      Ready To Use:                        false
    Events:                                <none>
    

通过 Azure 文件调整持久卷的大小

注释

目前不支持收缩永久性卷。 尝试修改尺寸比当前大小更小的现有 PVC 会出现以下错误消息:

The persistentVolumeClaim "pvc-azurefile" is invalid: spec.resources.requests.storage: Forbidden: field can not be less than previous value.

可以通过编辑 PVC 对象来请求更大的卷,指定更大的大小。 此项更改会触发为 PV 提供支持的基础卷的扩展。 永远不会创建新的 PV 来满足声明, 而是会调整现有卷的大小。

在 AKS 中,内置 managed-csi 存储类已经支持扩展,因此可以使用本教程前面创建的动态 PVC。 PVC 请求了 100 GiB 文件共享。

  1. 使用 kubectl exec 命令在 Pod 中运行 df -h 命令,验证 PVC 和文件系统的当前大小:

    kubectl exec -it nginx-azurefile -- df -h /mnt/azurefile
    

    输出应类似于以下示例输出,其中显示文件系统大小为 100 GB:

    Filesystem                                                                                      Size  Used Avail Use% Mounted on
    //a123b4c567de89fghi01jk2.file.core.chinacloudapi.cn/pvc-00aa00aa-bb11-cc22-dd33-44ee44ee44ee  100G  128K  100G   1% /mnt/azurefile
    
  2. 使用spec.resources.requests.storage命令增加kubectl patch字段,展开PVC。 在此示例中,我们将文件共享增加到 200 GiB:

    kubectl patch pvc pvc-azurefile --type merge --patch '{"spec": {"resources": {"requests": {"storage": "200Gi"}}}}'
    

    输出应类似于以下示例输出,其中显示 PVC 已成功修补:

    persistentvolumeclaim/pvc-azurefile patched
    
  3. 使用 kubectl get pvc 命令和 df -h 命令在 Pod 内验证 PVC 是否已成功调整大小,并检查新大小是否已在 Pod 中得到反映:

    kubectl get pvc pvc-azurefile
    

    输出应类似于以下示例输出,其中显示 PVC 仍处于 Bound 状态,容量已更新为 200 GiB:

    NAME            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS    AGE
    pvc-azurefile   Bound    pvc-00aa00aa-bb11-cc22-dd33-44ee44ee44ee   200Gi      RWX            azurefile-csi   64m
    
  4. 使用 kubectl exec 命令在 Pod 中运行 df -h 命令,验证 Pod 中文件系统的新大小:

    kubectl exec -it nginx-azurefile -- df -h /mnt/azurefile
    

    输出应类似于以下示例输出,其中显示文件系统大小现在为 200 GB:

    Filesystem                                                                                Size  Used Avail Use% Mounted on
    //a123b4c567de89fghi01jk2.file.core.chinacloudapi.cn/pvc-bbbbbbbb-1111-2222-3333-cccccccccccc  200G  128K  200G   1% /mnt/azurefile
    

通过 Azure 文件存储专用存储(专用终结点)使用永久性卷

如果“Azure Files”资源受到专用终结点的保护,则必须创建自己的存储类。 请确保你已将 DNS 设置配置为将专用终结点 IP 地址解析为连接字符串的 FQDN。 使用 Azure 文件 CSI 驱动程序创建存储类时,需要指定networkEndpointType参数,并将值设为privateEndpoint,同时提供以下参数:

  • resourceGroup:存储帐户所部署的资源组。
  • storageAccount:存储帐户名称。
  • server:存储帐户专用终结点的 FQDN。
  1. 创建一个名为private-azure-file-sc.yaml的文件,然后将以下清单粘贴到该文件中。 请确保替换 <resourceGroup><storageAccountName> 占位符。

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: private-azurefile-csi
    provisioner: file.csi.azure.com
    allowVolumeExpansion: true
    parameters:
      resourceGroup: <resourceGroup>
      storageAccount: <storageAccountName>
      server: <storageAccountName>.file.core.chinacloudapi.cn
    reclaimPolicy: Delete
    volumeBindingMode: Immediate
    mountOptions:
      - dir_mode=0777
      - file_mode=0777
      - uid=0
      - gid=0
      - mfsymlinks
      - cache=strict  # https://linux.die.net/man/8/mount.cifs
      - nosharesock  # reduce probability of reconnect race
      - actimeo=30  # reduce latency for metadata-heavy workload
    
  2. 使用 kubectl apply 以下命令创建存储类:

    kubectl apply -f private-azure-file-sc.yaml
    

    输出应类似于以下示例输出:

    storageclass.storage.k8s.io/private-azurefile-csi created
    
  3. 创建一个名为 private-pvc.yaml 的文件,并在其中粘贴以下清单。 请确保 storageClassName 的名称与您的现有存储类匹配。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: private-azurefile-pvc
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: private-azurefile-csi
      resources:
        requests:
          storage: 100Gi
    
  4. 使用 kubectl apply 命令创建 PVC。

    kubectl apply -f private-pvc.yaml
    

将 Azure 文件与 Windows 容器配合使用

Azure Files CSI 驱动程序还支持 Windows 节点和容器。 若要使用 Windows 容器,请遵循 Windows 容器快速入门教程添加 Windows 节点池。 拥有 Windows 节点池后,可以使用内置存储类,例如 azurefile-csi 或创建自定义存储类。 本部分中 基于 Windows 的有状态集 每隔一秒将时间戳保存到一个文件中 data.txt ,该文件使用 Azure 文件 CSI 驱动程序装载到 Azure 文件共享。

  1. 使用以下命令kubectl apply创建有状态集:

    kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/deploy/example/windows/statefulset.yaml
    

    输出应类似于以下示例输出:

    statefulset.apps/busybox-azurefile created
    
  2. 使用以下命令 kubectl exec 验证时间戳是否正在文件共享中写入,以在 Pod 中运行 cat 命令:

    kubectl exec -it busybox-azurefile-0 -- cat c:\\mnt\\azurefile\\data.txt # on Linux/MacOS Bash
    kubectl exec -it busybox-azurefile-0 -- cat c:\mnt\azurefile\data.txt # on Windows Powershell/CMD
    

    输出应类似于以下示例输出,其中显示了每秒写入文件共享的时间戳:

    2020-08-27 22:11:01Z
    2020-08-27 22:11:02Z
    2020-08-27 22:11:04Z
    (...)
    

将 NFS 协议与 Azure 文件配合使用

Azure 文件存储支持 NFS v4.1 协议。 Azure 文件存储的 NFS 版本 4.1 支持以服务形式提供了一个完全托管的 NFS 文件系统,该系统建立在高度可用且高度持久的分布式弹性存储平台基础之上。

此选项针对具有就地数据更新的随机访问工作负载进行了优化,并提供完整的 POSIX 文件系统支持。 本部分介绍如何在 AKS 群集上使用 Azure 文件 CSI 驱动程序的 NFS 共享。

将 NFS 共享与 Azure 文件配合使用的先决条件

  • AKS 群集 控制平面 标识(即 AKS 群集名称)将添加到 VNet 和 NetworkSecurityGroup 上的 “参与者 ”角色。
  • 必须将 AKS 群集服务主体或托管服务标识 (MSI) 添加到存储帐户的参与者角色。

注释

你可以使用专用终结点,而不允许访问所选的 VNet。

优化读取和写入大小选项

本部分介绍如何使用 Azure 文件 CSI 驱动程序通过rsizewsize选项进行 NFS 性能优化。 rsizewsize选项设置NFS操作的最大传输大小。 如果rsizewsize在装载时未指定,则客户端和服务器将协商两者所支持的最大大小。 目前,Azure 文件和新式 Linux 分发版都支持大小为 1,048,576 字节(1 MiB)的读取和写入大小。

最佳性能基于高效的客户端-服务器通信。 增加或减少 装载 读取和写入选项大小值可以提高 NFS 性能。 对于客户端和服务器之间传输的读/写数据包,针对 NFS 版本 2 的默认大小为 8 KB,针对 NFS 版本 3 和 4 的默认大小为 32 KB。 这些默认值可能太大或太小。 通过减少rsizewsize,并为每个 NFS 读取回复和写入请求发送较小的数据包,可以在拥堵的网络中提高 NFS 性能。 但是,这会增加跨网络发送数据所需的数据包数量,从而增加客户端和服务器上的网络总流量和 CPU 使用率。

请务必进行测试,以便找到能够保持高效数据包传输、不减少吞吐量且不增加延迟的rsizewsize

以下示例清单将存储类中 mountOptions 部分的节配置为最大 rsizewsize 256-KiB:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: azurefile-csi-nfs
provisioner: file.csi.azure.com
allowVolumeExpansion: true
parameters:
  protocol: nfs
mountOptions:
  - nconnect=4
  - noresvport
  - actimeo=30
  - rsize=262144
  - wsize=262144

有关支持的 mountOptions 列表,请参阅 NFS 装载选项

创建 NFS 文件共享存储类

注释

versminorversionsec 由 Azure 文件 CSI 驱动程序进行配置。 不支持在清单中为这些属性指定值。

  1. 创建一个名为 nfs-sc.yaml 的文件,并在其中粘贴以下清单。 请确保在参数部分中指定 protocol: nfs,并根据您的工作负荷需要调整 mountOptions

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: azurefile-csi-nfs
    provisioner: file.csi.azure.com
    allowVolumeExpansion: true
    parameters:
      protocol: nfs
    mountOptions:
      - nconnect=4
      - noresvport
      - actimeo=30
    
  2. 编辑并保存文件后,使用 kubectl apply 命令创建存储类。

    kubectl apply -f nfs-sc.yaml
    

    输出应类似于以下示例输出:

    storageclass.storage.k8s.io/azurefile-csi-nfs created
    

使用 NFS 支持的文件共享创建有状态集

  1. 创建一个名为 nfs-ss.yaml 的文件,并在其中粘贴以下清单。 此配置将时间戳保存到文件中 data.txt

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: statefulset-azurefile
      labels:
        app: nginx
    spec:
      podManagementPolicy: Parallel  # default is OrderedReady
      serviceName: statefulset-azurefile
      replicas: 1
      template:
        metadata:
          labels:
            app: nginx
        spec:
          nodeSelector:
            "kubernetes.io/os": linux
          containers:
            - name: statefulset-azurefile
              image: mcr.azk8s.cn/oss/nginx/nginx:1.19.5
              command:
                - "/bin/bash"
                - "-c"
                - set -euo pipefail; while true; do echo $(date) >> /mnt/azurefile/outfile; sleep 1; done
              volumeMounts:
                - name: persistent-storage
                  mountPath: /mnt/azurefile
      updateStrategy:
        type: RollingUpdate
      selector:
        matchLabels:
          app: nginx
      volumeClaimTemplates:
        - metadata:
            name: persistent-storage
          spec:
            storageClassName: azurefile-csi-nfs
            accessModes: ["ReadWriteMany"]
            resources:
              requests:
                storage: 100Gi
    
  2. 使用 kubectl apply 命令创建有状态集。

    kubectl apply -f nfs-ss.yaml
    

    输出应类似于以下示例输出:

    statefulset.apps/statefulset-azurefile created
    
  3. 使用以下 kubectl exec 命令在 Pod 中运行 df -h 命令,以验证卷的内容:

    kubectl exec -it statefulset-azurefile-0 -- df -h
    

    输出应类似于以下示例输出,其中显示 NFS 文件共享装载在大小正确的路径上:

    Filesystem      Size  Used Avail Use% Mounted on
    ...
    /dev/sda1                                                                                 29G   11G   19G  37% /etc/hosts
    accountname.file.core.chinacloudapi.cn:/accountname/pvc-cccccccc-2222-3333-4444-dddddddddddd  100G     0  100G   0% /mnt/azurefile
    ...
    

    由于 NFS 文件共享位于高级存储帐户中,因此最小文件共享大小为 100 GiB。 如果使用较小的存储大小创建 PVC,可能会遇到如下错误:无法创建文件共享 ... 大小 (5)...

传输中加密 (EiT) 用于 NFS 文件共享 (预览版)

注释

从 AKS 版本 1.33 开始,EiT 功能现在以预览版提供。 请注意,目前不支持 Ubuntu 20.04、Azure Linux、arm64 和 Windows 节点。

这些受支持区域中的以下 Linux 分发版支持此功能。

传输中的加密(EiT) 可确保对 VNET 中 NFS 文件共享的所有读取和写入都进行加密,从而提供额外的安全层。

通过在存储类参数中设置 encryptInTransit: "true" ,可以为 NFS Azure 文件共享启用传输中的数据加密。 例如:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: azurefile-csi-nfs
provisioner: file.csi.azure.com
allowVolumeExpansion: true
parameters:
  protocol: nfs
  encryptInTransit: "true"
mountOptions:
  - nconnect=4
  - noresvport
  - actimeo=30

使用托管标识访问 Azure 文件存储(预览版)

Azure 文件现在支持对 SMB 访问进行基于托管标识的身份验证。 这使应用程序能够安全地访问 Azure 文件,而无需存储或管理凭据。

注释

从 AKS 版本 1.34 开始,Linux 节点上的 AKS 可在预览版中提供对 Azure Files 的托管标识支持。

使用托管标识访问 Azure 文件存储的先决条件

  • 确保 用户分配的 Kubelet 标识 在存储帐户上具有 Storage File Data SMB MI Admin 角色。
    • 如果使用自己的存储账户,则需要将 Storage File Data SMB MI Admin 角色分配给用户指定的 Kubelet 标识,并在该存储账户上进行设定。
    • 如果存储帐户由 CSI 驱动程序创建,请向存储帐户所在的资源组授予 Storage File Data SMB MI Admin 角色。
    • 如果只是利用默认的内置用户分配的 Kubelet 标识,则它已具有托管节点资源组上所需的 Storage File Data SMB MI Admin 角色。

使用 Azure 文件为动态 PV 启用托管标识

若要为动态预配卷启用托管标识,需要创建一个新的存储类,其中包括 mountWithManagedIdentity"true",然后使用此存储类部署您的有状态集。

以下示例清单将存储类配置为使用托管标识访问 Azure 文件:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: azurefile-csi
provisioner: file.csi.azure.com
parameters:
   resourceGroup: EXISTING_RESOURCE_GROUP_NAME   # optional, node resource group by default if it's not provided
   storageAccount: EXISTING_STORAGE_ACCOUNT_NAME # optional, a new account will be created if it's not provided
   mountWithManagedIdentity: "true"
   # optional, clientID of the managed identity, kubelet identity would be used by default if it's not provided
   clientID: "xxxxx-xxxx-xxx-xxx-xxxxxxx"
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true
mountOptions:
   - dir_mode=0777  # modify this permission if you want to enhance the security
   - file_mode=0777
   - uid=0
   - gid=0
   - mfsymlinks
   - cache=strict  # https://linux.die.net/man/8/mount.cifs
   - nosharesock  # reduce probability of reconnect race
   - actimeo=30  # reduce latency for metadata-heavy workload
   - nobrl  # disable sending byte range lock requests to the server

使用 Azure 文件为静态 PV 启用托管标识

若要为静态卷启用托管标识,需要创建一个带有mountWithManagedIdentity: "true"配置的 PV,并将该 PV 装载到应用程序 Pod。

以下示例清单将 PV 配置为使用托管标识访问 Azure 文件存储:

apiVersion: v1
kind: PersistentVolume
metadata:
   name: pv-azurefile
spec:
   capacity:
   storage: 100Gi
   accessModes:
   - ReadWriteMany
   persistentVolumeReclaimPolicy: Retain
   storageClassName: azurefile-csi
   mountOptions:
   - dir_mode=0777  # modify this permission if you want to enhance the security
   - file_mode=0777
   - uid=0
   - gid=0
   - mfsymlinks
   - cache=strict  # https://linux.die.net/man/8/mount.cifs
   - nosharesock  # reduce probability of reconnect race
   - actimeo=30  # reduce latency for metadata-heavy workload
   - nobrl  # disable sending byte range lock requests to the server
   csi:
   driver: file.csi.azure.com
   # make sure volumeHandle is unique for every identical share in the cluster
   volumeHandle: "{resource-group-name}#{account-name}#{file-share-name}"
   volumeAttributes:
       resourceGroup: EXISTING_RESOURCE_GROUP_NAME   # optional, node resource group by default if it's not provided
       storageAccount: EXISTING_STORAGE_ACCOUNT_NAME # optional, a new account will be created if it's not provided
       shareName: EXISTING_FILE_SHARE_NAME
       mountWithManagedIdentity: "true"
       # optional, clientID of the managed identity, kubelet identity would be used by default if it's empty
       clientID: "xxxxx-xxxx-xxx-xxx-xxxxxxx"

使用 Azure 文件创建静态 PV

以下部分提供有关使用 Azure 文件创建静态 PV 的说明。 静态 PV 是管理员手动创建的持久卷。 此 PV 可供集群中的 Pods 使用。 若要使用静态 PV,请创建引用 PV 的 PVC,然后创建引用 PVC 的 Pod。

使用 Azure 文件存储静态 PV 的存储类参数

下表包含可用于使用 Azure 文件为静态 PVC 定义自定义存储类的参数:

名称 含义 可用值 必需 默认值
volumeAttributes.resourceGroup 指定Azure资源组名称。 myResourceGroup 如果为空,驱动程序将使用与当前群集相同的资源组名称。
volumeAttributes.storageAccount 指定现有的Azure storage帐户名称。 storageAccountName 是的
volumeAttributes.shareName 指定Azure文件共享名称。 fileShareName 是的
volumeAttributes.folderName 在Azure文件共享中指定文件夹名称。 folderName 如果文件共享中不存在文件夹名称,装载将失败。
volumeAttributes.protocol 指定文件共享协议。 smbnfs smb
volumeAttributes.server 指定Azure storage帐户服务器地址 现有服务器地址,例如 accountname.privatelink.file.core.chinacloudapi.cn 如果为空,驱动程序使用默认的 accountname.file.core.chinacloudapi.cn 或其他主权云帐户地址。
--- 以下参数仅适用于 SMB 协议 --- --- ---
volumeAttributes.secretName 指定用于存储帐户名称和密钥的机密名称。
volumeAttributes.secretNamespace 指定机密命名空间。 defaultkube-system 等。 PVC 命名空间(csi.storage.k8s.io/pvc/namespace
nodeStageSecretRef.name 指定用于存储帐户名称和密钥的机密名称。 现有机密名称。 如果为空,驱动程序则使用 kubelet 标识获取帐户密钥。
nodeStageSecretRef.namespace 指定机密命名空间。 Kubernetes 命名空间
--- 以下参数仅适用于 NFS 协议 --- --- ---
volumeAttributes.fsGroupChangePolicy 指示驱动程序如何更改卷的所有权。 Pod securityContext.fsGroupChangePolicy 将被忽略。 OnRootMismatch(默认)、AlwaysNone OnRootMismatch
volumeAttributes.mountPermissions 指定装载的文件夹权限。 默认值为 0777

创建 Azure 文件共享

必须先创建一个 Azure 存储帐户和 Azure Files 文件共享,然后才能将 Azure Files 文件共享用作 Kubernetes 卷。

  1. 使用命令 az aks show 通过参数 --query nodeResourceGroup 获取 AKS 群集的节点资源组的名称。

    az aks show --resource-group myResourceGroup --name myAKSCluster --query nodeResourceGroup -o tsv
    

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

    MC_myResourceGroup_myAKSCluster_chinanorth3
    
  2. 使用az storage account create命令和--sku参数创建存储帐户。 以下命令使用 Standard_LRS SKU 创建存储帐户。 请务必替换以下占位符:

    • myAKSStorageAccount,其中包含storage帐户的名称
    • nodeResourceGroupName 替换为 AKS 群集节点所在的资源组名称
    • location 替换为创建资源的区域名称。 它应与 AKS 群集节点为同一区域。
    az storage account create --name myAKSStorageAccount --resource-group nodeResourceGroupName --location location --sku Standard_LRS
    
  3. 使用 [az storage account show-connection-string][az-storage-account-show-connection-string] 命令将连接字符串导出为用于创建文件共享的环境变量。 请确保将storageAccountName替换为您的存储帐户名称,并将resourceGroupName替换为资源组名称。

    export AZURE_STORAGE_CONNECTION_STRING=$(az storage account show-connection-string --name storageAccountName --resource-group resourceGroupName -o tsv)
    

    注释

    必须使用密钥轮换或存储在 Azure 密钥保管库中来保护连接字符串。 有关连接字符串的详细信息,请参阅 配置 Azure Storage 连接字符串管理存储帐户访问密钥。 对于生产环境,Microsoft建议使用Microsoft Entra ID身份验证。 有关详细信息,请参阅授权访问 Azure 存储中的数据

  4. 使用 az storage share create 命令创建文件共享。 请确保将 shareName 替换为自己的共享名称。

    az storage share create --name shareName --connection-string $AZURE_STORAGE_CONNECTION_STRING
    
  5. 使用 [az storage account keys list][az-storage-account-keys-list] 命令将存储帐户密钥导出为环境变量。 请确保将storageAccountName替换为您的存储帐户名称,并将resourceGroupName替换为资源组名称。

    STORAGE_KEY=$(az storage account keys list --resource-group nodeResourceGroupName --account-name myAKSStorageAccount --query "[0].value" -o tsv)
    
  6. 使用以下命令显示存储帐户的名称和密钥。 记下用于在下一步中创建 Kubernetes 机密的存储帐户密钥。

    echo Storage account key: $STORAGE_KEY
    

创建 Kubernetes 机密

Kubernetes 需要凭据才能访问在上一步中创建的文件共享。 这些凭据存储在 Kubernetes 机密中,创建 Kubernetes Pod 时将引用它。

  • 使用 kubectl create secret 命令创建机密。 以下示例创建一个名为 azure-secret 的密钥,并提供上一步骤中的 azurestorageaccountnameazurestorageaccountkey。 若要使用现有Azure storage帐户,请提供帐户名称和密钥。

    kubectl create secret generic azure-secret --from-literal=azurestorageaccountname=myAKSStorageAccount --from-literal=azurestorageaccountkey=$STORAGE_KEY
    

将文件共享装载为持久卷

  1. 新建名为 azurefiles-pv.yaml 的文件,并将以下内容复制到其中。 在 csi 下,更新 resourceGroupvolumeHandleshareName。 对于装载选项,fileModedirMode 的默认值为 0777

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      annotations:
        pv.kubernetes.io/provisioned-by: file.csi.azure.com
      name: azurefile
    spec:
      capacity:
        storage: 5Gi
      accessModes:
        - ReadWriteMany
      persistentVolumeReclaimPolicy: Retain
      storageClassName: azurefile-csi
      csi:
        driver: file.csi.azure.com
        volumeHandle: "{resource-group-name}#{account-name}#{file-share-name}"  # make sure this volumeid is unique for every identical share in the cluster
        volumeAttributes:
          shareName: aksshare
        nodeStageSecretRef:
          name: azure-secret
          namespace: default
      mountOptions:
        - dir_mode=0777
        - file_mode=0777
        - uid=0
        - gid=0
        - mfsymlinks
        - cache=strict
        - nosharesock
        - nobrl  # disable sending byte range lock requests to the server and for applications which have challenges with posix locks
    
  2. 使用 kubectl create 命令创建 PV。

    kubectl create -f azurefiles-pv.yaml
    
  3. 创建名为 azurefiles-mount-options-pvc.yaml 的新文件,并粘贴以下内容。 请确保 storageClassName 与现有存储类的名称一致,并且 volumeName 与您在上一步中创建的 PV 名称一致。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: azurefile
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: azurefile-csi
      volumeName: azurefile
      resources:
        requests:
          storage: 5Gi
    
  4. 使用 kubectl apply 命令创建 PVC。

    kubectl apply -f azurefiles-mount-options-pvc.yaml
    
  5. 使用 kubectl get 命令验证您的 PVC 是否已创建并绑定到 PV。

    kubectl get pvc azurefile
    

    输出应类似于以下示例输出,其中显示了 PVC 处于 Bound 状态,并且绑定到名为 azurefile 的 PV:

    NAME        STATUS   VOLUME      CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    azurefile   Bound    azurefile   5Gi        RWX            azurefile      5s
    
  6. 更新容器规格以引用 YAML 文件中的 PVC 和 Pod。 例如:

    ...
      volumes:
      - name: azure
        persistentVolumeClaim:
          claimName: azurefile
    
  7. 无法就地更新 Pod 规范,因此请使用 kubectl delete 命令删除 Pod,然后使用 kubectl apply 命令重新创建 Pod。

    kubectl delete pod mypod
    kubectl apply -f azure-files-pod.yaml
    

将文件共享挂载为内嵌卷

注释

为了避免性能问题,建议您在大量 Pod 访问同一文件共享时使用持久卷而不是内联卷。 内联卷只能访问与 Pod 位于相同命名空间中的机密。 若要指定不同的机密命名空间,请使用 persistent volume

若要将 Azure Files 文件共享装载到 Pod 中,请在容器规范中配置卷。

  1. 新建名为 azure-files-pod.yaml 的文件,并将以下内容复制到其中。 如果更改了文件共享名称或机密名称,请更新 shareNamesecretName。 还可以更新 mountPath,这是文件共享在 Pod 中的装载路径。 对于 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
              readOnly: false
      volumes:
        - name: azure
          csi:
            driver: file.csi.azure.com
            volumeAttributes:
              secretName: azure-secret  # required
              shareName: aksshare  # required
              mountOptions: 'dir_mode=0777,file_mode=0777,cache=strict,actimeo=30,nosharesock,nobrl'  # optional
    
  2. 使用 kubectl apply 命令创建 pod。

    kubectl apply -f azure-files-pod.yaml
    
  3. 使用以下命令 kubectl describe 查看 Pod 的状态:

    kubectl describe pod mypod