你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

在 Linux 客户端上装载 SMB Azure 文件共享

可以使用 SMB 内核客户端在 Linux 分发版中装载 Azure 文件共享。

适用于

文件共享类型 SMB NFS
标准文件共享 (GPv2)、LRS/ZRS 是 否
标准文件共享 (GPv2)、GRS/GZRS 是 否
高级文件共享 (FileStorage)、LRS/ZRS 是 否

协议

在 Linux 上装载 Azure 文件共享的建议方法是使用 SMB 3.1.1。 默认情况下,Azure 文件存储要求进行传输中加密,而只有 SMB 3.0+ 支持传输中加密。 Azure 文件存储也支持 SMB 2.1(后者不支持传输中加密),但出于安全原因,你无法使用 SMB 2.1 从另一 Azure 区域或本地装载 Azure 文件共享。 除非应用程序专门需要用到 SMB 2.1,否则请使用 SMB 3.1.1。 SMB 2.1 支持已添加到 Linux 内核版本 3.7,因此,如果在 3.7 之后的版本使用 Linux 内核版本,则应支持 SMB 2.1。

分发 SMB 3.1.1(推荐) SMB 3.0
Linux 内核版本
  • 基本 3.1.1 支持:4.17
  • 默认装载:5.0
  • AES-128-GCM 加密:5.3
  • AES-256-GCM 加密:5.10
  • 基本 3.0 支持:3.12
  • AES-128-CCM 加密:4.11
Ubuntu AES-128-GCM 加密:18.04.5 LTS+ AES-128-CCM 加密:16.04.4 LTS+
Red Hat Enterprise Linux (RHEL)
  • 基本:8.0+
  • 默认装载:8.2+
  • AES-128-GCM 加密:8.2+
7.5+
Debian 基本:10+ AES-128-CCM 加密:10+
SUSE Linux Enterprise Server AES-128-GCM 加密:15 SP2+ AES-128-CCM 加密:12 SP2+

如果上表中未列出你的 Linux 发行版,可以使用 uname 命令检查 Linux 内核版本:

uname -r

先决条件

  • 确保已安装 cifs-utils 包。在所选的 Linux 发行版上使用包管理器安装最新版 cifs-utils 包。

在 Ubuntu 和 Debian 上,使用 apt 包管理器:

sudo apt update
sudo apt install cifs-utils

在其他分发版上,请使用相应的包管理器,或从源编译

  • 最新版本的 Azure 命令行接口 (CLI)。 若要详细了解如何安装 Azure CLI,请参阅安装 Azure CLI 并选择操作系统。 如果你想要在 PowerShell 6+ 中使用 Azure PowerShell 模块,也可使用;不过,本文中的说明适用于 Azure CLI。

  • 确保已打开端口 445:SMB 通过 TCP 端口 445 通信 - 请确保防火墙或 ISP 未阻止 TCP 端口 445 与客户端计算机通信。 替换 <your-resource-group><your-storage-account>,然后运行以下脚本:

    RESOURCE_GROUP_NAME="<your-resource-group>"
    STORAGE_ACCOUNT_NAME="<your-storage-account>"
    
    # This command assumes you have logged in with az login
    HTTP_ENDPOINT=$(az storage account show \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $STORAGE_ACCOUNT_NAME \
        --query "primaryEndpoints.file" --output tsv | tr -d '"')
    SMBPATH=$(echo $HTTP_ENDPOINT | cut -c7-${#HTTP_ENDPOINT})
    FILE_HOST=$(echo $SMBPATH | tr -d "/")
    
    nc -zvw3 $FILE_HOST 445
    

    如果连接成功,应会看到如下所示的输出:

    Connection to <your-storage-account> 445 port [tcp/microsoft-ds] succeeded!
    

    如果无法在企业网络中打开端口 445,或者 ISP 阻止此类操作,可以使用 VPN 连接或 ExpressRoute 来解决端口 445 的相关问题。 有关详细信息,请参阅直接访问 Azure 文件共享时的网络注意事项

权限

本文中的所有装载脚本都将使用默认的 0755 Linux 文件和文件夹权限装载文件共享。 这意味着为文件/目录所有者读取、写入和执行、为所有者组中的用户读取和执行,以及为其他用户读取和执行。 根据组织的安全策略,可能需要在装载选项中设置备用 uid/giddir_modefile_mode 权限。

若要详细了解如何设置权限,请参阅 Unix 符号表示法。 有关装载选项的列表,请参阅装载选项

使用 mount 按需装载 Azure 文件共享

在 Linux OS 上装载文件共享时,远程文件共享将在本地文件系统中以文件夹的形式表示。 可将文件共享装载到系统上的任何位置。 以下示例将文件共享装载到 /media 路径下。 可以通过修改 $MNT_ROOT 变量将此路径更改为所需的首选路径。

请将 <resource-group-name><storage-account-name><file-share-name> 替换为适合你的环境的信息。

RESOURCE_GROUP_NAME="<resource-group-name>"
STORAGE_ACCOUNT_NAME="<storage-account-name>"
FILE_SHARE_NAME="<file-share-name>"

MNT_ROOT="/media"
MNT_PATH="$MNT_ROOT/$STORAGE_ACCOUNT_NAME/$FILE_SHARE_NAME"

sudo mkdir -p $MNT_PATH

接下来,运行以下脚本来初始化凭据文件。

# Create a folder to store the credentials for this storage account and
# any other that you might set up.
CREDENTIAL_ROOT="/etc/smbcredentials"
sudo mkdir -p "/etc/smbcredentials"

# Get the storage account key for the indicated storage account.
# You must be logged in with az login and your user identity must have
# permissions to list the storage account keys for this command to work.
STORAGE_ACCOUNT_KEY=$(az storage account keys list \
    --resource-group $RESOURCE_GROUP_NAME \
    --account-name $STORAGE_ACCOUNT_NAME \
    --query "[0].value" --output tsv | tr -d '"')

# Create the credential file for this individual storage account
SMB_CREDENTIAL_FILE="$CREDENTIAL_ROOT/$STORAGE_ACCOUNT_NAME.cred"
if [ ! -f $SMB_CREDENTIAL_FILE ]; then
    echo "username=$STORAGE_ACCOUNT_NAME" | sudo tee $SMB_CREDENTIAL_FILE > /dev/null
    echo "password=$STORAGE_ACCOUNT_KEY" | sudo tee -a $SMB_CREDENTIAL_FILE > /dev/null
else
    echo "The credential file $SMB_CREDENTIAL_FILE already exists, and was not modified."
fi

# Change permissions on the credential file so only root can read or modify the password file.
sudo chmod 600 $SMB_CREDENTIAL_FILE

现在,可以使用凭据文件通过 mount 命令装载文件共享。 在以下示例中,使用存储帐户文件终结点的完全限定域名填充了 $SMB_PATH 命令。 有关 SMB 装载选项的列表,请参阅装载选项

注意

从 Linux 内核版本 5.0 开始,SMB 3.1.1 是默认的协商协议。 如果使用的 Linux 内核版本低于 5.0,请在装载选项列表中指定 vers=3.1.1

# This command assumes you have logged in with az login
HTTP_ENDPOINT=$(az storage account show \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $STORAGE_ACCOUNT_NAME \
    --query "primaryEndpoints.file" --output tsv | tr -d '"')
SMB_PATH=$(echo $HTTP_ENDPOINT | cut -c7-${#HTTP_ENDPOINT})$FILE_SHARE_NAME

STORAGE_ACCOUNT_KEY=$(az storage account keys list \
    --resource-group $RESOURCE_GROUP_NAME \
    --account-name $STORAGE_ACCOUNT_NAME \
    --query "[0].value" --output tsv | tr -d '"')

sudo mount -t cifs $SMB_PATH $MNT_PATH -o credentials=$SMB_CREDENTIAL_FILE,serverino,nosharesock,actimeo=30,mfsymlinks

如果需要,还可将同一个 Azure 文件共享装载到多个装入点。

使用完 Azure 文件共享后,请使用 sudo umount $mntPath 卸载共享。

自动装载文件共享

在 Linux OS 上装载文件共享时,远程文件共享将在本地文件系统中以文件夹的形式表示。 可将文件共享装载到系统上的任何位置。 以下示例将文件共享装载到 /media 路径下。 可以通过修改 $MNT_ROOT 变量将此路径更改为所需的首选路径。

MNT_ROOT="/media"
sudo mkdir -p $MNT_ROOT

若要在 Linux 上装载 Azure 文件共享,请使用存储帐户名称作为文件共享的用户名,并使用存储帐户密钥作为密码。 因为存储帐户凭据可随时更改,所以应将存储帐户的凭据与装载配置分开存储。

以下示例演示如何创建一个用于存储凭据的文件。 请记得将 <resource-group-name><storage-account-name> 替换为适合你的环境的信息。

RESOURCE_GROUP_NAME="<resource-group-name>"
STORAGE_ACCOUNT_NAME="<storage-account-name>"

# Create a folder to store the credentials for this storage account and
# any other that you might set up.
CREDENTIAL_ROOT="/etc/smbcredentials"
sudo mkdir -p "/etc/smbcredentials"

# Get the storage account key for the indicated storage account.
# You must be logged in with az login and your user identity must have
# permissions to list the storage account keys for this command to work.
STORAGE_ACCOUNT_KEY=$(az storage account keys list \
    --resource-group $RESOURCE_GROUP_NAME \
    --account-name $STORAGE_ACCOUNT_NAME \
    --query "[0].value" --output tsv | tr -d '"')

# Create the credential file for this individual storage account
SMB_CREDENTIAL_FILE="$CREDENTIAL_ROOT/$STORAGE_ACCOUNT_NAME.cred"
if [ ! -f $SMB_CREDENTIAL_FILE ]; then
    echo "username=$STORAGE_ACCOUNT_NAME" | sudo tee $SMB_CREDENTIAL_FILE > /dev/null
    echo "password=$STORAGE_ACCOUNT_KEY" | sudo tee -a $SMB_CREDENTIAL_FILE > /dev/null
else
    echo "The credential file $SMB_CREDENTIAL_FILE already exists, and was not modified."
fi

# Change permissions on the credential file so only root can read or modify the password file.
sudo chmod 600 $SMB_CREDENTIAL_FILE

若要自动装载文件共享,可以选择通过 /etc/fstab 实用工具使用静态装载,或者通过 autofs 实用工具使用动态装载。

通过 /etc/fstab 进行静态装载

沿用前面所述的环境,在装载文件夹下为存储帐户/文件共享创建一个文件夹。 请将 <file-share-name> 替换为你的 Azure 文件共享的相应名称。

FILE_SHARE_NAME="<file-share-name>"

MNT_PATH="$MNT_ROOT/$STORAGE_ACCOUNT_NAME/$FILE_SHARE_NAME"
sudo mkdir -p $MNT_PATH

最后,在 /etc/fstab 文件中为 Azure 文件共享创建一条记录。 在以下命令中,使用了默认的 0755 Linux 文件和文件夹权限,这表示所有者拥有读取、写入和执行权限(基于文件/目录 Linux 所有者),所有者组中的用户拥有读取和执行权限,系统中的其他用户拥有读取和执行权限。 对于装载,可以根据需要设置备用的 uidgid 或者 dir_modefile_mode 权限。 若要详细了解如何设置权限,请参阅 UNIX 数值表示法。 有关 SMB 装载选项的列表,请参阅装载选项

提示

如果希望运行 .NET Core 应用程序的 Docker 容器能够写入 Azure 文件共享,请在 SMB 装载选项中包含 nobrl,以避免将字节范围锁定请求发送到服务器。

HTTP_ENDPOINT=$(az storage account show \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $STORAGE_ACCOUNT_NAME \
    --query "primaryEndpoints.file" --output tsv | tr -d '"')
SMB_PATH=$(echo $HTTP_ENDPOINT | cut -c7-${#HTTP_ENDPOINT})$FILE_SHARE_NAME

if [ -z "$(grep $SMB_PATH\ $MNT_PATH /etc/fstab)" ]; then
    echo "$SMB_PATH $MNT_PATH cifs _netdev,nofail,credentials=$SMB_CREDENTIAL_FILE,serverino,nosharesock,actimeo=30,mfsymlinks" | sudo tee -a /etc/fstab > /dev/null
else
    echo "/etc/fstab was not modified to avoid conflicting entries as this Azure file share was already present. You might want to double check /etc/fstab to ensure the configuration is as desired."
fi

sudo mount -a

注意

从 Linux 内核版本 5.0 开始,SMB 3.1.1 是默认的协商协议。 可以使用 vers 装载选项指定备用协议版本(协议版本为 3.1.13.02.1)。

通过 autofs 进行动态装载

若要使用 autofs 实用工具动态装载文件共享,请在你选择的 Linux 发行版上使用包管理器安装该实用工具。

在 Ubuntu 和 Debian 发行版上,使用 apt 包管理器:

sudo apt update
sudo apt install autofs

接下来,更新 autofs 配置文件。 有关 SMB 装载选项的列表,请参阅装载选项

FILE_SHARE_NAME="<file-share-name>"

HTTP_ENDPOINT=$(az storage account show \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $STORAGE_ACCOUNT_NAME \
    --query "primaryEndpoints.file" --output tsv | tr -d '"')
SMB_PATH=$(echo $HTTP_ENDPOINT | cut -c7-$(expr length $HTTP_ENDPOINT))$FILE_SHARE_NAME

echo "$FILE_SHARE_NAME -fstype=cifs,credentials=$SMB_CREDENTIAL_FILE,serverino,nosharesock,actimeo=30,mfsymlinks :$SMB_PATH" > /etc/auto.fileshares

echo "/fileshares /etc/auto.fileshares --timeout=60" > /etc/auto.master

最后一步是重启 autofs 服务。

sudo systemctl restart autofs

装载选项

在 Linux 上装载 SMB Azure 文件共享时,可以使用以下装载选项。

装载选项 建议的值 描述
username= 存储帐户名称 进行 NTLMv2 身份验证时是必需的。
password= 存储帐户主密钥 进行 NTLMv2 身份验证时是必需的。
password2= 存储帐户辅助密钥 建议在需要进行无停机密钥轮换时使用。
mfsymlinks 不适用 推荐。 强制此装载支持符号链接,允许 git 之类的应用程序使用符号链接克隆存储库。
actimeo= 30-60 推荐。 CIFS 客户端在向服务器请求属性信息之前缓存文件或目录的属性的时间(以秒为单位)。 使用小于 30 秒的值可能会导致性能下降,因为文件和目录的属性缓存很快就会过期。 建议将 actimeo 设置为 30 到 60 秒。
nosharesock 不适用 可选。 强制客户端始终与服务器建立新连接,即使它有一个到 SMB 装载的现有连接。 这可以增强性能,因为每个装入点都会使用不同的 TCP 套接字。 在某些情况下,nosharesock 可能会降低性能,因为从同一客户端的两个装载打开时,不会缓存同一文件。
max_channels= 4 建议在使用 SMB 多通道时使用。 指定文件共享的最大通道数(网络连接数)。 如果使用的是 SMB 多通道并且通道数超过 4 个,则会导致性能不佳。
remount 不适用 重新装载文件共享并更改装载选项(如果已指定)。 在你想要指定备用密码来修复进行原始装载后过期的密码时与 password2 选项配合使用。
nobrl 不适用 建议在需要咨询锁的单客户端场景中使用。 Azure 文件存储不支持咨询锁,此设置会阻止向服务器发送字节范围锁请求。
snapshot= time 装载文件共享的特定快照。 时间必须是一个用于标识请求的快照的正整数(以 1601 年 1 月 1 日以来经历的以 100 纳秒为单位的单位数表示,也可以 GMT 格式指定,例如 @GMT-2024.03.27-20.52.19)。
closetimeo= 5 配置以秒为单位的延迟关闭超时(句柄缓存),或通过将它设置为 0 来禁用它。 默认值为 5 秒。
nostrictsync 不适用 不要要求服务器在 fsync() 上刷新。 某些服务器默认执行非缓冲写入,在这种情况下刷新是多余的。 此选项可以提高其中的客户端在执行大量小型写入 + fsync 组合操作且网络延迟远高于服务器延迟的工作负荷的性能。
multiuser 不适用 在访问服务器时将用户访问映射到单个凭据。 默认情况下,CIFS 装载在访问共享时仅使用单组用户凭据(装载凭据)。 使用此选项,每当新用户访问装载时,客户端都会改为通过用户的凭据与服务器创建新的会话。 该用户的进一步的访问也将使用这些凭据。 由于内核无法提示用户输入密码,因此多用户装载仅限于使用不需要密码的 sec= 选项的装载。
cifsacl 不适用 此选项用于在 CIFS/NTFS ACL 与 Linux 权限位之间来回映射、在 SID 与 UID 和 GID 之间来回映射,以及获取和设置安全描述符。 仅支持用于 NTLMv2 身份验证。
idsfromsid,modefromsid 不适用 建议在客户端需要进行客户端强制授权时使用。 启用 Unix 样式权限。 仅当 UID/GID 在所有客户端中统一时才有效。 仅支持用于 NTLMv2 身份验证。
sec= krb5 进行 Kerberos 身份验证所需。 若要启用 Kerberos 安全模式,请设置 sec=krb5。 使用此选项时,必须省略用户名和密码。 Linux 客户端必须已加入域。 请参阅通过 SMB 为 Linux 客户端启用 Active Directory 身份验证
uid= 0 可选。 设置一个 UID,该 UID 在服务器不提供所有权信息时会拥有已装载文件系统上的所有文件或目录。 可以将其指定为用户名或数字 UID。 在未指定的情况下,默认值为 0。
gid= 0 可选。 设置一个 GID,该 GID 在服务器不提供所有权信息时会拥有已装载文件系统上的所有文件或目录。 可以将其指定为组名或数字 GID。 在未指定的情况下,默认值为 0。
file_mode= 不适用 可选。 如果服务器不支持 CIFS Unix 扩展,则会替代默认文件模式。
dir_mode= 不适用 可选。 如果服务器不支持 CIFS Unix 扩展,则会替代目录的默认模式。
handletimeout= 不适用 可选。 服务器应在故障转移后保留文件句柄以等待客户端重新连接的时间(以毫秒为单位)。

后续步骤

若要详细了解如何通过 Linux 使用 SMB Azure 文件共享,请参阅: