Azure 免费服务写的很清楚:

当然,这文件存储挂载到别的主机上,流量费用肯定是另算的。

本期就来试一下用 SMB 将这免费的盘挂到 Linux 主机上。

先决条件

  • 一个有效的Azure国际版订阅,不是国内特供的世纪互联版
  • 还在免费期内。(要不然你就得自己花钱了)

创建存储账户(如果还没有的话)

搜索并打开存储账户,如果还没有就点击创建。(能来这里看的应该都是没有的吧)

资源组后来换到别的地方去了,所以这里手动打个补丁
  1. 选择这个存储账户属于哪个资源组。可以新建,也可以部署到已有的资源组,这个随意。
  2. 起一个名称。
  3. (重要)选择你的存储账户区域,这决定了你的云盘在哪个地方。如果你想挂载到你的 Azure 主机,务必要把它设置为和你的 Azure 主机一致的地域,防止微软收你跨数据中心数据传输的钱;如果挂载到非 Azure 主机,那就尽量选靠近的地方。因为我要挂载到的 Azure 主机在新加坡(东南亚),所以我的存储账户也选了新加坡。
  4. (重要)冗余:选择 LRS。免费的只是 LRS,默认的 GRS 是要收钱的。

然后无脑下一步并创建就行了。值得注意的是,“网络”这个选项让我很在意,不知道选 Internet 会怎么样,有知道选择 Internet 后收费会变成什么样的请务必告诉我。

创建文件共享

大部分都很简单,除了“层”要解释一下:

层的定义是按照是读写速度(事务优化程度)来的。比如,“已优化事务”最适合用在有很多业务、读写频繁的场合,他的读写性能好,并且事务操作的收费最低;然而,在上面存数据的花费最高。相反,“冷”层读写速度较慢,事务操作收费较高,但是存数据花费最低,适合存放归档数据。如果试图在冷层上做业务,或者在事务优化层存数据,都是钱多得烧手行为。“热”层就介于两者之间。

当然,我们是白嫖,不花钱,所以直接默认性能最好的事务优化层。

创建好之后,点进去,修改配额(也就是大小)。我这里修改为 20G。记住,免费 100G 是你名下所有使用了 LRS 文件存储的大小,而不是单个的大小。

挂载 SMB

我这里系统是 Debian 11(Azure),在 Ubuntu 20.04 (阿里云)上也成功了。其他系统请根据下面的微软文档链接自行更换命令。

安装 az login, cifs-utils, netcat

安装 az login:(来源:https://learn.microsoft.com/zh-cn/cli/azure/install-azure-cli-linux?pivots=apt

curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
az login

安装完会提示:To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code <一串代码> to authenticate. 去这个网址,登录你的存储账户所属的微软账号(账号不对后面会报错“该存储账户不存在(Resource group '<存储账户>' could not be found)”),然后输入代码完成授权。

接下来安装别的包:

sudo apt update
sudo apt install cifs-utils
sudo apt-get -y install netcat

连接 SMB

首先确保你的服务器 445 端口已在防火墙或者云服务器安全面板中放行。

然后把下面的 harukastoragetest_group 替换为你的资源组名,harukastoragetest 替换为你的存储账户名,share1替换为你的文件共享名:

RESOURCE_GROUP_NAME="harukastoragetest_group"
STORAGE_ACCOUNT_NAME="harukastoragetest"
FILE_SHARE_NAME="share1"

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 harukastoragetest.file.core.windows.net (<IP地址>) 445 port [tcp/microsoft-ds] succeeded!

如果出现下面的,那就可能是自己的 445 端口没打开,或者是其他原因:

nc: connect to harukastoragetest.file.core.windows.net (<IP地址>) port 445 (tcp) timed out: Operation now in progress

创建挂载点

挂载点就是你想把这个网盘挂载到哪个目录下。比如,我想把它挂载到可道云(可道云的安装见:玩转云服务(1):使用可道云搭建私人网盘 – Eterance的小窝),那么就要把这个目录放到可道云有权限访问的地方,在示例中也就是 /www/wwwroot/kodbox/remotedrive/harukasmbremotedrive/harukasmb 是我自己随意起的,只要挂载到 /www/wwwroot/kodbox 下面可道云都有权限访问,但是挂载到/home里面就不行了)。你要根据你自己的实际情况来修改 MNT_PATH

MNT_PATH="/www/wwwroot/kodbox/remotedrive/harukasmb"
sudo mkdir -p $MNT_PATH

创建存储凭据

CREDENTIAL_ROOT="/etc/smbcredentials"
sudo mkdir -p "/etc/smbcredentials"

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 '"')

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 "凭据文件 $SMB_CREDENTIAL_FILE 已经存在,并且未被修改。"
fi

sudo chmod 600 $SMB_CREDENTIAL_FILE

开机自动挂载 SMB

SMB_PATH=$(echo $HTTP_ENDPOINT | cut -c7-${#HTTP_ENDPOINT})$FILE_SHARE_NAME
sudo cp /etc/fstab /etc/fstab.bak

if [ -z "$(grep $SMB_PATH\ $MNT_PATH /etc/fstab)" ]; then
    echo "$SMB_PATH $MNT_PATH cifs nofail,credentials=$SMB_CREDENTIAL_FILE,noperm,serverino,nosharesock,actimeo=30" | sudo tee -a /etc/fstab > /dev/null
else
    echo "/etc/fstab 未被修改以避免冲突,因为此 Azure 文件共享已经存在。您可能需要重新检查 /etc/fstab (sudo vim /etc/fstab),以确保配置正确。"
fi

sudo mount -a

可能会输出 mount: cifs: mount point does not exist.,似乎可以忽略。

这个时候就会挂载上这个云盘,并且开机自动挂上。输入 df -h 检查一下:

就是成功了,容量也正确(就是一开始设置的 20G)。

(可选)测试一下

可以通过往挂载好的网盘里建立一个 txt 文件查看有没有建立成功。将下面的 /www/wwwroot/kodbox/remotedrive/harukasmb 修改为你自己的挂载路径:

cd /www/wwwroot/kodbox/remotedrive/harukasmb
echo "Hello world!" >> "testSMB.txt"
ls -a

这段命令会在挂载的网盘里添加一个 testSMB.txt 文件,并且显示文件夹下的所有文件。你应该会看到类似的以下输出:

同时,你也可以在 Azure 控制面板里看到这个 txt(刷新一下网页):

SMB 挂载是公交车,可以同一个网盘挂到很多服务器上。

下面是我用了一段时间的挂载(作为定时备份)。可以看到 LRS 存储确实没有花钱,但是第一位的带宽这个 0.29 刀是不是存储数据访问导致的就不知道了。网址:https://www.microsoftazuresponsorships.com/Usage

解挂 SMB

警告

解挂之前,要仔细检查没有其他服务在使用这个挂载,以及自行确保数据安全!

删除开机自动挂载

本节需要你掌握 vim 的基本使用。输入以下命令打开文件:

sudo vim /etc/fstab

最后一行就是我们刚才添加的 SMB 挂载。如果你添加了多个 SMB 挂载,请自行分辨。

切换到英文输入法,然后操纵键盘方向键使光标移动到那一行,然后按两次 d 键删除这一行,然后依次输入 :wq 保存并退出。如果你删错了,可以依次输入 :q! 不保存退出,然后再来一次。

删除挂载

上一步重启后就可以解挂了。如果不想重启,就输入下面命令(将 /www/wwwroot/kodbox/remotedrive/harukasmb 修改为你自己的挂载路径):

cd /
MNT_PATH="/www/wwwroot/kodbox/remotedrive/harukasmb"
sudo umount $MNT_PATH

上面加个 cd / 回到根目录是因为有时你的终端工作目录还在里面,就会报错 umount: <挂载目录>: target is busy.那你终端还在这个目录,当然 busy 了(粗心操作

如果成功(没有任何输出),输入 df -h 命令可以查看挂载消失了。

SMB 挂载被成功删除

如果终端工作目录确实不在里面,还是报错 umount: <挂载目录>: target is busy.,那就是还有进程在占用。省事就可以直接重启,或者使用:

fuser -mv $MNT_PATH

检查有啥进程在占用,然后杀掉它。(在此之前自行检查是不是重要进程,杀了会不会丢失数据!)