在Linux中挂载NFS后如何启动systemd服务

时间:2020-02-23 14:40:32  来源:igfitidea点击:

如何在挂载网络文件系统后执行脚本?
仅在NFS共享已安装并在Linux中可用后,如何才能启动systemd服务?
在网络共享(例如NFS,CIFS)安装在Linux之后,是否可以通过systemd服务执行脚本?
如何检查设备是否已安装systemd?

我现在经常从不同的用户那里得到这些问题。
随着RHEL/CentOS 7中systemd的引入,我们现在可以更好地控制系统服务,挂载点的处理和管理方式。
尽管在某些情况下,即使对于高级用户来说,配置选项的数量也可能不堪重负。
由于我们有很多选择,我们往往会混淆以选择满足我们要求的最佳选择。

在本教程中,我将共享启动服务之前检查是否已安装网络共享(例如NFS/CIFS)所需的systemd依赖关系。

1.创建网络共享

为了演示,我将使用NFS共享。
我已经写了一篇非常详细的文章,介绍配置NFS服务器的步骤,因此不再重复。

让我用一个具有读写权限的共享快速设置我的NFS服务器。

[root@nfs-server ~]# exportfs -v
/data           (sync,wdelay,hide,no_subtree_check,sec=sys,rw,no_root_squash,no_all_squash)

2.创建系统单元以挂载NFS共享

让我们继续NFS客户端。
由于我正在使用RHEL/CentOS,因此我将在服务器上安装nfs-utils以访问NFS共享。
有关其他发行版以及更多有关挂载NFS共享的详细信息,我们应该阅读:《初学者指南》,该示例在Linux中挂载NFS共享

在创建systemd单元文件之前,让我尝试手动安装NFS共享以确保配置正确

[root@nfs-client ~]# mount 192.168.43.10:/data /share
[root@nfs-client ~]# df -h /share/
Filesystem           Size  Used Avail Use% Mounted on
192.168.43.10:/data   17G  2.2G   14G  14% /share

因此,可以正确访问NFS服务器中的共享。
让我们卸载它,因为我们将使用systemd装载单元文件来装载它。

[root@nfs-client ~]# umount /share/

下面是我用于挂载NFS共享的systemd单元文件

提示:

创建安装单元文件时,应遵循某种命名语法。
例如,如果挂载点是/tmp/share,那么单元名称应该是temp-share.mount,如果挂载点是/var/srv-records/public,那么单元文件的名称应该是var-srv_records-public.mount
这与systemd如何从/etc/fstab中命名挂载单元文件的方式保持一致。

[root@nfs-client ~]# cat /etc/systemd/system/share.mount
[Unit]
Description=NFS Share from nfs-server.example.com(192.168.43.10)
DefaultDependencies=no
Conflicts=umount.target
After=network-online.target remote-fs.target
Before=umount.target
[Mount]
What=192.168.43.10:/data
Where=/share
Type=nfs
Options=defaults
[Install]
WantedBy=multi-user.target

让我们了解[Unit]部分:

  • 目标单元将对所有配置为Wants =或者Requires =的依赖项进行补充,并以After =类型的依赖项进行补充,除非在指定单元中设置了" DefaultDependencies = no"。

  • 我们将umount.target和Conflicts =放在一起,以确保在另一个单元启动之前停止了冲突单元

  • 由于NFS依赖于网络,因此我们将network-online.targetremote-fs.target放在After =下。

  • netfs服务(remote-fs.target服务)负责挂载/etc/fstab中列出的与网络相关的文件系统(NFS,SMBFS/CIFS,NCP或者任何带有_netdev选项的行)。

  • 一旦系统启动网络,它将仅挂载这些类型的文件系统。
    如果在启动时未启动此服务,则将不会安装与网络相关的文件系统。

  • 我们也想在umount.target之前调用我们的服务

考虑到[Mount]部分几乎是不言自明的,因此让我们跳过其余部分。

重新加载系统更改。
这是重要的步骤,请勿跳过此步骤:

[root@nfs-client ~]# systemctl daemon-reload

让我们验证此挂载单元服务文件,以确保它挂载了NFS共享

[root@nfs-client ~]# systemctl start share.mount

检查此服务的状态

[root@nfs-client ~]# systemctl status share.mount
● share.mount - NFS Share from nfs-server.example.com(192.168.43.10)
   Loaded: loaded (/etc/systemd/system/share.mount; enabled-runtime; vendor preset: disabled)
   Active: active (mounted) since Sun 2017-08-30 10:40:42 IST; 1s ago
    Where: /share
     What: 192.168.43.10:/data
    Tasks: 0 (limit: 30445)
   Memory: 156.0K
   CGroup: /system.slice/share.mount
Aug 30 10:40:42 nfs-client.example.com systemd[1]: Mounting NFS Share from nfs-server.example.com(192.168.43.10)...
Aug 30 10:40:42 nfs-client.example.com systemd[1]: Mounted NFS Share from nfs-server.example.com(192.168.43.10).

验证共享是否已安装在安装点上

[root@nfs-client ~]# df -h /share/
Filesystem           Size  Used Avail Use% Mounted on
192.168.43.10:/data   17G  2.2G   14G  14% /share

由于一切看起来都不错,我们将启用该服务,否则将不会在重新启动阶段执行该服务。

[root@nfs-client ~]# systemctl enable share.mount
Created symlink /etc/systemd/system/multi-user.target.wants/share.mount → /etc/systemd/system/share.mount.

重新启动节点后,我的共享已正确安装:

[root@nfs-client ~]# df -h /share/
Filesystem           Size  Used Avail Use% Mounted on
192.168.43.10:/data   17G  2.2G   14G  14% /share

说明:

除了使用systemd单元文件挂载NFS共享外,我们还可以使用旧方法,即/etc/fstab在重新引导期间挂载NFS共享。
fstab还将在内部创建systemd单元文件以挂载NFS共享。
继续并添加以下内容

# NFS_SERVER:/PATH/TO/EXPORTED/DIR    /MOUNT_POINT_ON_CLIENT    TYPE_OF_FS   OPTIONS   DUMP	PASS
  192.168.43.10:/data                 /share                    nfs          defaults    0    0

创建脚本(可选)

我假设我们已经拥有要挂载NFS共享后要执行的脚本。
但是为了演示,我将创建一个小的shell脚本。
我将以root用户身份执行脚本,但是我们也可以将其配置为以特定用户身份而不是root用户的身份被调用。

该脚本将执行某些预检查,然后在/share下创建目录。

在系统启动时访问NFS共享装载的示例脚本

创建系统服务单元文件以在NFS挂载后执行脚本

这是本教程的主要部分。

在安装并可用设备之后,我们将介绍systemd单元文件中执行脚本所需的依赖项。
我更喜欢在/etc/systemd/system中而不是其他位置创建服务单元文件。

# cat /etc/systemd/system/nfs-share.service
[Unit]
Description="Execute script after NFS share is mounted"
RequiresMountsFor=/share
[Service]
Type=simple
RemainAfterExit=yes
ExecStart=/root/create_dir.sh
[Install]
WantedBy=default.target

我们已经使用RequiresMountsFor来确保所提供的安装点正在使用中。
这会自动为访问指定路径所需的所有安装单元添加类型" Requires ="和" After ="的依赖项。

让我们启动该服务并验证其是否正常运行

[root@nfs-client ~]# systemctl start nfs-share.service

检查服务状态

[root@nfs-client ~]# systemctl status nfs-share.service

现在,如果我们检查此单位文件的属性,它将自动使用提供的安装点添加" Requires ="和" After ="部分。

[root@nfs-client ~]# systemctl show nfs-share.service | grep -E 'After=|Requires='
Requires=share.mount sysinit.target -.mount system.slice
After=systemd-journald.socket basic.target share.mount sysinit.target -.mount system.slice

因此,该服务已正确启动,并且已经按预期在NFS共享上创建了目录

[root@nfs-client ~]# ls -l /share/
total 4
drwxr-xr-x 2 root root 4096 Aug 30 11:32 dir_30-08-2017-11:32:19

接下来启用该服务,以确保它在重新启动后自动启动

[root@nfs-client ~]# systemctl enable nfs-share.service
Created symlink /etc/systemd/system/default.target.wants/nfs-share.service → /etc/systemd/system/nfs-share.service.

下一步,重新启动服务器,并验证其是否正常工作:

[root@nfs-client ~]# ls -l /share/
total 8
drwxr-xr-x 2 root root 4096 Aug 30 11:32 dir_30-08-2017-11:32:19
drwxr-xr-x 2 root root 4096 Aug 30 11:36 dir_30-08-2017-11:36:08

所以重启后,/share文件夹下还有一个目录,所以生活很好。

这是一个非常基本的示例,我们可能有一个脚本,该脚本需要运行更长的时间,在这种情况下,我们可以使用" TimeoutStartSec"来定义服务在终止该脚本并标记为systemd服务失败。

但是请注意,TimeoutStartSec不能与Type = oneshot一起使用,因为默认情况下此TimeoutStartSec被禁用。