在Linux中挂载NFS后如何启动systemd服务
如何在挂载网络文件系统后执行脚本?
仅在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.target
和remote-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被禁用。