AzureFile 排错

AzureFile 提供了基于 SMB 协议(也称 CIFS)托管文件共享服务。它支持 Windows 和 Linux 容器,并支持跨主机的共享,可用于多个 Pod 之间的共享存储。AzureFile 的缺点是性能较差AKS#223),并且不提供 Premium 存储。

推荐基于 StorageClass 来使用 AzureFile,即

  1. kind: StorageClass
  2. apiVersion: storage.k8s.io/v1
  3. metadata:
  4. name: azurefile
  5. provisioner: kubernetes.io/azure-file
  6. mountOptions:
  7. - dir_mode=0777
  8. - file_mode=0777
  9. - uid=1000
  10. - gid=1000
  11. parameters:
  12. skuName: Standard_LRS

使用 AzureFile 推荐的版本:

Kubernetes version Recommended version
1.12 1.12.6 或更高版本
1.13 1.13.4 或更高版本
1.14 1.14.0 或更高版本
>=1.15 >=1.15

访问权限

AzureFile 使用 mount.cifs 将其远端存储挂载到 Node 上,而fileModedirMode 控制了挂载后文件和目录的访问权限。不同的 Kubernetes 版本,fileModedirMode 的默认选项是不同的

Kubernetes 版本 fileMode和dirMode
v1.6.x, v1.7.x 0777
v1.8.0-v1.8.5 0700
v1.8.6 or above 0755
v1.9.0 0700
v1.9.1-v1.12.1 0755
>=v1.12.2 0777

按照默认的权限会导致非跟用户无法在目录中创建新的文件,解决方法为

  • v1.8.0-v1.8.5:设置容器以 root 用户运行,如设置 spec.securityContext.runAsUser: 0
  • v1.8.6 以及更新版本:在 AzureFile StorageClass 通过 mountOptions 设置默认权限,比如设置为 0777 的方法为
  1. kind: StorageClass
  2. apiVersion: storage.k8s.io/v1
  3. metadata:
  4. name: azurefile
  5. provisioner: kubernetes.io/azure-file
  6. mountOptions:
  7. - dir_mode=0777
  8. - file_mode=0777
  9. - uid=1000
  10. - gid=1000
  11. - mfsymlinks
  12. - nobrl
  13. - cache=none
  14. parameters:
  15. skuName: Standard_LRS

Windows Node 重启后无法访问 AzureFile

Windows Node 重启后,挂载 AzureFile 的 Pod 可以看到如下错误(#60624):

  1. Warning Failed 1m (x7 over 1m) kubelet, 77890k8s9010 Error: Error response from daemon: invalid bind mount spec "c:\\var\\lib\\kubelet\\pods\\07251c5c-1cfc-11e8-8f70-000d3afd4b43\\volumes\\kubernetes.io~azure-file\\pvc-fb6159f6-1cfb-11e8-8f70-000d3afd4b43:c:/mnt/azure": invalid volume specification: 'c:\var\lib\kubelet\pods\07251c5c-1cfc-11e8-8f70-000d3afd4b43\volumes\kubernetes.io~azure-file\pvc-fb6159f6-1cfb-11e8-8f70-000d3afd4b43:c:/mnt/azure': invalid mount config for type "bind": bind source path does not exist
  2. Normal SandboxChanged 1m (x8 over 1m) kubelet, 77890k8s9010 Pod sandbox changed, it will be killed and re-created.

临时性解决方法为删除并重新创建使用了 AzureFile 的 Pod。当 Pod 使用控制器(如 Deployment、StatefulSet等)时,删除 Pod 后控制器会自动创建一个新的 Pod。

该问题的修复 #60625 包含在 v1.10 中。

AzureFile ProvisioningFailed

Azure 文件共享的名字最大只允许 63 个字节,因而在集群名字较长的集群(Kubernetes v1.7.10 或者更老的集群)里面有可能会碰到 AzureFile 名字长度超限的情况,导致 AzureFile ProvisioningFailed:

  1. persistentvolume-controller Warning ProvisioningFailed Failed to provision volume with StorageClass "azurefile": failed to find a matching storage account

碰到该问题时可以通过升级集群解决,其修复 #48326 已经包含在 v1.7.11、v1.8 以及更新版本中。

在开启 RBAC 的集群中,由于 AzureFile 需要访问 Secret,而 kube-controller-manager 中并未为 AzureFile 自动授权,从而也会导致 ProvisioningFailed:

  1. Events:
  2. Type Reason Age From Message
  3. ---- ------ ---- ---- -------
  4. Warning ProvisioningFailed 8s persistentvolume-controller Failed to provision volume with StorageClass "azurefile": Couldn't create secret secrets is forbidden: User "system:serviceaccount:kube-syste
  5. m:persistent-volume-binder" cannot create secrets in the namespace "default"
  6. Warning ProvisioningFailed 8s persistentvolume-controller Failed to provision volume with StorageClass "azurefile": failed to find a matching storage account

解决方法是为 ServiceAccount persistent-volume-binder 授予 Secret 的访问权限:

  1. ---
  2. apiVersion: rbac.authorization.k8s.io/v1
  3. kind: ClusterRole
  4. metadata:
  5. name: system:azure-cloud-provider
  6. rules:
  7. - apiGroups: ['']
  8. resources: ['secrets']
  9. verbs: ['get','create']
  10. ---
  11. apiVersion: rbac.authorization.k8s.io/v1beta1
  12. kind: ClusterRoleBinding
  13. metadata:
  14. name: system:azure-cloud-provider
  15. roleRef:
  16. kind: ClusterRole
  17. apiGroup: rbac.authorization.k8s.io
  18. name: system:azure-cloud-provider
  19. subjects:
  20. - kind: ServiceAccount
  21. name: persistent-volume-binder
  22. namespace: kube-system

Azure German Cloud 无法使用 AzureFile

Azure German Cloud 仅在 v1.7.11+、v1.8+ 以及更新版本中支持(#48460),升级 Kubernetes 版本即可解决。

“could not change permissions” 错误

在 Azure Files 插件上运行 PostgreSQL 时,可能会看到类似于以下内容的错误:

  1. initdb: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted
  2. fixing permissions on existing directory /var/lib/postgresql/data

此错误是由使用 cifs/SMB 协议的 Azure 文件插件导致的。 使用 cifs/SMB 协议时,无法在装载后更改文件和目录权限。 若要解决此问题,请将子路径与 Azure 磁盘插件结合使用。

参考文档