适用于: ✔️ SMB Azure 文件共享
本文列出了在 Linux 客户端中使用 SMB Azure文件共享时可能发生的常见问题。 并提供了这些问题的可能原因和解决方法。
重要
本文仅适用于 SMB 共享。 有关 NFS 共享的详细信息,请参阅排查 NFS Azure 文件共享问题。
运行诊断程序
诊断工具可帮助确保客户端具备正确的先决条件,并收集有关可能难以重现的字段问题的调试信息。
使用 AzFileDiagnostics
使用 AzFileDiagnostics 自动执行症状检测并确保 Linux 客户端具有正确的先决条件。 它有助于设置环境以获得最佳性能。
使用 Always-On 诊断工具
还可以使用 Always-On 诊断(AOD)工具来收集 SMB 和 NFSv4 Linux 客户端上的日志。 守护程序作为系统服务在后台运行,可配置为检测各种源(例如 dmesg 日志、调试数据、错误指标和延迟指标)中的异常。 它可以从 tcpdump、nfsstat、mountstats 和其他源捕获数据,以及系统的 CPU 和内存使用情况。
Always-On 诊断工具目前与运行 SUSE Linux Enterprise Server 15(SLES 15)和 Red Hat Enterprise Linux 8(RHEL 8)的系统兼容。 按照与操作系统对应的安装步骤操作:
在 SLES 15 中,按照以下说明安装 Always-On 诊断工具:
添加Microsoft存储库。 可能需要将Microsoft存储库密钥添加到受信任的密钥列表中。
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc sudo zypper addrepo --check --refresh --name 'Microsoft' https://packages.microsoft.com/sles/15/prod microsoft刷新存储库。
sudo zypper refresh检查是否已添加存储库,并且
aod包可用于安装。zypper search aod安装此包。
sudo zypper install aod
复制文件时会丢失时间戳
在 Linux/Unix 平台上,如果不同的用户拥有文件 1 和文件 2,命令 cp -p 将失败。
原因
COPYFILE 中的强制标志 f 会导致在 Unix 上执行 cp -p -f 。 此命令也无法保留不归你拥有的文件的时间戳。
解决方法
使用存储帐户用户复制文件:
str_acc_name=[storage account name]sudo useradd $str_acc_namesudo passwd $str_acc_namesu $str_acc_namecp -p filename.txt /share
ls:无法访问 '<path>':输入/输出错误
尝试使用 ls 命令列出 Azure 文件共享中的文件时,命令在列出文件时挂起。 您会收到以下错误:
ls: 无法访问 '<path>': 输入/输出错误
解决方案
将 Linux 内核升级到包含此问题修补程序的版本。 使用以下版本之一:
- 4.4.87+
- 4.9.48+
- 4.12.11+
- 4.13 或更高版本的任何版本
无法创建符号链接 - ln: 未能创建符号链接 't': 操作不受支持
原因
默认情况下,使用 SMB 在 Linux 上装载 Azure 文件共享不会启用符号链接的支持。 你可能会看到如下错误:
sudo ln -s linked -n t
ln: failed to create symbolic link 't': Operation not supported
解决方案
Linux SMB 客户端不支持通过 SSMB 2 或 3 协议创建 Windows 样式符号链接。 Linux 客户端目前支持使用称作 Minshall+French 符号链接的另一种样式的符号链接来执行创建和跟踪操作。 需要符号链接的客户可以使用 mfsymlinks 装载选项。 使用 mfsymlinks ,因为它也是 Mac 使用的格式。
若要使用符号链接,请将以下选项添加到 SMB 装载命令的末尾:
,mfsymlinks
因此,该命令如下所示:
sudo mount -t cifs //<storage-account-name>.file.core.windows.net/<share-name> <mount-point> -o vers=<smb-version>,username=<storage-account-name>,password=<storage-account-key>,dir_mode=0777,file_mode=0777,serverino,mfsymlinks
然后,可以按照 wiki 上的建议创建符号链接。
无法访问文件夹或文件
装载在 Linux 上时,无法从 Azure 文件共享访问文件夹或文件。 访问共享时,像 du 和 ls 这样的命令以及第三方应用程序可能会失败,并出现“无此类文件或目录”错误。
原因 1
文件夹或文件的名称包含由上传它们的系统以不同方式编码的字符。 例如,从 macOS 客户端上传的文件可能包含 0xF028 或 0xF029 字符,而不是 0x20(空格)或 0x2E(点号)。
解决方案 1
在 Linux 上装载共享时使用 mapchars 此选项。
而不是:
sudo mount -t cifs $smbPath $mntPath -o vers=3.0,username=$storageAccountName,password=$storageAccountKey,serverino
使用:
sudo mount -t cifs $smbPath $mntPath -o vers=3.0,username=$storageAccountName,password=$storageAccountKey,serverino,mapchars
原因二
当您删除某个文件但其句柄仍处于打开状态时,SMB 服务器会保留一个僵尸文件,直到该文件的最后一个句柄被关闭。 对此僵尸文件进行操作的任何尝试都可能导致 Linux 上出现“没有这样的文件或目录”错误。
解决方案 2
如有必要,请从最新备份还原已删除的文件。
Azure 存储帐户实时迁移的 DNS 问题
装载的文件系统上的文件 I/O 开始出现“主机故障”或“权限被拒绝”错误。 客户端上的 Linux dmesg 日志将显示重复的错误,例如:
Status code returned 0xc000006d STATUS_LOGON_FAILURE
cifs_setup_session: 2 callbacks suppressed
CIFS VFS: \\contoso.file.core.windows.net Send error in SessSetup = -13
你还会看到,服务器 FQDN 现在解析到的 IP 地址与其当前所连接的 IP 地址不同。 在服务器 IP 地址可以更改(例如帐户迁移)的任何方案中,都可能出现此问题。 另一个已知方案是存储帐户故障转移,因为 DNS 映射可能会更改。
原因
出于容量负载均衡的目的,系统有时会实时将存储帐户从一个存储群集迁移到另一个。 帐户迁移将更新 DNS 映射,使其指向目标群集,这会将源群集Azure 文件存储流量重定向到目标群集。 此更新阻止来自该帐户的源群集的所有流量。 SMB 客户端应会获取 DNS 更新,并将后续流量重定向到目标群集。 但是,由于 Linux SMB 内核客户端中的 bug,此重定向不会生效。 因此,数据流量会继续转到源群集,这会在迁移后停止为此帐户提供服务。
解决方法
通过重新启动客户端 OS 可以缓解此问题,但如果不将客户端 OS 升级到具有帐户迁移支持的 Linux 发行版,则可能会再次遇到此问题。
虽然卸载和重新装载共享似乎暂时解决了该问题,但这不是永久的解决方案。 当客户端重新连接到服务器时,可能会再次出现问题。 出现临时缓解是因为新的装载操作会绕过 SMB 内核缓存并解析用户空间中的 DNS 地址。 但是,内核 DNS 缓存在任何网络断开连接恢复期间都使用,这可能会导致问题再次出现。 即使在存储帐户迁移之外,此行为也会持续存在。
若要更好地解决此问题,请清除内核 DNS 解析程序缓存:
运行以下命令显示内核
dns_resolver模块的状态:grep '.dns_resolver' /proc/keys应会看到类似于以下示例的命令输出:
132b6bbf I------ 1 perm 1f030000 0 0 keyring .dns_resolver: 1运行以下命令清除内核 DNS 解析程序缓存:
sudo keyctl clear $((16#$(grep '.dns_resolver' /proc/keys | cut -f1 -d\ ) ))再次显示内核
dns_resolver模块的状态:grep '.dns_resolver' /proc/keys应会看到类似于以下示例的命令输出,指示缓存现在为空:
132b6bbf I------ 1 perm 1f030000 0 0 keyring .dns_resolver: empty卸载并重新挂载共享以缓解此问题。
备注
在某些较旧的 Linux 发行版中,缓解步骤可能不起作用。 在这种情况下,重新启动客户端 OS 会暂时解决问题。 对于永久修复,请将专用终结点添加到存储帐户,并使用专用链接连接到文件共享。
解决方案
要进行永久修复,请将客户端 OS 升级到具有帐户迁移支持的 Linux 发行版。 针对 Linux SMB 内核客户端的几项修复已提交至 Linux 主线内核。 以下发行版包含这些修复:
- Ubuntu:20.04、22.04、24.04 和 AKS 22.04(修补程序已在内核版本 5.15.0-1068 中推出)
- RHEL:8.6+
- SLES:15SP2、15SP3、15SP4 和 15SP5
- Azure Linux:2.0(在内核版本 5.15.159.1 中推出修补程序)和 3.0
一些发行版回移植这些修补程序。 检查你正在使用的发行版版本中是否存在以下修补程序:
启用 FIPS 时无法装载 SMB 文件共享
在 Linux VM 中启用 联邦信息处理标准(FIPS) 时,无法装载 SMB 文件共享。 客户端上的 Linux dmesg 日志显示如下错误:
kernel: CIFS: VFS: Could not allocate crypto hmac(md5)
kernel: CIFS: VFS: Error -2 during NTLMSSP authentication
kernel: CIFS: VFS: \\contoso.file.core.windows.net Send error in SessSetup = -2
kernel: CIFS: VFS: cifs_mount failed w/return code = -2
重要
FIPS 是美国政府用来确保计算机系统安全性和完整性的一套标准。 当系统处于 FIPS 模式时,它遵循这些标准概述的特定加密要求。
原因
SMB 文件共享的客户端使用 NTLMSSP 身份验证,这需要 MD5 哈希算法。 但是,在 FIPS 模式下,MD5 算法受到限制,因为它不符合 FIPS。 MD5 是一个广泛使用的哈希函数,用于生成 128 位哈希值。 但是,出于加密目的,MD5 被视为不安全。
如何检查是否已启用 FIPS 模式
若要验证是否已在客户端上启用 FIPS 模式,请运行以下命令。 如果该值设置为 1,则启用 FIPS。
sudo cat /proc/sys/crypto/fips_enabled
解决方案
若要解决此问题,请为 SMB 文件共享启用 Kerberos 身份验证。 如果无意中启用了 FIPS,请参阅 option2 将其禁用。
选项 1:为 SMB 文件共享启用 Kerberos 身份验证
若要在启用了 FIPS 的 Linux VM 上装载 SMB 文件共享,请使用基于标识的身份验证。 有关详细信息,请参阅通过 SMB 为访问 Azure 文件存储的 Linux 客户端启用 Active Directory 身份验证。
在
/etc/sysctl.conf中,将crypto.fips_enabled的 sysctl 值更改为 0。修改
/etc/default/grub文件中的GRUB_CMDLINE_LINUX_DEFAULT,并删除参数fips=1。使用以下命令重新生成 grub2 配置文件:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg使用以下命令重新生成 initramfs 映像:
sudo dracut -fv重启 VM。
有关详细信息,请参阅 Linux 分发服务器提供的以下文档:
需要帮助?
如果仍需帮助,请联系支持人员,以快速解决问题。