Chapter1 - 控制服务和守护进程
使用systemctl 控制服务
系统启动和服务器进程由systemd 系统和服务管理器进行管理。此程序提供了一种方式,可以在启动时和运行中的系统上激活系统资源、服务器守护进程和其他进程。
守护 进程是在执行我各种任务的后台等待或运行的进程。为了侦听连接,守护进程使用套接字。套接字可以由守护进程创建,或者与守护进程分离,并且可能由另一个进程创建(systemd),随后在客户端建立老婆如甲方将套接字为传递到守护进程。
服务通常指的是一个或多个守护进程,但启动或停止一项服务可能会对系统的状态进行一次性更改(如配置网络接口),不会留下守护进程之后继续运行。
一点历史
许多年来,Linux 和 unix 系统的进程ID 1 属于 init 进程。此进程负责激活系统上的其他服务。常用的守护进程在系统启动时通过System V 和 Linux Standard Base(LSB) init 脚本启动。较不常用的守护进程由其他服务根据需要启动,如 init 或 Xinetd 。这些系统存在诸多限制,但 systemd 可以解决。
在RHEL 7 中进程ID 1 属于systemd 这一新的init ,以下是 systemd 系统提供的几项新功能:
- 并行化功能,它可提高系统的启动速度。
- 按需启动守护进程,而不需要单独的服务。
- 自动服务依赖关系管理可以防止长时间超时,例如在网络不可用时不启动网络服务。
- 利用 Linux 控制组一起追踪相关进程的方式。
注意
有了 systemd ,基于 shell 的服务脚本仅用于几个传统服务.因此,带有shell 变量的配置文件将被取代,如 /etc/sysconfig 中可找到的配置文件。仍在使用中的配置文件作为systemd 环境文件被纳入,并作为 NAME=VALUE 对进行读取。它们不再以 shell 脚本的形式提供。
systemctl 和 systemd 单元
systemctl 命令用于管理各种类型的systemd 对象,他们称为单元。可以通过systemctl -t help 命令显示单元类型的列表。
重要
systemctl 可以缩写或“省略”单元名称、进程树条目和单元说明,除非运行时带有 -l 选项。
常用单元类型:
- 服务单元具有.service 扩展名,代表系统服务。这种单元用于启动经常访问的守护进程,如web 服务器
- 套接字单元具有.socket 扩展名,代表进程间通信(IPC)套接字。套接字的控制可能在建立客户端老婆如甲方传递到守护进程或新启动的服务。套接字单元用于延迟启动时的服务启动,或者按需启动不常使用的服务,这原则上类似使用xinetd 超级服务器按需启动的服务。
- 路径单元具有 .path 扩展名,用于将服务的激活推迟到特定文件系统更改发生之后。这通常用于使用假脱机目录,如打印系统。
服务状态
可能通过 systemctl status name.type 查看服务的状。如果示提供单元类型,则 systemctl 将显示服务单元的状态(如果存在)
[root@rhel ~]# systemctl status sshd.service
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2019-01-03 19:26:20 CST; 49s ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 9232 (sshd)
CGroup: /system.slice/sshd.service
└─9232 /usr/sbin/sshd -D
Jan 03 19:26:20 rhel.tk systemd[1]: Starting OpenSSH server daemon...
Jan 03 19:26:20 rhel.tk sshd[9232]: Server listening on 0.0.0.0 port 22.
Jan 03 19:26:20 rhel.tk sshd[9232]: Server listening on :: port 22.
Jan 03 19:26:20 rhel.tk systemd[1]: Started OpenSSH server daemon.
Jan 03 19:26:58 rhel.tk sshd[9745]: Accepted password for root from 192.168.142.1 port 63462 ssh2
COPY
关键字 | 描述 |
---|---|
loaded | 单元配置文件已经处理 |
active(running) | 正在通过一个或多个持续进程运行 |
active(exited) | 已完成一次性配置 |
active(waiting) | 运行中,但正在等待事件 |
inactive | 不在运行 |
enabled | 将在系统启动时启动 |
disabled | 不会在系统启动时启动 |
static | 无法启动,但可以由某一启用的单元自动启动 |
注意
systemctl status NAME 命令取代了旧版的 RHEL 中使用的service NAME status
使用systemctl 列出单元文件
#查询所有单元的状态以 验证系统启动
[root@rhel ~]# systemctl
#仅查询服务单元的状态
[root@rhel ~]# systemctl --type=service
#调查处于失败或者维护状态的任何单元。可选择添加 -l 选项以显示完整的输出。
[root@rhel ~]# systemctl status rngd.service -l
#也可使用 status 参数来判断特定的单元是否活动,以及显示该单元是否已启用在系统启动时启动。其他备用命令也可以轻松显示活动和已启用状态:
[root@rhel ~]# systemctl is-active sshd
[root@rhel ~]# systemctl is-enabled sshd
#列出所有已加载单元的活动状态。也可选择限制单元类型。--all 选项可加入不活动的单元
[root@rhel ~]# systemctl list-units --type=service
[root@rhel ~]# systemctl list-units --type=service --all
#列出所有单元的已启用和已禁用设置。也可选择限制单元类型。
[root@rhel ~]# systemctl list-unit-files --type=service
#仅查看失败的服务。
[root@rhel ~]# systemctl --faild --type=serviceCOPY
启动和停止运行中系统上的系统守护进程
启动、停止、重新启动、重新加载和验证状态是管理服务时经常执行的操作。
查看sshd 服务的状态。
[root@rhel ~]# systemctl status sshd.service
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2019-01-03 19:26:20 CST; 1h 46min ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 9232 (sshd)
CGroup: /system.slice/sshd.service
└─9232 /usr/sbin/sshd -D
Jan 03 19:26:20 rhel.tk systemd[1]: Starting OpenSSH server daemon...
Jan 03 19:26:20 rhel.tk sshd[9232]: Server listening on 0.0.0.0 port 22.
Jan 03 19:26:20 rhel.tk sshd[9232]: Server listening on :: port 22.
Jan 03 19:26:20 rhel.tk systemd[1]: Started OpenSSH server daemon.
Jan 03 19:26:58 rhel.tk sshd[9745]: Accepted password for root from 192.168.142.1 port 63462 ssh2
[root@rhel ~]#
验证进程正在运行。
[root@rhel ~]# ps -up 9232
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 9232 0.0 0.1 112756 4316 ? Ss 19:26 0:00 /usr/sbin/sshd -D

停止服务并验证其状态

启动服务并查看状态。进程ID已经改变

以单一命令停止服务,然后再启动该服务

发出指示使用服务读取和重新加载配置文件,而不完全停止和启动服务。进程ID 不会改变
单元依赖项
服务可能会以其他服务依赖项的形式启动。如果套接字单元已启动。但名称相同的服务单元没有启动,对该网络套接字发出请求时将自动启动该服务。服务也可能会在满足文件系统条件时由路径单元触发。
systemctl list-dependencies UNIT 命令可用于显示必须与特定单元联会启动的其他单元的树。此命令 –reverser 选项将显示哪些单元必须要在指定单元启动后才能运行。
屏蔽服务
系统可能针对某一特定功能安装了有冲突的服务,如防火墙(iptables 和 firewalld )。为防止管理员意外启动某一服务,可以屏蔽将在配置目录中创建链接,使得启动该服务时什么也不会发生。

重要
禁用的服务不会在系统启动时自动启动,也不会被其他单元文件启动,但可以手动启动。屏蔽的服务无法手动启动,也不会自动启动。
使守护进程在系统启动时启动或停止
#查看服务的状态
[root@rhel ~]# systemctl status sshd.service
#禁用服务并验证其状态。请注意禁用服务不会停止该服务
[root@rhel ~]# systemctl disable sshd.service
[root@rhel ~]# systemctl status sshd.service
#启用服务并验证其状态
[root@rhel ~]# systemctl enable sshd.service
[root@rhel ~]# systemctl is-enabled sshd.service
命令 | 任务 |
---|---|
systemctl status UNIT | 查看有关单元状态的详细信息 |
systemctl stop UNIT | 在运行中的系统上停止一项服务 |
systemctl start UNIT | 在运行中的系统上启动一项服务 |
systemctl restart UNIT | 在运行中的系统上重启一项服务 |
systemctl reload UNIT | 重新加载运行中服务的配置文件 |
systemctl mask UNIT | 彻底禁用服务,使其无法手动启动或在系统启动时启动 |
systemctl umask UNIT | 使屏蔽的服务变为可用 |
systemctl enable UNIT | 将服务配置为在系统启动时启动 |
systemctl disable UNIT | 禁止服务在系统启动时启动 |
systemctl list-dependencies UNIT | 列出指定单元依赖的单元 |
控制启动过程
选择systemd 目标
systemd 目标是一组应在启动后牵动所需状态的systemd 单元。下表中列出了重要目标。
目标 | 用途 |
---|---|
graphical.target | 系统支持多用户、图形和基于文件的登录 |
multi-user.target | 系统仅支持多用户、基于文本的登录 |
rescue.target | sulogin提示,表示 基本系统初始化已完成 |
emergency.target | sulogin提示,表示initramfs回转完成,且系统root以只读形式挂载于 / 上 |
某个目标可能属于另一目标;例如 graphical.target 包含multi-user.target 后者反过来取决于basic.target 和其他目标。使用以下命令可从命令行查看这些依赖:
[root@client ~]# systemctl list-dependencies graphical.target | grep target
使用以下命令可查看所有可用目标的概述:
[root@client ~]# systemctl list-units --type=target --all
使用以下命令可查看磁盘上安装 的所有目标的概述:
[root@client ~]# systemctl list-unit-files --type=target --all
在运行时选择目标
在运行的系统中,管理员可以选择使用 systemctl isolate 命令来切换到其他目标;例如 systemctl isolate multi-user.target 。
注意
并非所有目标都能隔离(isolate)。只有单元文件中设置了 AllowIsolate=yes 的目标才可以隔离;例如 grephical.target 目标可以隔离,但cryptsetup.target 目标不能隔离。

设备默认目标
在系统启动且将控制权从initramfs 交给 systemd 后,systemd 会尝试激活 default.target 目标。通常,default.target 目标是 (/etc/systemd/system/中) 会指向 graphical.target 或 multi-user.target 的符号链接。
systemctl 工具提供了两个命令来管理连接:get-default 和set-default .

在启动时选择其他目标
要在启动时选择其他目标,可从启动加载器将特殊选项附加到内核命令行: systemd.unit= 。例如,要将系统启动到救援 shell ,请在交互启动加载器菜单中传递以下选项:
systemd.unit=resecue.target
要使用这种选择其他目标的方法,请针对 RHEL 7 系统执行以下步骤:
- (重新)启动系统
- 按任意键中断启动加载菜单倒计时。
- 将光标移至要启动的条目。
- 按 e 编辑当前条目
- 将光标移至以 linux16 开关的行。此为内核命令行。
- 附加 systemd.unit=rescue.target
- 按 Ctrl + x 使用这些更改进行启动。
恢复 root 密码
在仍以管理员或者具有完整sudo 访问权限的用户的身份登录时,恢复root 用户密码是一项微不足道的任务,但在管理员未登录时,这项任务便略微有点复杂。在后面的情况中,管理员可以从 Live CD 中启动,从其中挂载根文件系统并编辑/etc/shadow 。管理员还能够在不使用外部介质的情况下执行根密码恢复。
注意:
在RHEL 6 及早期版本中,管理员可以启动系统进入 runlevel 1 然后看到一个root 提示。在 RHEL 7 计算机上与 runlevel 1 最接近的模拟是 rescue.target 和emergency.target 目标,这两个目标都需要 root 密码才能登录。
在RHEL 7中,可以使用 initramfs
运行的脚本在某些点暂停,提供 root shell
,然后在该 shell 存在的情况继续。虽然主要是为了进行调试,但也可以用于懒得丢失的 root 密码
- 重新启动系统
- 按任意键中断启动加载倒计时。
- 将光标移动到需要启动的条目。
- 按 e 编辑选项目标条目
- 将光标移至以 linux16 开关的行(内核命令行)
- 附加 rd.break console=tty0(就在从 initramfs 向实际系统移动控制权前,该操作会中断,最新版的7.4已经可以不要跟 console=tty0了)
- 按 Ctrl + x 使用这些更改进行启动,此时会显示 root shell 且实际系统 root 文件系统会在 /sysroot 中以只读方式挂载
- 由于此时尚未启用 selinux ,因此任何创建的新文件都不会分配有 SElinux 上下文。请记住,有些工具(例如passwd )首先会创建一个新文件,然后移动新文件以代替要编辑的文件,从而有效的创建不带 SElinux 上下文的新文件。
- 此时要恢复 root 密码,请使用如下步骤:
- 以读写形式重新挂载 /sysroot
- switch_root:/#mount -oremount,rw /sysroot
- 切换为 chroot 存放位置,其中 /sysroot 被视为系统树的 root
- switch_root:/#chroot /sysroot
- 设置新 root 密码
- sh-4.2# passwd root
- 确保所有未标记的文件 (包括此时的 /etc/shadow )在启动过程中都会重新获得标记
- sh-4.2# touch /.autorelabel
- 键入exit 两次,第一次将退出 chroot 存放位置,第二次将退出 initramfs 。调试 shell 。此时系统将继续进行启动,执行完整的 SElinux 重新标记,然后再次重新启动。
诊断和修复 systemd 启动问题
如果在启动服务过程中出现问题,则有几个工具可供系统管理员用于协助高度和 / 或故障排除:
早期调试 shell
通过运行 systemctl enable debug-shell.service ,启动序列早期将在 tty9 (Ctrl+Alt+F9) 上生成一个 root shell ,该 shell 会自动作为 root 登录 ,这样,管理员可以在系统仍在启动时使用一些其他调试工具。
警告
在完成高度后,请不要忘记禁用 debug-shell.service 服务,因为该服务会使未经身份验证的 root shell 向任何拥有本地控制台访问权限的人员开放。
紧急情况和救援目标
通过从启动加载器将 systemd.unit=rescue.target 或 systemd.unit=emergency.target附加到内核命令行,系统将生成特殊的救援或紧急情况shell ,而不是正常启动。这两个 shell 都需要提供 root 密码。emergency 目标使用 root 文件系统以只读试挂载,而 rescue.target 会等待 sysinit.target 先完成,这样更多的系统会进行初始化,例如日志记录、文件系统等。从这些 shell 退出后,系统会继续进行常规启动过程。
阻塞作业
在启动过程中,systemd 会生成大量作业。如果其中某些作业无法完成,则他们会妨碍其他作业运行,要检查 当前作业列表,管理员使用命令 systemctl list-jobs 。所有列为 running 的作业都必须先完成,然后列为 wating 的作业能可以继续。