Linux基础服务 Linux基础知识 ·

systemd之systemctl

systemd 这个启动服务的机制,主要是通过 systemctl 的命令来处理的!跟以前 systemV 需要 service / chkconfig / setup / init 等指令来协助不同, systemd 就是仅有 systemctl 这个指令来处理而已!

systemctl启动、关闭单一服务(service unit)

systemctl [command] [unit]

常用command主要有:

start :立刻启动后面接的 unit。

stop :立刻关闭后面接的 unit。

restart :重启后面接的 unit,即执行 stop 再 start 的意思。

reload :不关闭后面接的 unit 的情况下,重新载入配置文件,让设定生效。

enable :设定下次开机时,后面接的 unit 会被启动。

disable :设定下次开机时,后面接的 unit 不会被启动。

status :查看后面接的这个 unit 的状态,会列出有没有正在执行、开机预设执行否、登录等信息等!

is-active :查看有没有正在运作中。

is-enabled:查看开机时有没有预设要启用这个 unit。


一般不建议使用 kill 的方式来关掉一个正常的服务!否则 systemctl 会无法继续监控该服务!

daemon 的加载状态:

  • enabled:这个daemon 将在开机时被执行。
  • disabled:这个daemon 在开机时不会被执行。
  • static:这个 daemon 不可以自己启动( enable 不可),不过可能会被其他的 enabled 的服务来唤醒(相依赖属性的服务)
  • mask:这个 daemon 无论如何都无法被启动!因为已经被强制注销(非删除)。可提供systemctl unmask 方式改回原本状态。

daemon 的运行状态:

  • active (running):正有一支或多支程序正在系统中执行的意思。
  • active (exited):仅执行一次就正常结束的服务,目前并没有任何程序在系统中执行。举例来说,开机或者是挂载时才会进行一次的 quotaon 功能,就是这种模式!quotaon 不须要一直执行,只须执行一次之后,就交给文件系统去自行处理了!通常用 bash shell 写的小型服务,大多是属于这种类型(无须常驻内存)。
  • active (waiting):正在执行当中,不过还再等待其他的事件才能继续处理。举例来说,打印的伫列相关服务就是这种状态!虽然正在启动中,不过,也需要真的有伫列进来(打印工作)这样他才会继续唤醒打印机服务来进行下一步打印的功能。
  • active (dead):此程序已关闭。
  • inactive:这个服务目前没有运行的意思。

示例:开启 httpd 服务开机自启动

示例:查看 httpd 服务运行状态

示例:关闭 httpd 服务

示例:关闭 httpd 服务开机自启动并查看其状态

systemctl查看系统上所以的服务

通过 list-units 及 list-unit-files 可以查看当前系统上面有多少的服务存在。

systemctl [command] [--type=TYPE] [--all]

常用command:
list-units :依据 unit 列出目前有启动的 unit。若加上 --all 才会列出没启动的。
list-unit-files :依据 /usr/lib/systemd/system/ 内的文件,将所有文件列表说明。
--type=TYPE:就是 unit type,主要有 service, socket, target 等


示例:查看当前系统已启动的 unit

示例:列出已安装 unit

使用 systemctl list-unit-files 会将系统上所有的服务通通列出来~而不像 list-units 仅以 unit 分类作大致的说明。至于 STATE 状态就是开机是否会载入的那个状态项目!主要有 enabled / disabled / mask / static 等等。

示例:只查看 service 这种类别的 daemon,而且不论是否已经启动,通通要列出来!

systemctl管理不同的操作环境(target unit)

先查看一下跟操作界面比较有关的 target 项目

在 CentOS 7.1 的预设情况下,就有 26 个 target unit !而跟操作界面相关性比较高的 target 主要有底下几个:

  • graphical.target:就是字符加上图形界面,这个项目已经包含了底下的multi-user.target 项目!
  • multi-user.target:纯字符界面模式!
  • rescue.target:在无法使用root 登入的情况下,systemd 在开机时会多加一个额外的暂时系统,与你原本的系统无关。这时你可以取得 root 的权限来维护你的系统。但是这是额外系统,因此可能需要动到 chroot 的方式来取得你原有的系统!
  • emergency.target:紧急处理系统的错误,还是需要使用 root 登入的情况,在无法使用 rescue.target 时,可以尝试使用这种模式!
  • shutdown.target:就是关机的流程。
  • getty.target:可以设定你需要几个tty 之类的,如果想要降低 tty 的项目,可以修改这个东西的配置文件!

正常的模式是 multi-user.target 以及 graphical.target 两个,救援方面的模式主要是 rescue.target 以及更严重的 emergency.target。如果要修改可提供登入的 tty 数量,则修改 getty.target 项目。基本上,我们最常使用的当然就是 multi-user 以及 graphical !


查看与修改运行的操作环境可以使用如下命令:

systemctl [command] [unit.target]

command:
get-default :查看当前的 target。
set-default :设定后面接的 target 成为默认的操作模式。
isolate :切换到后面接的模式。


示例:查看当前运行的操作环境

要注意,改变 graphical.target 以及 multi-user.target 是通过 isolate 来处理的!在multi-user.target 环境下转成 graphical.target 时, 可以通过 systemctl start graphical.target !然而使用 systemctl stop graphical.target 是不能关闭图形界面回到字符界面环境的。

在 service 部份应该使用 start/stop/restart ,而在 target 项目则应该使用 isolate (隔离不同的操作模式) !

在正常的切换情况下,使用上述 isolate 的方式即可。不过为了方便起见, systemd 也提供了数个简单的指令给我们切换操作模式之用!大致上如下所示:

  • systemctl poweroff 系统关机
  • systemctl reboot 重新开机
  • systemctl suspend 进入暂停模式
  • systemctl hibernate 进入休眠模式
  • systemctl rescue 强制进入救援模式
  • systemctl emergency 强制进入紧急救援模式

什么是暂停与休眠模式呢?

  • suspend:暂停模式会将系统的状态数据保存到内存中,然后关闭掉大部分的系统硬件,而并没有实际关机!当使用者按下唤醒机器的按钮,系统数据会从内存中加载,然后重新驱动被关闭的硬件,开始正常运作!唤醒的速度较快。
  • hibernate:休眠模式则是将系统状态保存到磁盘当中,保存完毕后,将电脑关机。当使用者尝试唤醒系统时,系统会开始正常运作, 然后将保存在磁盘中的系统状态恢复回来。因为资料是由磁盘读出,因此唤醒的效能与你的磁盘速度有关。

systemctl分析各服务的依赖性

我们可以使用 systemctl 的子命令 list-dependencies 来查看 unit 的依赖关系。

systemctl list-dependencies [unit] [--reverse]
选项与参数:
--reverse :反向追踪谁使用这个unit 的意思!


范例:列出目前的 target 环境下,用到什么特别的 unit

范例:查看 graphical.target 使用了多少的服务

范例:查看谁会用到 multi-user.target

所以可以看得出来,graphical.target 就是在 multi-user.target 底下再加上 accounts-daemon, gdm, network, rtkit-deamon, systemd-update-utmp-runlevel 等服务而已!

systemctl配置文件相关目录简介

我们知道服务的管理是通过 systemd,而 systemd 的配置文件大部分放置于/usr/lib/systemd/system/ 目录内。但是Red Hat 官方文件指出, 该目录的文件主要是原本软件所提供的设定,建议不要修改!而要修改的位置应该放置于/etc/systemd/system/ 目录内。

举例来说,如果你想要额外修改vsftpd.service 的话, 他们建议要放置路径如下:

  • /usr/lib/systemd/system/ vsftpd.service:官方放出的预设配置文件;
  • /etc/systemd/system/ vsftpd.service.d /custom.conf:在 /etc/systemd/system 底下建立与配置文件相同文件名的目录,但是要加上 .d 的后缀。然后在该目录下建立配置文件即可。另外,配置文件最好后缀名为 .conf !在这个目录下的文件会『累加其他设定』进入/usr/lib/systemd/system/vsftpd.service 内!
  • /etc/systemd/system/ vsftpd.service.wants /*:此目录内的文件为链接文件,设定想依赖的服务的链接。意思是启动了 vsftpd.service 之后,最好再加上这目录底下建议的服务。
  • /etc/systemd/system/ vsftpd.service.requires /*:此目录内的文件为链接文件,设定相依赖服务的链接。意思是在启动 vsftpd.service 之前,需要事先启动哪些服务的意思。

基本上,在配置文件里面你都可以自由设定相依赖服务的检查,并且设定加入到哪些 target 里头去。但是如果是已经存在的配置文件,或者是官方提供的配置文件, Red Hat 是建议你不要修改原设定,而是到上面提到的几个目录去进行额外的自定义设定比较好!

systemctl配置文件内容简介

我们以 sshd.service 的内容做示例:

分析上面的配置文件,我们基本能够将整个设定分为三个部份:

  • [Unit]: unit 本身的说明,以及与其他相依赖 daemon 的设定,包括在什么服务之后才启动此 unit 之类的设定值;
  • [Service], [Socket], [Timer], [Mount], [Path]..:不同的 unit type 就得要使用相对应的设定项目。我们拿的是 sshd.service 来当范本,所以这边就使用[Service] 来设定。这个项目内主要在规范服务启动的脚本、环境配置文件的文件名、重新启动的方式等等。
  • [Install]:这个项目就是将此 unit 安装到哪个target 里面去的意思!

配置文件内设定规则的说明:

  • 设定项目通常是可以重复的,例如我可以重复设定两个 After 在配置文件中,不过,后面的设定会取代前面的!因此,如果你想要将设定值归零, 可以使用类似『 After= 』的设定,即该项目的等号后面什么都没有,就将该设定归零了(reset)。
  • 如果设定参数需要有『是/否』的项目(布林值, boolean),你可以使用1, yes, true, on 代表启动,用0, no, false, off 代表关闭!随喜好选择!
  • 空白行、开头为# 或 ; 的那一行,都代表注解!

每个部份里面还有很多的设定细项,如下表格说明:

[Unit] 部份
设定参数 参数意义说明
Description 就是当我们使用systemctl list-units 时,会输出给管理员看的简易说明!当然,使用systemctl status 输出的此服务的说明,也是这个项目!
这个项目在提供管理员能够进行进一步的文件查询的功能!提供的文件可以是如下的资料:
Documentation Documentation=http://www....
Documentation=man:sshd(8)
Documentation=file:/etc/ssh/sshd_config
After 说明此unit 是在哪个daemon 启动之后才启动的意思!基本上仅是说明服务启动的顺序而已,并没有强制要求里头的服务一定要启动后此unit 才能启动。以sshd.service 的内容为例,该档案提到After 后面有network.target 以及sshd-keygen.service,但是若这两个unit 没有启动而强制启动sshd.service 的话, 那么sshd.service 应该还是能够启动的!这与Requires 的设定是有差异的!
Before 与After 的意义相反,是在什么服务启动前最好启动这个服务的意思。不过这仅是规范服务启动的顺序,并非强制要求的意思。
Requires 明确的定义此unit 需要在哪个daemon 启动后才能够启动!就是设定相依服务啦!如果在此项设定的前导服务没有启动,那么此unit 就不会被启动!
Wants 与Requires 刚好相反,规范的是这个unit 之后最好还要启动什么服务比较好的意思!不过,并没有明确的规范就是了!主要的目的是希望建立让使用者比较好操作的环境。因此,这个Wants 后面接的服务如果没有启动,其实不会影响到这个unit 本身!
Conflicts 代表冲突的服务!亦即这个项目后面接的服务如果有启动,那么我们这个unit 本身就不能启动!我们unit 有启动,则此项目后的服务就不能启动!反正就是冲突性的检查啦!

 

接下来了解一下在[Service] 当中有哪些项目可以使用!

[Service] 部份
设定参数 参数意义说明
Type 说明这个daemon 启动的方式,会影响到ExecStart !一般来说,有底下几种类型

  • simple:预设值,这个daemon 主要由ExecStart 接的指令串来启动,启动后常驻于记忆体中。
  • forking:由ExecStart 启动的程序透过spawns 延伸出其他子程序来作为此daemon 的主要服务。原生的父程序在启动结束后就会终止运作。传统的unit 服务大多属于这种项目,例如httpd 这个WWW 服务,当httpd 的程序因为运作过久因此即将终结了,则systemd 会再重新生出另一个子程序持续运作后, 再将父程序删除。据说这样的效能比较好!!
  • oneshot:与simple 类似,不过这个程序在工作完毕后就结束了,不会常驻在记忆体中。
  • dbus:与simple 类似,但这个daemon 必须要在取得一个D-Bus 的名称后,才会继续运作!因此设定这个项目时,通常也要设定BusName= 才行!
  • idle:与simple 类似,意思是,要执行这个daemon 必须要所有的工作都顺利执行完毕后才会执行。这类的daemon 通常是开机到最后才执行即可的服务!

比较重要的项目大概是simple, forking 与oneshot 了!毕竟很多服务需要子程序(forking),而有更多的动作只需要在开机的时候执行一次(oneshot),例如档案系统的检查与挂载等等的。

EnvironmentFile 可以指定启动脚本的环境设定档!例如sshd.service 的设定档写入到/etc/sysconfig/sshd 当中!你也可以使用Environment= 后面接多个不同的Shell 变数来给予设定!
ExecStart 就是实际执行此daemon 的指令或脚本程式。你也可以使用ExecStartPre (之前) 以及ExecStartPost (之后) 两个设定项目来在实际启动服务前,进行额外的指令行为。但是你得要特别注意的是,指令串仅接受『指令参数参数...』的格式,不能接受, >>, |, & 等特殊字符,很多的bash 语法也不支援!所以,要使用这些特殊的字符时,最好直接写入到指令脚本里面去!不过,上述的语法也不是完全不能用,亦即,若要支援比较完整的bash 语法,那你得要使用Type=oneshot 才行!其他的Type 才不能支援这些字符。
ExecStop 与systemctl stop 的执行有关,关闭此服务时所进行的指令。
ExecReload 与systemctl reload 有关的指令行为
Restart 当设定Restart=1 时,则当此daemon 服务终止后,会再次的启动此服务。举例来说,如果你在tty2 使用文字界面登入,操作完毕后登出,基本上,这个时候tty2 就已经结束服务了。但是你会看到萤幕又立刻产生一个新的tty2 的登入画面等待你的登入!那就是Restart 的功能!除非使用systemctl 强制将此服务关闭,否则这个服务会源源不绝的一直重复产生!
RemainAfterExit 当设定为RemainAfterExit=1 时,则当这个daemon 所属的所有程序都终止之后,此服务会再尝试启动。这对于Type=oneshot 的服务很有帮助!
TimeoutSec 若这个服务在启动或者是关闭时,因为某些缘故导致无法顺利『正常启动或正常结束』的情况下,则我们要等多久才进入『强制结束』的状态!
KillMode 可以是process, control-group, none 的其中一种,如果是process 则daemon 终止时,只会终止主要的程序(ExecStart 接的后面那串指令),如果是control-group 时, 则由此daemon 所产生的其他control-group 的程序,也都会被关闭。如果是none 的话,则没有程序会被关闭!
RestartSec 与Restart 有点相关性,如果这个服务被关闭,然后需要重新启动时,大概要sleep 多少时间再重新启动的意思。预设是100ms (毫秒)。

 

最后,再来看看那么Install 内还有哪些项目可用?

[Install] 部份
设定参数 参数意义说明
WantedBy 这个设定后面接的大部分是*.target unit !意思是,这个unit 本身是附挂在哪一个target unit 底下的!一般来说,大多的服务性质的unit 都是附挂在multi-user.target 底下!
Also 当目前这个unit 本身被enable 时,Also 后面接的unit 也请enable 的意思!也就是具有相依性的服务可以写在这里呢!
Alias 进行一个连结的别名的意思!当systemctl enable 相关的服务时,则此服务会进行连结档的建立!以multi-user.target 为例,这个家伙是用来作为预设操作环境default.target 的规划, 因此当你设定用成default.target 时,这个/etc/systemd/system/default.target 就会连结到/usr/lib/systemd/system/multi-user.target 啰!

大致的项目就有这些!

参与评论