如果服务器稍后才准备好,如何自动挂载 CIFS 共享?

如果服务器稍后才准备好,如何自动挂载 CIFS 共享?

我的家庭网络上有两台服务器:

  • Linux 服务器。 (目前使用 systemd 运行 Debian,但我不认为这里有任何特定于 Debian 的东西。)
  • NAS 服务器。 (网络附加存储。)

断电后,两台服务器同时开启。然而,Linux服务器启动速度快,比NAS服务器更快。 Linux服务器可以访问网络,尝试挂载CIFS共享,但由于NAS服务器尚未准备好而失败。

即使NAS服务器启动时间较长,如何让Linux服务器自动挂载CIFS挂载? (多长时间?让我们假设夫妻分钟。)

当前配置

Linux 服务器有这样的行/etc/fstab(匿名):

//192.168.XX.XX/Foobar  /mnt/Foobar  cifs  credentials=/etc/fstab-cifs-credentials,rw,uid=1000,gid=1000,nobrl  0  0

它也在运行systemd,并sudo systemctl show mnt-Foobar.mount显示网络依赖项已自动配置:


Wants=network-online.target
After=system.slice network.target systemd-journald.socket network-online.target remote-fs-pre.target -.mount

journalctl或 by显示的错误消息sudo systemctl status mnt-Foobar.mount

mount[544]: mount error(113): could not connect to 192.168.XX.XXUnable to find suitable address.

如果手动触发,或者在 NAS 服务器启动后重新启动 Linux 服务器,则挂载效果良好。

需要什么

我需要一个解决方案,可以在完全放弃之前重试安装几次,每次尝试之间有一些延迟。

或者是不断重试安装的解决方案。

或者即使服务器尚未准备好,也认为挂载成功的解决方案,相信服务器最终会准备好。 (如果服务器未准备好,任何访问都应该阻塞几分钟。)

或者在安装网络文件系统之前引入固定的任意延迟的解决方案。

奖励:服务依赖性

我有一些使用存储在 NAS 上的文件的 Docker 服务。此类 docker 服务具有从/mnt/Foobardocker 容器到卷的映射。因此,docker 服务必须在所有 CIFS 挂载准备就绪后才启动。

设置此类服务依赖性是另一个问题的主题。然而,这个问题的解决方案应该与 docker 启动依赖关系很好地配合。

解决方法

我当前的解决方法是手动 ssh 进入 Linux 服务器,然后重新启动它或手动挂载共享。 (并手动重新启动 docker 服务。)绝对不理想,需要太多服务器的照顾。

答案1

只需将“x-systemd.automount”添加到您的 fstab 中,如下所示:

//192.168.XX.XX/Foobar  /mnt/Foobar  cifs  credentials=/etc/fstab-cifs-credentials,rw,uid=1000,gid=1000,nobrl,x-systemd.automount  0  0

Systemd 将为您处理一切。

答案2

完全未经测试:

$ cat /usr/local/libexec/cifs-mounter.sh
#! /bin/bash
SRV=192.168.0.111 # FQDN or IP address
while ! nc -z $SRV 445; do
    sleep 10
done

mount -t cifs //$SRV/share /mnt/point
$ cat /etc/systemd/system/multi-user.target.wants/cifs-mounter.service
[Unit]
Description=CIFS mounter
After=network.target

[Service]
ExecStart=/usr/local/libexec/cifs-mounter.sh
KillMode=process
Restart=on-failure
RestartSec=30s

[Install]
WantedBy=multi-user.target

答案3

长话短说:添加x-systemd.automount到安装选项,按照Zardoz89 的回答

现在我有一个不同的问题,即(重新)启动 docker 容器,由于启动太早而失败。但这是另一个问题。


官方文档位于man systemd.mount本文来自 SUSE 支持也很有帮助。

_netdev

有一个选项_netdev,但不需要,因为:

通常,文件系统类型用于确定挂载是否为“网络挂载”,即是否仅应在网络可用后启动。使用此选项会覆盖此检测并指定安装需要网络。

事实上,我比较了两个安装单元的输出systemctl show mnt-Foobar.mount(一个有这个选项,一个没有这个选项),它们非常相似。具体来说,AfterRequiredByRequiresMountsForRequiresWants等效的(但顺序不同;但顺序并不重要)。

x-systemd.automount

下列的Zardoz89 的回答,我尝试添加x-systemd.automount到我的安装点。

重新启动后,我可以通过查看systemctl list-automounts或来检查是否已检测到它systemctl list-units '*mount*'

尝试访问这些目录中的任何内容都会返回错误:

$ tree
.
└── Foobar  [error opening dir]

$ ls -R
.:
Foobar
ls: cannot open directory './Foobar': No such device

值得庆幸的是,一旦共享文件夹在服务器上可用,这些目录就重新开始工作。

Docker 故障

依赖于这些共享文件夹中的卷的 docker 容器仍然无法启动,并且即使在这些卷可用之后仍然处于关闭状态。也许我可以添加一些健康检查解决这个问题。或者尝试使用但无论如何这是一个不同的问题。

服务依赖

如果您的每项服务都有 systemd 单元,您可以/etc/fstab直接在文件中声明挂载点依赖关系,通过添加以下一个(或多个)选项:

  • x-systemd.after=
  • x-systemd.before=
  • x-systemd.required-by=
  • x-systemd.wanted-by=

其中每一项的含义都有解释man 系统单元

x-systemd.device-timeout 和 x-systemd.mount-timeout (对我不起作用)

假设您不想使用x-systemd.automount.那么,您仍然可以声明并增加安装这些设备的超时,使用:

  • x-systemd.device-timeout=
  • x-systemd.mount-timeout=

时间可以在s或中指定min(也可以h在 或 中指定ms,无论出于何种原因)。

然而,当我尝试使用它们时,它们不起作用。即使我有 15 分钟的超时,重新启动后这些挂载点仍然显示失败。所以,要么这些不起作用,要么它们对我不起作用,因为我对它们不够了解。

这可以与 systemd 依赖项结合起来,以确保您的服务仅在正确的时刻启动。

相关内容