一、Systemd 简介
首先 systmed 是一个用户空间的程序,属于应用程序,不属于 Linux 内核范畴。Systemd 是 Linux 系统中最新的初始化系统(init),它主要的设计目标是克服 sysvinit 固有的缺点,提高系统的启动速度。
Linux内核加载启动后,用户空间的第一个进程就是初始化进程,这个程序的物理文件约定位于/sbin/init,当然也可以通过传递内核参数来让内核启动指定的程序。这个进程的特点是进程号为1,代表第一个运行的用户空间进程。不同发行版采用了不同的启动程序,主要有以下几种主流选择:
- 以 Ubuntu 为代表的 Linux 发行版采用 upstart
- CentOS7.0 版本之前的 System V init
- CentOS7.0 版本的 systemd
下面是 CentOS6.5 和 CentOS7 两个版本初始化进程的信息截图:
二、Systemd unit
对于开发者来说,工作量最大的部分应该是编写配置单元文件,定义所需要的单元。
举例来说,开发人员开发了一个新的服务程序,比如 httpd,就需要为其编写一个配置单元文件以便该服务可以被 systemd 管理,类似 UpStart 的工作配置文件。在该文件中定义服务启动的命令行语法,以及和其他服务的依赖关系等。
此外我们之前已经了解到,systemd 的功能繁多,不仅用来管理服务,还可以管理挂载点,定义定时任务等。这些工作都是由编辑相应的配置单元文件完成的。
2.1 systemd unit 类型
Unit Type | File Extension | Description |
---|---|---|
Service unit |
.service |
服务类 |
Target unit |
.target |
一个 unit 服务组,用于模拟实现运行级别 |
Automount unit |
.automount |
文件系统自动挂载点 |
Device unit |
.device |
内核识别的设备文件 |
Mount unit |
.mount |
文件系统挂载点 |
Path unit |
.path |
文件或目录 |
Scope unit |
.scope |
外部创建的进程 |
Slice unit |
.slice |
A group of hierarchically organized units that manage system processes. |
Snapshot unit |
.snapshot |
系统快照 |
Socket unit |
.socket |
套接字 |
Swap unit |
.swap |
标识 swap 设备 |
Timer unit |
.timer |
systemd 的计时器 |
2.2 unit 文件保存位置
Directory | Description |
---|---|
/usr/lib/systemd/system/ |
RPM 包安装时分发的 unit 文件 |
/run/systemd/system/ |
systemd 运行时创建的文件 |
/etc/systemd/system/ |
systemctl enable 创建的 unit 文件 |
2.3 几个配置单元文件示例
下面是 iptables 服务的配置单元文件,服务配置单元文件以 .service 为文件名后缀:
文件分为三个小节。第一部分是 [Unit] ,这里仅仅有一个描述信息。第二部分是 [Service] ,ExecStart 定义启动服务的具体命令行语法。第三部分是 [Install] ,WangtedBy 表明这个服务是在多用户模式下所需要的。
接下来我们就来看下 multi-user.target 吧:
在 [Unit] 小节中的 Requires 定义表明 multi-user.target 启动的时候 basic.target 也必须被启动;另外 basic.target 停止的时候,multi-user.target 也必须停止。如果您接着查看 basic.target 文件,会发现它又指定了 sysinit.target 等其他的单元必须随之启动。同样 sysinit.target 也会包含其他的单元。采用这样的层层链接的结构,最终所有需要支持多用户模式的组件服务都会被初始化启动好。
在 [Install] 小节中有 Alias 定义,即定义本单元的别名,这样在运行 systemctl 的时候就可以使用这个别名来引用本单元。这里的别名是 default.target,比 multi-user.target 要简单一些。
此外在 /etc/systemd/system 目录下还可以看到诸如 *.wants 的目录,放在该目录下的配置单元文件等同于在 [Unit] 小节中的 wants 关键字,即本单元启动时,还需要启动这些单元。比如您可以简单地把您自己写的 foo.service 文件放入 multi-user.target.wants 目录下,这样每次都会被默认启动了。
最后,让我们来看看 sys-kernel-debug.mout 文件,这个文件定义了一个文件挂载点:
挂载配置单元文件有一个 [Mount] 配置小节,里面配置了 What,Where 和 Type 三个数据项,这都是挂载命令所必须的。配置单元文件的编写需要很多的学习,必须参考 systemd 附带的 man 等文档进行深入学习。
三、管理系统服务
systemd 的主要命令行工具是 systemctl 。
多数管理员应该都已经非常熟悉系统服务和 init 系统的管理,比如 service、chkconfig 以及 telinit 命令的使用。systemd 也完成同样的管理任务,只是命令工具 systemctl 的语法有所不同而已。
3.1 Systemd 命令和 sysvinit 命令对比
service 和 systemctl:
service | systemctl | Description |
---|---|---|
service name start |
systemctl start name.service |
启动服务 |
service name stop |
systemctl stop name.service
|
停止服务 |
service name restart |
systemctl restart name.service
|
重启服务(没启动的服务会启动) |
service namecondrestart |
systemctl try-restart name.service |
只重启正在运行的服务 |
service name reload |
systemctl reload name.service |
重载配置文件 |
service name status |
systemctl status name.service systemctl is-active name.service |
检查服务状态 检查服务是否启动 |
service --status-all |
systemctl list-units --type service --all |
显示所有的服务状态 |
chkconfig 和 systemctl:
chkconfig | systemctl | Description |
---|---|---|
chkconfig name on |
systemctl enable name.service |
启用开机自启服务 |
chkconfig name off |
systemctl disable name.service |
停用自启服务 |
chkconfig --list name |
systemctl status name.service systemctl is-enabled name.service |
检查服务状态 查看服务是否自启 |
chkconfig --list |
systemctl list-unit-files --type service |
查看所有服务 |
chkconfig --list |
systemctl list-dependencies --after |
列出在指定服务之前启动的服务(依赖) |
chkconfig --list |
systemctl list-dependencies --before |
列出在指定服务之后启动的服务(被依赖) |
一个服务设置为开机启动使用会将 /usr/lib/systemd/system/name.service 软链接到 /etc/systemd/system/ ,但是 enable 命令不会重写已经存在的链接,所以当我们修改了服务文件就需要重新加载:
systemctl reenable name.service
3.2 服务状态信息
Field | Description |
---|---|
Loaded |
关于服务是否已经加载的信息,文件的绝对路径以及是否被启用的注释 |
Active |
服务是否正在运行,然后是启动时间信息 |
Main PID |
服务主进程 PID |
Status |
系统服务的额外信息 |
Process |
进程额外信息 |
CGroup |
Control Groups(cgroups)额外信息 |
3.3 电源管理命令
命令 | 操作 |
---|---|
systemctl reboot |
重启机器 |
systemctl poweroff |
关机 |
systemctl suspend |
待机 |
systemctl hibernate |
休眠 |
systemctl hybrid-sleep |
混合休眠模式(同时休眠到硬盘并待机) |
关机不是每个登录用户在任何情况下都可以执行的,一般只有管理员才可以关机。正常情况下系统不应该允许 SSH 远程登录的用户执行关机命令。否则其他用户正在工作,一个用户把系统关了就不好了。为了解决这个问题,传统的 Linux 系统使用 ConsoleKit 跟踪用户登录情况,并决定是否赋予其关机的权限。现在 ConsoleKit 已经被 systemd 的 logind 所替代。
参考
《浅析 Linux 初始化 init 系统,第 3 部分: Systemd》:https://www.ibm.com/developerworks/cn/linux/1407_liuming_init3
《Managing Services with systemd》:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/chap-managing_services_with_systemd