我的家庭网络上有两台服务器:
- 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/Foobar
docker 容器到卷的映射。因此,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
(一个有这个选项,一个没有这个选项),它们非常相似。具体来说,After
、RequiredBy
、RequiresMountsFor
和Requires
是Wants
等效的(但顺序不同;但顺序并不重要)。
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 依赖项结合起来,以确保您的服务仅在正确的时刻启动。