如果多个 Pod 需要对同一存储卷进行并发访问,则可以使用 Azure 文件存储使用 服务器消息块(SMB) 或 NFS 协议进行连接。 本文介绍如何使用 Azure 文件动态和静态创建 Azure 文件共享,供 Azure Kubernetes 服务 (AKS) 群集中的多个 Pod 使用。
注释
Azure 文件 CSI 驱动程序仅允许使用基于密钥(NTLM v2)的身份验证来装载 SMB 文件共享,因此不支持 Azure 文件共享设置的最高安全设置。 另一方面,装载 NFS 文件共享不需要基于密钥的身份验证。
注释
建议在运行基准测试时使用 FIO。 有关详细信息,请参阅 基准测试工具和测试。
先决条件
- 已安装并配置 Azure CLI 2.0.59 或更高版本。 使用
az --version命令查找版本。 若要安装或升级,请参阅安装 Azure CLI。 - 在 AKS 群集上启用了 Azure 文件 CSI 驱动程序。
- Azure 存储帐户。
- 在标准文件共享和高级文件共享之间进行选择时,请务必了解计划在 Azure 文件上运行的预期使用模式的预配模型和要求。 有关详细信息,请参阅根据使用模式选择 Azure 文件性能层。
使用内置存储类通过 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 文件共享。
在以下示例清单中创建一个名为
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 文件存储动态 PV 的存储类参数
下表包含可用于使用 Azure 文件为永久性卷声明(PVC)定义自定义存储类的参数:
| 名称 | 含义 | 可用值 | 必需 | 默认值 |
|---|---|---|---|---|
accountAccessTier |
存储帐户的访问层 | 标准帐户可以选择 Hot 或 Cool,高级帐户只能选择 Premium。 |
否 | 空白。 对不同的存储帐户类型使用默认设置。 |
accountQuota |
限制帐户的配额。 默认情况下,可以指定最大配额(102400 GB)。 如果帐户超过指定的配额,驱动程序将跳过选择该帐户的步骤。 | 否 | 102400 |
|
allowBlobPublicAccess |
允许或禁止对驱动程序创建的存储帐户中的所有 blob 或容器进行公共访问。 |
true 或 false |
否 | false |
disableDeleteRetentionPolicy |
指定是否禁用驱动程序创建的存储账户的DeleteRetentionPolicy。 |
true 或 false |
否 | false |
folderName |
在Azure文件共享中指定文件夹名称。 | Azure文件共享中的现有文件夹名称。 | 否 | 如果文件共享中不存在文件夹名称,装载会失败。 |
getLatestAccount |
确定是否根据创建时间获取最新的帐户密钥。 默认情况下,此驱动程序将获取第一个密钥。 |
true 或 false |
否 | false |
location |
指定 Azure 存储帐户的 Azure 区域。 | 例如,chinanorth3。 |
否 | 如果为空,驱动程序将使用与当前 AKS 群集相同的位置名称。 |
matchTags |
驱动程序在尝试查找合适的存储帐户时匹配标记。 |
true 或 false |
否 | false |
networkEndpointType |
为由驱动创建的存储帐户指定网络终结点类型。 如果指定了 privateEndpoint,则会为存储帐户创建专用终结点。 对于其他情况,默认会创建服务终结点。 |
"",privateEndpoint |
否 | "" |
protocol |
指定文件共享协议。 |
smb、nfs |
否 | smb |
requireInfraEncryption |
指定服务是否对驱动程序创建的存储帐户中的静态数据应用由平台托管密钥的二次加密层。 |
true 或 false |
否 | false |
resourceGroup |
指定Azure磁盘的资源组。 | 现有资源组名称 | 否 | 如果为空,驱动程序将使用与当前 AKS 群集相同的资源组名称。 |
selectRandomMatchingAccount |
确定是否随机选择匹配帐户。 默认情况下,驱动程序始终按字母顺序选择第一个匹配的帐户(注意:此驱动程序使用帐户搜索缓存,这会导致多个帐户之间的文件创建分布不均匀)。 |
true 或 false |
否 | false |
server |
指定Azure storage帐户服务器地址。 | 现有服务器地址,例如 accountname.privatelink.file.core.chinacloudapi.cn。 |
否 | 如果为空,驱动程序使用默认的 accountname.file.core.chinacloudapi.cn 或其他主权云帐户地址。 |
shareAccessTier |
文件共享的访问层 | General purpose v2 帐户可以在 TransactionOptimized (默认值)、Hot 和 Cool 之间进行选择。 仅适用于文件共享的高级存储帐户类型。 |
否 | 空白。 对不同的存储帐户类型使用默认设置。 |
shareName |
指定Azure文件共享名称。 | 现有或新的Azure文件共享名称。 | 否 | 如果为空,驱动程序将生成Azure文件共享名称。 |
shareNamePrefix |
指定Azure驱动程序创建的文件共享名称前缀。 | 共享名只能包含小写字母、数字、连字符,长度应少于 21 个字符。 | 否 | |
skuName |
Azure Files 存储帐户类型(别名:storageAccountType) |
Standard_LRS、、Standard_ZRS、Standard_GRSStandard_RAGRS、、Standard_RAGZRSPremium_LRS、Premium_ZRS、StandardV2_LRSStandardV2_ZRSStandardV2_GRS、StandardV2_GZRS、、 PremiumV2_LRSPremiumV2_ZRS |
否 | Standard_LRS 高级帐户类型的最小文件共享大小为 100 GB。 ZRS 帐户类型在有限区域内受支持。 NFS 文件共享仅支持高级帐户类型。 标准 V2 SKU 名称适用于 预配的 Azure 文件存储 v2 模型。 |
storageAccount |
指定Azure storage帐户名称。 | storageAccountName | 否 | 如果未提供特定的存储帐户名称,驱动程序将查找与同一资源组中的帐户设置匹配的合适存储帐户。 如果驱动程序找不到匹配的存储帐户,则将创建新的存储帐户。 但是,如果指定了存储帐户名,则存储帐户必须已存在。 |
storageEndpointSuffix |
指定 Azure 存储终结点后缀。 |
core.chinacloudapi.cn、core.chinacloudapi.cn 等 |
否 | 如果为空,驱动程序会根据云环境使用默认的存储终结点后缀。 例如,core.chinacloudapi.cn。 |
tags |
标签是在新的存储帐户中创建的。 | 标记格式:“foo=aaa,bar=bbb” | 否 | "" |
| --- | 以下参数仅适用于 SMB 协议 | --- | --- | --- |
subscriptionID |
指定创建Azure文件共享的Azure订阅 ID。 | Azure 订阅 ID | 否 | 如果不为空,则必须提供 resourceGroup。 |
storeAccountKey |
指定是否将存储帐户密钥存储为 Kubernetes 机密。 |
true 或 false false 表示驱动程序使用 kubelet 标识获取帐户密钥。 |
否 | true |
secretName |
指定用于存储帐户密钥的机密名称。 | 否 | ||
secretNamespace |
指定用于存储帐户密钥的机密的命名空间。 注意: 如果未指定 secretNamespace,则会在 Pod 所在的同一命名空间中创建机密。 |
default、kube-system 等。 |
否 | PVC 命名空间,例如 csi.storage.k8s.io/pvc/namespace |
useDataPlaneAPI |
指定是否使用 数据平面 API 来创建、删除或调整文件共享的大小,这可以解决 SRP API 的限制问题,因为数据平面 API 几乎没有限制。不过,当存储账户上有防火墙或 Vnet 设置时,该方法可能会失败。 |
true 或 false |
否 | false |
| --- | 以下参数仅适用于 NFS 协议 | --- | --- | --- |
mountPermissions |
挂载的文件夹权限。 默认值为 0777。 如果设置为 0,则驱动程序在装载后不会执行 chmod。 |
0777 |
否 | |
rootSquashType |
指定共享上的根压缩行为。 默认值为 NoRootSquash |
AllSquash、NoRootSquash、RootSquash |
否 | |
| --- | 以下参数仅适用于 VNet 设置(例如:NFS、专用终结点) | --- | --- | --- |
fsGroupChangePolicy |
指示驱动程序如何更改卷的所有权。 Pod securityContext.fsGroupChangePolicy 将被忽略。 |
OnRootMismatch(默认)、Always、None |
否 | 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 访问模式。
创建一个名为
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_LRSSKU,则storage的最小值必须为100Gi。使用
kubectl apply命令创建 PVC。kubectl apply -f azure-file-pvc.yaml使用
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:”。
创建一个名为
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使用
kubectl apply命令创建 pod。kubectl apply -f azure-pvc-files.yaml使用以下命令
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 及更高版本,fileMode 和 dirMode 的默认值为 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 共享挂载选项
以下存储类示例中提供了 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 共享挂载选项
以下存储类示例中提供了建议的 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 驱动程序支持创建持久卷的快照和基础文件共享。
使用以下命令创建卷快照类:
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 创建
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使用
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 文件共享。
使用
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使用
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使用
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使用
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。
创建一个名为
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的文件,并在其中粘贴以下清单。 请确保storageClassName的名称与您的现有存储类匹配。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
将 Azure 文件与 Windows 容器配合使用
Azure Files CSI 驱动程序还支持 Windows 节点和容器。 若要使用 Windows 容器,请遵循 Windows 容器快速入门教程添加 Windows 节点池。 拥有 Windows 节点池后,可以使用内置存储类,例如 azurefile-csi 或创建自定义存储类。 本部分中 基于 Windows 的有状态集 每隔一秒将时间戳保存到一个文件中 data.txt ,该文件使用 Azure 文件 CSI 驱动程序装载到 Azure 文件共享。
使用以下命令
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使用以下命令
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 性能优化。
rsize和wsize选项设置NFS操作的最大传输大小。 如果rsize或wsize在装载时未指定,则客户端和服务器将协商两者所支持的最大大小。 目前,Azure 文件和新式 Linux 分发版都支持大小为 1,048,576 字节(1 MiB)的读取和写入大小。
最佳性能基于高效的客户端-服务器通信。 增加或减少 装载 读取和写入选项大小值可以提高 NFS 性能。 对于客户端和服务器之间传输的读/写数据包,针对 NFS 版本 2 的默认大小为 8 KB,针对 NFS 版本 3 和 4 的默认大小为 32 KB。 这些默认值可能太大或太小。 通过减少rsize和wsize,并为每个 NFS 读取回复和写入请求发送较小的数据包,可以在拥堵的网络中提高 NFS 性能。 但是,这会增加跨网络发送数据所需的数据包数量,从而增加客户端和服务器上的网络总流量和 CPU 使用率。
请务必进行测试,以便找到能够保持高效数据包传输、不减少吞吐量且不增加延迟的rsize和wsize。
以下示例清单将存储类中 mountOptions 部分的节配置为最大 rsize 和 wsize 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 文件共享存储类
注释
vers、minorversion 和 sec 由 Azure 文件 CSI 驱动程序进行配置。 不支持在清单中为这些属性指定值。
创建一个名为
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编辑并保存文件后,使用
kubectl apply命令创建存储类。kubectl apply -f nfs-sc.yaml输出应类似于以下示例输出:
storageclass.storage.k8s.io/azurefile-csi-nfs created
使用 NFS 支持的文件共享创建有状态集
创建一个名为
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使用
kubectl apply命令创建有状态集。kubectl apply -f nfs-ss.yaml输出应类似于以下示例输出:
statefulset.apps/statefulset-azurefile created使用以下
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 节点。
传输中的加密(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 |
指定文件共享协议。 |
smb、nfs |
否 | smb |
volumeAttributes.server |
指定Azure storage帐户服务器地址 | 现有服务器地址,例如 accountname.privatelink.file.core.chinacloudapi.cn。 |
否 | 如果为空,驱动程序使用默认的 accountname.file.core.chinacloudapi.cn 或其他主权云帐户地址。 |
| --- | 以下参数仅适用于 SMB 协议 | --- | --- | --- |
volumeAttributes.secretName |
指定用于存储帐户名称和密钥的机密名称。 | 否 | ||
volumeAttributes.secretNamespace |
指定机密命名空间。 |
default、kube-system 等。 |
否 | PVC 命名空间(csi.storage.k8s.io/pvc/namespace) |
nodeStageSecretRef.name |
指定用于存储帐户名称和密钥的机密名称。 | 现有机密名称。 | 否 | 如果为空,驱动程序则使用 kubelet 标识获取帐户密钥。 |
nodeStageSecretRef.namespace |
指定机密命名空间。 | Kubernetes 命名空间 | 否 | |
| --- | 以下参数仅适用于 NFS 协议 | --- | --- | --- |
volumeAttributes.fsGroupChangePolicy |
指示驱动程序如何更改卷的所有权。 Pod securityContext.fsGroupChangePolicy 将被忽略。 |
OnRootMismatch(默认)、Always、None |
否 | OnRootMismatch |
volumeAttributes.mountPermissions |
指定装载的文件夹权限。 默认值为 0777 |
否 |
创建 Azure 文件共享
必须先创建一个 Azure 存储帐户和 Azure Files 文件共享,然后才能将 Azure Files 文件共享用作 Kubernetes 卷。
使用命令
az aks show通过参数--query nodeResourceGroup获取 AKS 群集的节点资源组的名称。az aks show --resource-group myResourceGroup --name myAKSCluster --query nodeResourceGroup -o tsv该命令的输出类似于以下示例:
MC_myResourceGroup_myAKSCluster_chinanorth3使用
az storage account create命令和--sku参数创建存储帐户。 以下命令使用Standard_LRSSKU 创建存储帐户。 请务必替换以下占位符:-
myAKSStorageAccount,其中包含storage帐户的名称 -
nodeResourceGroupName替换为 AKS 群集节点所在的资源组名称 -
location替换为创建资源的区域名称。 它应与 AKS 群集节点为同一区域。
az storage account create --name myAKSStorageAccount --resource-group nodeResourceGroupName --location location --sku Standard_LRS-
使用 [
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 存储中的数据。
使用
az storage share create命令创建文件共享。 请确保将shareName替换为自己的共享名称。az storage share create --name shareName --connection-string $AZURE_STORAGE_CONNECTION_STRING使用 [
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)使用以下命令显示存储帐户的名称和密钥。 记下用于在下一步中创建 Kubernetes 机密的存储帐户密钥。
echo Storage account key: $STORAGE_KEY
创建 Kubernetes 机密
Kubernetes 需要凭据才能访问在上一步中创建的文件共享。 这些凭据存储在 Kubernetes 机密中,创建 Kubernetes Pod 时将引用它。
使用
kubectl create secret命令创建机密。 以下示例创建一个名为 azure-secret 的密钥,并提供上一步骤中的 azurestorageaccountname 和 azurestorageaccountkey。 若要使用现有Azure storage帐户,请提供帐户名称和密钥。kubectl create secret generic azure-secret --from-literal=azurestorageaccountname=myAKSStorageAccount --from-literal=azurestorageaccountkey=$STORAGE_KEY
将文件共享装载为持久卷
新建名为
azurefiles-pv.yaml的文件,并将以下内容复制到其中。 在csi下,更新resourceGroup、volumeHandle和shareName。 对于装载选项,fileMode和dirMode的默认值为 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使用
kubectl create命令创建 PV。kubectl create -f azurefiles-pv.yaml创建名为 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使用
kubectl apply命令创建 PVC。kubectl apply -f azurefiles-mount-options-pvc.yaml使用
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更新容器规格以引用 YAML 文件中的 PVC 和 Pod。 例如:
... volumes: - name: azure persistentVolumeClaim: claimName: azurefile无法就地更新 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 中,请在容器规范中配置卷。
新建名为
azure-files-pod.yaml的文件,并将以下内容复制到其中。 如果更改了文件共享名称或机密名称,请更新shareName和secretName。 还可以更新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使用
kubectl apply命令创建 pod。kubectl apply -f azure-files-pod.yaml使用以下命令
kubectl describe查看 Pod 的状态:kubectl describe pod mypod