在 Azure Kubernetes 服务 (AKS) 中使用 Azure 文件存储容器存储接口 (CSI) 驱动程序

Azure 文件存储容器存储接口 (CSI) 驱动程序是符合 CSI 规范的驱动程序,供 Azure Kubernetes 服务 (AKS) 用来管理 Azure 文件共享的生命周期。 CSI 是有关对 Kubernetes 上的容器化工作负载公开任意块和文件存储系统的一个标准。

现在,AKS 可以采用 CSI 来编写、部署和迭代插件,以在 Kubernetes 中公开新的或改进现有的存储系统。 在 AKS 中使用 CSI 驱动程序可以避免改动核心 Kubernetes 代码并等待完成代码发布周期。

重要

从 Kubernetes 版本 1.21 开始,Kubernetes 仅使用 CSI 驱动程序,这也是它的默认做法。 这些驱动程序代表了 Kubernetes 中将来所支持的存储的趋势。

对于低于 1.21 的 Kubernetes 版本,Kubernetes 将不支持在 Azure 中国世纪互联中启用 CSI 驱动程序。

注意

“树中驱动程序”是指包含在核心 Kubernetes 代码中的当前存储驱动程序,而不是新的 CSI 驱动程序(插件)。

Azure 文件存储 CSI 驱动程序新功能

除了原始的树内驱动程序功能外,Azure 文件存储 CSI 驱动程序还支持以下新功能:

  • 网络文件系统 (NFS) 版本 4.1
  • 专用终结点
  • 并行创建大量文件共享。

通过 Azure 文件存储使用永久性卷

永久性卷 (PV) 表示已经过预配的可用于 Kubernetes Pod 的存储块。 一个 PV 可供一个或多个 Pod 使用,并可动态或静态预配。 如果多个 Pod 需要同时访问同一存储卷,你可以使用 Azure 文件存储通过服务器消息块 (SMB)NFS 协议进行连接。 本文将介绍如何动态创建 Azure 文件共享以供 AKS 群集中的多个 Pod 使用。 有关静态预配,请参阅通过 Azure 文件共享手动创建并使用卷

在节点上没有对 Azure 文件存储共享的装载个数限制。

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

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

存储类用于定义如何创建 Azure 文件共享。 系统会在节点资源组中自动创建一个存储帐户,以便与存储类一起用来保存 Azure 文件共享。 为“skuName”选择以下 Azure 存储冗余 SKU 之一:

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

注意

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

在 AKS 中使用存储 CSI 驱动程序时,还有两个内置 StorageClasses 使用 Azure 文件存储 CSI 存储驱动程序。 其他这些 CSI 存储类是使用群集连同树中默认的存储类一起创建的。

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

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

若要使用这些存储类,请创建一个引用并使用这些类的 PVC 和相应 Pod。 PVC 用于基于存储类自动预配存储。 PVC 可以使用一个预先创建的存储类或用户定义的存储类,为所需的 SKU 和大小创建 Azure 文件共享。 创建 Pod 定义时,将指定 PVC 来请求所需的存储。

通过运行 kubectl apply 命令创建一个可将当前日期输出到 outfile 的示例 PVC 和 Pod

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

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

persistentvolumeclaim/pvc-azurefile created
pod/nginx-azurefile created

在 Pod 处于运行状态后,可以通过运行以下命令并验证输出中是否包含 outfile,来验证是否正确装载了文件共享:

kubectl exec nginx-azurefile -- ls -l /mnt/azurefile

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

total 29
-rwxrwxrwx 1 root root 29348 Aug 31 21:59 outfile

创建自定义存储类

默认存储类适合最常见的方案,但并非适合所有方案。 在某些情况下,你可能想要使用自己的参数来自定义自己的存储类。 例如,使用以下清单配置文件共享的 mountOptions

对于 Kubernetes 装载的文件共享,fileMode 和 dirMode 的默认值为 0777 。 可以在存储类对象中指定不同的装载选项。

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

通过运行 kubectl apply 命令创建存储类:

kubectl apply -f azure-file-sc.yaml

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

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

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

注意

此驱动程序仅支持创建快照,不支持从快照还原。 可以通过 Azure 门户或 CLI 还原快照。 有关创建和还原快照的详细信息,请参阅 Azure 文件存储的共享快照概述

使用 kubectl apply 命令创建卷快照类

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

基于我们在本教程开头动态创建的 PVC pvc-azurefile 创建卷快照

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

运行以下命令验证是否正确创建了快照:

kubectl describe volumesnapshot azurefile-volume-snapshot

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

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:               c359a38f-35c1-4fb1-9da9-2c06d35ca0f4
Spec:
  Source:
    Persistent Volume Claim Name:  pvc-azurefile
  Volume Snapshot Class Name:      csi-azurefile-vsc
Status:
  Bound Volume Snapshot Content Name:  snapcontent-c359a38f-35c1-4fb1-9da9-2c06d35ca0f4
  Ready To Use:                        false
Events:                                <none>

调整永久性卷的大小

可为 PVC 请求较大的卷。 编辑 PVC 对象,并指定较大的大小。 此项更改会触发为 PV 提供支持的基础卷的扩展。

注意

永远不会创建新的 PV 来满足声明, 而是会调整现有卷的大小。

目前不支持收缩永久性卷。

在 AKS 中,内置的 azurefile-csi 存储类已经能够支持扩展,因此请使用先前通过此存储类创建的 PVC。 PVC 请求了 100 GiB 文件共享。 可通过运行以下命令来确认一点:

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

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

Filesystem                                                                                Size  Used Avail Use% Mounted on
//f149b5a219bd34caeb07de9.file.core.chinacloudapi.cn/pvc-5e5d9980-da38-492b-8581-17e3cad01770  100G  128K  100G   1% /mnt/azurefile

通过增大 spec.resources.requests.storage 字段值来扩展 PVC:

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

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

persistentvolumeclaim/pvc-azurefile patched

验证 Pod 中的 PVC 和文件系统是否都显示新的大小:

kubectl get pvc pvc-azurefile
NAME            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS    AGE
pvc-azurefile   Bound    pvc-5e5d9980-da38-492b-8581-17e3cad01770   200Gi      RWX            azurefile-csi   64m

kubectl exec -it nginx-azurefile -- df -h /mnt/azurefile
Filesystem                                                                                Size  Used Avail Use% Mounted on
//f149b5a219bd34caeb07de9.file.core.chinacloudapi.cn/pvc-5e5d9980-da38-492b-8581-17e3cad01770  200G  128K  200G   1% /mnt/azurefile

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

如果 Azure 文件存储资源受专用终结点保护,则必须创建自己的存储类。 请确保你已将 DNS 设置配置为将专用终结点 IP 地址解析为连接字符串的 FQDN。 自定义以下参数:

  • resourceGroup:部署存储帐户的资源组。
  • storageAccount:存储帐户名称。
  • server:存储帐户的专用终结点的 FQDN。

创建一个名为 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

使用 kubectl apply 命令创建存储类:

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

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

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

创建一个名为 private-pvc.yaml 的文件,然后将以下示例清单粘贴到该文件中:

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

使用 kubectl apply 命令创建 PVC:

kubectl apply -f private-pvc.yaml

NFS 文件共享

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

此选项已针对包含就地数据更新的随机访问工作负载进行优化,提供全面的 POSIX 文件系统支持。 本部分将介绍如何在 AKS 群集上通过 Azure 文件存储 CSI 驱动程序使用 NFS 共享。

先决条件

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

注意

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

优化读取和写入大小选项

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

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

请务必执行测试,以查找可维持高效数据包传输的 rsize 和 wsize,并且不会降低吞吐量和增加延迟。

例如,若要配置最大 rsizewsize,即 256-KiB,请在存储类中配置 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
  - rsize=262144
  - wsize=262144

创建 NFS 文件共享存储类

创建一个名为 nfs-sc.yaml 的文件并复制以下清单。 有关支持的 mountOptions 的列表,请参阅 NFS 装载选项

注意

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

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

编辑并保存该文件后,使用 kubectl apply 命令创建存储类:

kubectl apply -f nfs-sc.yaml

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

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

使用 NFS 支持的文件共享创建部署

可以通过 kubectl apply 命令部署 StatefulSet 示例,该示例将时间戳保存到文件 data.txt 中:

kubectl apply -f

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

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

statefulset.apps/statefulset-azurefile created

运行以下命令验证卷的内容:

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

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

Filesystem      Size  Used Avail Use% Mounted on
...
/dev/sda1                                                                                 29G   11G   19G  37% /etc/hosts
accountname.file.core.chinacloudapi.cn:/accountname/pvc-fa72ec43-ae64-42e4-a8a2-556606f5da38  100G     0  100G   0% /mnt/azurefile
...

注意

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

Windows 容器

Azure 文件存储 CSI 驱动程序还支持 Windows 节点和容器。 若要使用 Windows 容器,请遵循 Windows 容器快速入门教程添加 Windows 节点池。

添加 Windows 节点池后,使用内置的存储类(例如 azurefile-csi)或创建自定义的存储类。 可以通过运行 kubectl apply 命令部署基于 Windows 的 StatefulSet 示例,该示例将时间戳保存到文件 data.txt 中:

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

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

statefulset.apps/busybox-azurefile created

运行以下 kubectl exec 命令验证卷的内容:

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
(...)

后续步骤