利用systemd来管理服务
1.1 简介
systemd是linux系统的系统和服务管理器,它兼容之前的SysV init脚本,并提供一系列的其他特色:启动时系统服务的并行启动、按需启动服务、支持系统状态快照、基于服务依赖的控制逻辑。
systemd引入systemd units概念,这些units是通过一些配置文件代表的。以下列出所有的systemd units类型:
Unit Type File Extension Description
------------------------------------------------------------------
Service unit .service 系统服务
Target unit .target 一组systemd units
Automount unit .automount 文件系统的自动挂载点
-------------------------------------------------------------------
Device unit .device 由内核识别的设备文件
Mount unit .mount 文件系统挂载点
Path unit .path 文件系统中的文件或者目录
-------------------------------------------------------------------
Scope unit .scope 外部创建的进程
Slice unit .slice 一组管理系统进程的分级组织的units
Snapshot unit .snapshot 存储的系统管理器状态
Socket unit .socket 进程间通信套接字
-------------------------------------------------------------------
Swap unit .swap 交换设备或者文件
Timer unit .timer systemd定时器
Systemd unit存储位置:
文件夹 描述
/usr/lib/systemd/system/ 利用RPM包安装的软件产生的Systemd unit
/run/systemd/system/ 运行时产生的Systemd units,该文件夹优先于directory with installed service units
/etc/systemd/system/ 系统管理员创造的systemd units,该文件夹优先于运行时units
1.1.1 主要特点
也就是以上列出的系统支持的unit类型对应的启动特点。
1.1.2 兼容性
systemd对于runlevels的支持是比较局限的。它仅提供一些target units文件,这些文件可以对应runlevels中的运行级别。但是,并不是所有的运行级别都能一一对应,因此尽管可以用runlevel命令,但并不建议这么做。
systemctl工具并不支持定制命令,这在SysV int启动脚本中是可以的。systemctl工具并不能与非systemd启动的服务进行交流,当用systemd启动一个系统服务时,它会存储该服务主要进程的ID并跟踪,systemctl利用这个PID来管理这个服务,而当用户在命令行直接启动一个服务时,systemctl并不能判断该服务的状态也不能停止该服务。
系统服务并不能从标准输入读取信息,当systemd启动一个服务,它会把该服务的标准输入连接到/dev/null来防止与用户直接交流。
系统服务并不能从用户以及他们的对话中继承任何环境(包括HOME、PATH等环境变量),每一个服务都运行在新的执行环境中。
所有针对服务的操作都遵守默认5min的超时,以防服务发生问题导致系统死机。
1.2 管理系统服务
早期版本的RHEL采用SysV init或Upstart,利用/etc/rc.d/init.d/文件夹中的启动脚本,这些启动脚本通常是bash脚本,并且允许管理员控制服务的状态。在systemd控制的系统中,这些启动脚本被service units替代。
以.service后缀的系统units与启动脚本完成相似的功能,为了view、start、stop、restart、enable、disable一项系统服务,可以用systemctl命令。当然之前的service和chkconfig命令也是可用的,但是不建议使用。
为了清晰明了,该部分采用全名(带有.service后缀):
systemctl stop bluetooth.service
当处理系统服务时,允许省略文件后缀:systemctl工具当面对一个没有后缀的unit时,会默认其为service unit,因此上一个命令与下面的等价
systemctl stop bluetooth
systemctl start name.service 启动服务
systemctl stop name.service 关闭服务
systemctl restart name.service 重启服务
systemctl try-restart name.service 当系统运行状态则重启该服务
systemctl reload name.service 重新加载配置
systemctl status name.service 判断服务状态
systemctl is-active name.servie 判断服务是否在运行
systemctl list-units --type service --all 列出所有服务的状态
systemctl enable name.service 开机自启一项服务
systemctl disable name.service 关闭开机自启一项服务
systemctl is-enabled name.service 判断该服务是否enabled
systemctl list-unit-files --type service 列出所有的服务,并判断其是否enabled
systemctl list-dependencies --after 列出特定unit启动之前需要启动的服务
systemctl list-dependencies --before 列出特定unit启动之后才启动的服务
1.2.1 列出服务
为了列出目前所有的service units,用以下命令:
systemctl list-units --type service
默认情况下,systemctl list-units命令示出活动的units,如果想要列出任何状态的units,用以下命令:
systemctl list-units --type service --all
列出所有安装的服务以及它们的enable状态
systemctl list-unit-files --type service
1.2.2 显示服务状态
利用systemctl status name.service 会列出如下字段信息:
Loaded 关于该系统服务unit是否已加载、unit文件的绝对路径、该unit是否时enabled状态
Active 显示该服务是否在运行,并在其后有一个时间
Main PID 相应系统服务的名字以及其PID
Status 相应系统服务的额外信息
Process 相应进程的额外信息
CGroup 相关控制组(cgroups)的额外信息
1.2.3 启动一项服务
systemctl start name.service
|
|
1.2.6 自启一项服务
为了是Apache HTTP 服务器在开机时自启,可以用root用户运行如下命令
systemctl enable httpd.service
ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'
1.2.7 取消服务开机自启
systemctl disable name.service
该命令会把/usr/lib/systemd/system/name.service在/etc/systemd/system/文件夹以及其子文件夹中的链接删除。此外,你还可以通过mask来掩蔽一项服务,从而使其不能自启或由其它服务启动:
systemctl mask name.service
该命令会把/etc/systemd/system/name.service这一文件替换为指向/dev/null的链接,若想取消:
systemctl unmask name.service
1.3 Systemd targets
systemd targets通过target units代表,其具有.target后缀,target存在的唯一目的就是通过一系列依赖性集合其它的systemd units。例如,graphical.target unit就是用来开启图形会话,启动诸如gdm.service,accounts-daemon.service的服务,且激活multi-user.target unit
runlevel0.target,poweroff.target 关机
runlevel1.target,rescue.target 拯救模式,单用户模式
runlevel2.target,multi-user.target 字符界面多用户
runlevel3.target,multi-user.target 字符界面多用户
runlevel4.target,multi-user.target 字符界面多用户
runlevel5.target,graphical.target 图形界面多用户
runlevel6.target,reboot.target 重启
1.3.1 查看默认target
systemctl get-default
该命令查看/etc/systemd/system/default.target这一链接指向。
1.3.2 查看目前target
以下命令查看当前系统加载的target units:
systemctl list-units --type target
1.3.3 改变默认target
systemctl set-default name.target
1.3.4 改变目前target
systemctl isolate name.target
这一命令会启动name.target需要的所有服务,并终止所有不需要的服务。
1.3.5 改变到拯救模式
systemctl rescue
这一命令与systemctl isolate rescue.target基本相同,但是它会向目前登陆用户发送信息,要想阻止信息发送,可以用如下命令:
systemctl --no-wall rescue
1.3.6 改变到救急模式
systemctl emergency
与拯救模式类似,也会在进入前向登陆用户发送信息,也可以通过以下方式阻止信息发送:
systemctl --no-wall emergency
1.4 关机、休眠、睡眠
systemctl halt 关机
systemctl poweroff 关机断电
systemctl reboot 重启
systemctl suspend 挂起
systemctl hibernate 休眠
systemctl hybrid-sleep 休眠并挂起
shutdown命令:
为了在一个特定的时间关机并对机器断电,可以用如下格式的命令:
shutdown --poweroff hh:mm (hh:mm为24小时制时间格式)
当然也可以用:
shutdown --poweroff +m 在m分钟后关机
如果想要取消关机,可以用:
shutdown -c
1.5 在远程设备上操控systemd
除了可以在本机对systemd系统进行控制外,其还允许你通过SSH协议连接到远程电脑上进行操控。但是远程主机必须得运行sshd服务,你可以通过如下命令连接到该主机上:
systemctl --host user_name@host_name command
除了前面部分需要加上--host user_name@host_name外,command是相同的
1.6 创建、修改Systemd unit文件
Unit file具有如下形式:
unit_name.type_extension
文件结构: [Unit] 描述与unit类型无关的信息、对其它units的依赖
[unit type] 关于该unit类型的指引
[Install] 包含systemctl安装命令(enable/disable)
[Unit] Section:
Description 针对该unit的描述,该段文字会在systemctl status命令中显示
Documentation 提供关于该unit的帮助文档URIs
After 定义unit启动顺序,该unit会在该字段定义的unit启动后才启动
Requires 配置依赖的服务,这里列出的unit会同时启动
Wants 要求比Requires要若
Conflicts 冲突的units
[Service] Section:
Type
simple 默认值;
forking 该进程启动后会产生一个子程序并成为服务的主进程,父进程随之退出
oneshot 与simple相似,但是该进程会在后面的unit启动前关闭
dbus
notify 随后的units仅会在sd_notify()发送通知信息后启动
idle
ExecStart 指定unit启动后执行的命令或脚本
ExecStop 指定unit结束后执行的命令或脚本
ExecReload 指定unit重启后执行的命令或脚本
Restart 当该项enabled,则当进程退出后会重启,当然通过systemctl命令停止并不会重启
RemainAfterExit 如果为True,当它退出后仍会认为是活动的;默认值为false,该字段对Type=oneshot很有用
[Install] Section
Alias 提供该unit的别名,不同别名通过空格间隔
RequiredBy 依赖该unit的units
WantedBy 弱依赖units
Also 指定会随同该unit安装或卸载的units
1.6.2 创建自定义unit文件
(1)准备一个可执行的自定义服务,可以是一个脚本也可以是一个可执行程序。如果必须的话,准备一个包含该服务PID的PID文件。也可能会需要environment文件来储存该服务用到的shell变量。并确认该脚本是可执行的(chmod a+x)并且是非交互的。
(2)在/etc/systemd/system/文件夹下创建一个unit文件,并确认文件权限是正确的:
touch /etc/systemd/system/name.service
chmod 664 /etc/systemd/system/name.service
(3) 打开该name.service文件并加入配置选项。下面是一个网络相关的服务的例子:
[Unit]
Description=service_description
After=network.target
[Service]
ExecStart=path_to_executable
Type=forking
PIDFile=path_to_pidfile
[Install]
WantedBy=default.target
(4) 通知systemd有一个新的name.service文件存在,运行如下命令:
systemctl daemon-reload
systemctl start name.service
1.6.3 把SysV Init脚本转变为unit文件
需要作复杂的变换:找到服务描述、服务依赖、默认target、服务所用到的文件,这些过程比较复杂,需要对启动脚本中的目的明确才行。
1.6.4 修改现有的unit文件
安装的服务的默认unit文件一般储存在/usr/lib/systemd/system/文件夹下,系统管理员不应该直接修改这些文件;任何自定义都要在/etc/systemd/system/文件夹下进行,根据所需要修改的程序,选择以下方法中的一种即可:
> 在/etc/systemd/system/unit.d/下建立一个文件夹,这也是对大多数情况建议使用的方法。这种方法允许对默认配置增加额外的功能,而且能够保持原来的unit文件。
> 在/etc/systemd/system下拷贝/usr/lib/systemd/system中初始的unit文件。这一拷贝将会覆盖初始配置,因此软件包更新的配置并不能自动更新进来。这种方法经常用在对配置需要做永久的改动,而不论软件包是否更新。
如果想要复原默认配置,那么只需要删除以上创建的配置文件,而后重启系统或者运行如下命令即可:
systemctl daemon-reload
daemon-reload选项会重新加载所有的unit文件并重新生成依赖树,你也可以利用如下方法达到同样效果:
init q
同样,如果修改的unit文件属于一个正在运行的服务,那么服务必须重启才能接受新的设置:
systemctl restart name.service
· 拓展默认unit配置:
为了对默认的unit文件增加一些额外的选项,首先需要在/etc/systemd/system/下创建配置文件夹:
mkdir /etc/systemd/system/name.service.d
在上面的目录中新建配置文件,记住文件后缀必须为.conf
touch /etc/systemd/system/name.service.d/config_name.conf
然后在该文件中在相应的字段中加入配置即可。为了是修改生效,需要执行:
systemctl daemon-reload
systemctl restart name.service
· 重写默认unit配置:
为了要对软件包的配置作持久的更改,需要把unit文件拷贝到/etc/systemd/system/目录下:
cp /usr/lib/systemd/system/name.service /etc/systemd/system/name.service
然后对拷贝的文件做出需要的修改。之后运行:
systemctl daemon-reload
systemctl restart name.service
1.1 简介
systemd是linux系统的系统和服务管理器,它兼容之前的SysV init脚本,并提供一系列的其他特色:启动时系统服务的并行启动、按需启动服务、支持系统状态快照、基于服务依赖的控制逻辑。
systemd引入systemd units概念,这些units是通过一些配置文件代表的。以下列出所有的systemd units类型:
Unit Type File Extension Description
------------------------------------------------------------------
Service unit .service 系统服务
Target unit .target 一组systemd units
Automount unit .automount 文件系统的自动挂载点
-------------------------------------------------------------------
Device unit .device 由内核识别的设备文件
Mount unit .mount 文件系统挂载点
Path unit .path 文件系统中的文件或者目录
-------------------------------------------------------------------
Scope unit .scope 外部创建的进程
Slice unit .slice 一组管理系统进程的分级组织的units
Snapshot unit .snapshot 存储的系统管理器状态
Socket unit .socket 进程间通信套接字
-------------------------------------------------------------------
Swap unit .swap 交换设备或者文件
Timer unit .timer systemd定时器
Systemd unit存储位置:
文件夹 描述
/usr/lib/systemd/system/ 利用RPM包安装的软件产生的Systemd unit
/run/systemd/system/ 运行时产生的Systemd units,该文件夹优先于directory with installed service units
/etc/systemd/system/ 系统管理员创造的systemd units,该文件夹优先于运行时units
1.1.1 主要特点
也就是以上列出的系统支持的unit类型对应的启动特点。
1.1.2 兼容性
systemd对于runlevels的支持是比较局限的。它仅提供一些target units文件,这些文件可以对应runlevels中的运行级别。但是,并不是所有的运行级别都能一一对应,因此尽管可以用runlevel命令,但并不建议这么做。
systemctl工具并不支持定制命令,这在SysV int启动脚本中是可以的。systemctl工具并不能与非systemd启动的服务进行交流,当用systemd启动一个系统服务时,它会存储该服务主要进程的ID并跟踪,systemctl利用这个PID来管理这个服务,而当用户在命令行直接启动一个服务时,systemctl并不能判断该服务的状态也不能停止该服务。
系统服务并不能从标准输入读取信息,当systemd启动一个服务,它会把该服务的标准输入连接到/dev/null来防止与用户直接交流。
系统服务并不能从用户以及他们的对话中继承任何环境(包括HOME、PATH等环境变量),每一个服务都运行在新的执行环境中。
所有针对服务的操作都遵守默认5min的超时,以防服务发生问题导致系统死机。
1.2 管理系统服务
早期版本的RHEL采用SysV init或Upstart,利用/etc/rc.d/init.d/文件夹中的启动脚本,这些启动脚本通常是bash脚本,并且允许管理员控制服务的状态。在systemd控制的系统中,这些启动脚本被service units替代。
以.service后缀的系统units与启动脚本完成相似的功能,为了view、start、stop、restart、enable、disable一项系统服务,可以用systemctl命令。当然之前的service和chkconfig命令也是可用的,但是不建议使用。
为了清晰明了,该部分采用全名(带有.service后缀):
systemctl stop bluetooth.service
当处理系统服务时,允许省略文件后缀:systemctl工具当面对一个没有后缀的unit时,会默认其为service unit,因此上一个命令与下面的等价
systemctl stop bluetooth
systemctl start name.service 启动服务
systemctl stop name.service 关闭服务
systemctl restart name.service 重启服务
systemctl try-restart name.service 当系统运行状态则重启该服务
systemctl reload name.service 重新加载配置
systemctl status name.service 判断服务状态
systemctl is-active name.servie 判断服务是否在运行
systemctl list-units --type service --all 列出所有服务的状态
systemctl enable name.service 开机自启一项服务
systemctl disable name.service 关闭开机自启一项服务
systemctl is-enabled name.service 判断该服务是否enabled
systemctl list-unit-files --type service 列出所有的服务,并判断其是否enabled
systemctl list-dependencies --after 列出特定unit启动之前需要启动的服务
systemctl list-dependencies --before 列出特定unit启动之后才启动的服务
1.2.1 列出服务
为了列出目前所有的service units,用以下命令:
systemctl list-units --type service
默认情况下,systemctl list-units命令示出活动的units,如果想要列出任何状态的units,用以下命令:
systemctl list-units --type service --all
列出所有安装的服务以及它们的enable状态
systemctl list-unit-files --type service
1.2.2 显示服务状态
利用systemctl status name.service 会列出如下字段信息:
Loaded 关于该系统服务unit是否已加载、unit文件的绝对路径、该unit是否时enabled状态
Active 显示该服务是否在运行,并在其后有一个时间
Main PID 相应系统服务的名字以及其PID
Status 相应系统服务的额外信息
Process 相应进程的额外信息
CGroup 相关控制组(cgroups)的额外信息
1.2.3 启动一项服务
systemctl start name.service
|
|
1.2.6 自启一项服务
为了是Apache HTTP 服务器在开机时自启,可以用root用户运行如下命令
systemctl enable httpd.service
ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'
1.2.7 取消服务开机自启
systemctl disable name.service
该命令会把/usr/lib/systemd/system/name.service在/etc/systemd/system/文件夹以及其子文件夹中的链接删除。此外,你还可以通过mask来掩蔽一项服务,从而使其不能自启或由其它服务启动:
systemctl mask name.service
该命令会把/etc/systemd/system/name.service这一文件替换为指向/dev/null的链接,若想取消:
systemctl unmask name.service
1.3 Systemd targets
systemd targets通过target units代表,其具有.target后缀,target存在的唯一目的就是通过一系列依赖性集合其它的systemd units。例如,graphical.target unit就是用来开启图形会话,启动诸如gdm.service,accounts-daemon.service的服务,且激活multi-user.target unit
runlevel0.target,poweroff.target 关机
runlevel1.target,rescue.target 拯救模式,单用户模式
runlevel2.target,multi-user.target 字符界面多用户
runlevel3.target,multi-user.target 字符界面多用户
runlevel4.target,multi-user.target 字符界面多用户
runlevel5.target,graphical.target 图形界面多用户
runlevel6.target,reboot.target 重启
1.3.1 查看默认target
systemctl get-default
该命令查看/etc/systemd/system/default.target这一链接指向。
1.3.2 查看目前target
以下命令查看当前系统加载的target units:
systemctl list-units --type target
1.3.3 改变默认target
systemctl set-default name.target
1.3.4 改变目前target
systemctl isolate name.target
这一命令会启动name.target需要的所有服务,并终止所有不需要的服务。
1.3.5 改变到拯救模式
systemctl rescue
这一命令与systemctl isolate rescue.target基本相同,但是它会向目前登陆用户发送信息,要想阻止信息发送,可以用如下命令:
systemctl --no-wall rescue
1.3.6 改变到救急模式
systemctl emergency
与拯救模式类似,也会在进入前向登陆用户发送信息,也可以通过以下方式阻止信息发送:
systemctl --no-wall emergency
1.4 关机、休眠、睡眠
systemctl halt 关机
systemctl poweroff 关机断电
systemctl reboot 重启
systemctl suspend 挂起
systemctl hibernate 休眠
systemctl hybrid-sleep 休眠并挂起
shutdown命令:
为了在一个特定的时间关机并对机器断电,可以用如下格式的命令:
shutdown --poweroff hh:mm (hh:mm为24小时制时间格式)
当然也可以用:
shutdown --poweroff +m 在m分钟后关机
如果想要取消关机,可以用:
shutdown -c
1.5 在远程设备上操控systemd
除了可以在本机对systemd系统进行控制外,其还允许你通过SSH协议连接到远程电脑上进行操控。但是远程主机必须得运行sshd服务,你可以通过如下命令连接到该主机上:
systemctl --host user_name@host_name command
除了前面部分需要加上--host user_name@host_name外,command是相同的
1.6 创建、修改Systemd unit文件
Unit file具有如下形式:
unit_name.type_extension
文件结构: [Unit] 描述与unit类型无关的信息、对其它units的依赖
[unit type] 关于该unit类型的指引
[Install] 包含systemctl安装命令(enable/disable)
[Unit] Section:
Description 针对该unit的描述,该段文字会在systemctl status命令中显示
Documentation 提供关于该unit的帮助文档URIs
After 定义unit启动顺序,该unit会在该字段定义的unit启动后才启动
Requires 配置依赖的服务,这里列出的unit会同时启动
Wants 要求比Requires要若
Conflicts 冲突的units
[Service] Section:
Type
simple 默认值;
forking 该进程启动后会产生一个子程序并成为服务的主进程,父进程随之退出
oneshot 与simple相似,但是该进程会在后面的unit启动前关闭
dbus
notify 随后的units仅会在sd_notify()发送通知信息后启动
idle
ExecStart 指定unit启动后执行的命令或脚本
ExecStop 指定unit结束后执行的命令或脚本
ExecReload 指定unit重启后执行的命令或脚本
Restart 当该项enabled,则当进程退出后会重启,当然通过systemctl命令停止并不会重启
RemainAfterExit 如果为True,当它退出后仍会认为是活动的;默认值为false,该字段对Type=oneshot很有用
[Install] Section
Alias 提供该unit的别名,不同别名通过空格间隔
RequiredBy 依赖该unit的units
WantedBy 弱依赖units
Also 指定会随同该unit安装或卸载的units
1.6.2 创建自定义unit文件
(1)准备一个可执行的自定义服务,可以是一个脚本也可以是一个可执行程序。如果必须的话,准备一个包含该服务PID的PID文件。也可能会需要environment文件来储存该服务用到的shell变量。并确认该脚本是可执行的(chmod a+x)并且是非交互的。
(2)在/etc/systemd/system/文件夹下创建一个unit文件,并确认文件权限是正确的:
touch /etc/systemd/system/name.service
chmod 664 /etc/systemd/system/name.service
(3) 打开该name.service文件并加入配置选项。下面是一个网络相关的服务的例子:
[Unit]
Description=service_description
After=network.target
[Service]
ExecStart=path_to_executable
Type=forking
PIDFile=path_to_pidfile
[Install]
WantedBy=default.target
(4) 通知systemd有一个新的name.service文件存在,运行如下命令:
systemctl daemon-reload
systemctl start name.service
1.6.3 把SysV Init脚本转变为unit文件
需要作复杂的变换:找到服务描述、服务依赖、默认target、服务所用到的文件,这些过程比较复杂,需要对启动脚本中的目的明确才行。
1.6.4 修改现有的unit文件
安装的服务的默认unit文件一般储存在/usr/lib/systemd/system/文件夹下,系统管理员不应该直接修改这些文件;任何自定义都要在/etc/systemd/system/文件夹下进行,根据所需要修改的程序,选择以下方法中的一种即可:
> 在/etc/systemd/system/unit.d/下建立一个文件夹,这也是对大多数情况建议使用的方法。这种方法允许对默认配置增加额外的功能,而且能够保持原来的unit文件。
> 在/etc/systemd/system下拷贝/usr/lib/systemd/system中初始的unit文件。这一拷贝将会覆盖初始配置,因此软件包更新的配置并不能自动更新进来。这种方法经常用在对配置需要做永久的改动,而不论软件包是否更新。
如果想要复原默认配置,那么只需要删除以上创建的配置文件,而后重启系统或者运行如下命令即可:
systemctl daemon-reload
daemon-reload选项会重新加载所有的unit文件并重新生成依赖树,你也可以利用如下方法达到同样效果:
init q
同样,如果修改的unit文件属于一个正在运行的服务,那么服务必须重启才能接受新的设置:
systemctl restart name.service
· 拓展默认unit配置:
为了对默认的unit文件增加一些额外的选项,首先需要在/etc/systemd/system/下创建配置文件夹:
mkdir /etc/systemd/system/name.service.d
在上面的目录中新建配置文件,记住文件后缀必须为.conf
touch /etc/systemd/system/name.service.d/config_name.conf
然后在该文件中在相应的字段中加入配置即可。为了是修改生效,需要执行:
systemctl daemon-reload
systemctl restart name.service
· 重写默认unit配置:
为了要对软件包的配置作持久的更改,需要把unit文件拷贝到/etc/systemd/system/目录下:
cp /usr/lib/systemd/system/name.service /etc/systemd/system/name.service
然后对拷贝的文件做出需要的修改。之后运行:
systemctl daemon-reload
systemctl restart name.service