实验3: 启动和启动过程¶
目标¶
完成本实验后,您将能够
- 手动控制一些启动过程和服务
- 自动控制服务
估计完成本实验所需时间: 50 分钟
启动过程概述¶
本实验中的练习将从启动过程开始,一直到用户登录。 这些步骤将检查并尝试自定义启动过程的部分内容。 启动过程中的高级步骤如下:
步骤总结¶
- 硬件加载、读取并执行引导扇区
- 执行引导加载程序 (大多数 Linux 发行版上的 GRUB)
- 内核解压缩并执行
- 内核初始化硬件
- 内核挂载根文件系统
- 内核执行 /usr/lib/systemd/systemd 作为 PID 1
systemd
启动运行默认启动目标所需的单元和配置getty
程序在每个定义的终端上生成getty
提示登录getty
执行 /bin/login 以验证用户- 登录启动 Shell
systemd
¶
systemd
是 Linux 操作系统的系统和服务管理器。
systemd
单元¶
systemd
为各种实体提供了一个依赖系统,称为“单元”。 单元封装了系统启动和维护所需的各种对象。 大多数单元都在所谓的单元配置文件中进行配置 - 纯文本 ini 风格的文件。
systemd
单元类型¶
systemd
定义了以下 11 种单元类型:
服务单元 启动和控制守护进程及其包含的进程。
套接字单元 封装系统中的本地 IPC 或网络套接字,对于基于套接字的激活很有用。
目标单元 用于对其他单元进行分组。 它们在启动过程中提供众所周知的同步点
设备单元 在 systemd
中公开内核设备,可用于实现基于设备的激活。
挂载单元 控制文件系统中的挂载点
自动挂载单元 提供自动挂载功能,用于按需挂载文件系统,以及并行启动。
计时器单元 用于基于计时器触发其他单元的激活。
交换单元 与挂载单元非常相似,并封装操作系统的内存交换分区或文件。
路径单元 当文件系统对象发生变化或被修改时,可以激活其他服务。
切片单元 可用于将管理系统进程 (如服务和范围单元) 的单元在层次结构树中进行分组,以进行资源管理。
范围单元 与服务单元类似,但管理外部进程,而不是启动它们。
练习1¶
/usr/lib/systemd/systemd | PID=1¶
历史上 init 被称为许多名称,并采取了许多形式。
无论其名称或实现如何,init (或其等效项) 通常被称为所有进程之母。
“init” 的手册页将其称为所有进程的父进程。 按照惯例,内核执行的第一个程序或进程始终具有进程 ID 1。 一旦第一个进程运行,它就会继续启动其他服务、守护进程、进程、程序等等。
探索第一个系统进程¶
注意
在以下练习中,将 PID 替换为进程 ID 号。
以任何用户身份登录系统。查询 /proc/PID/comm 虚拟文件系统路径,并找出 ID 为 1 的进程的名称。键入
[root@localhost ~]# cat /proc/1/comm systemd
运行
ls
命令以查看 /proc/PID/exe 虚拟文件系统路径,并查看 ID 为 1 的进程背后的可执行文件的名称和路径。键入[root@localhost ~]# ls -l /proc/1/exe lrwxrwxrwx 1 root root 0 Oct 5 23:56 /proc/1/exe -> /usr/lib/systemd/systemd
尝试使用
ps
命令找出 PID 背后的进程或程序的名称。键入[root@localhost ~]# ps -p 1 -o comm= systemd
使用
ps
命令查看 PID 1 背后的进程或程序的完整路径和任何命令行参数。键入[root@localhost ~]# ps -p 1 -o args= /usr/lib/systemd/systemd --switched-root --system --deserialize 16
要检查所有进程之母(传统上称为 init)实际上是否为 systemd,请使用
ls
确认init
是指向systemd
二进制文件的符号链接。键入[root@localhost ~]# ls -l /usr/sbin/init lrwxrwxrwx. 1 root root 22 Aug 8 15:33 /usr/sbin/init -> ../lib/systemd/systemd
使用
pstree
命令显示系统进程的树状视图。键入[root@localhost ~]# pstree --show-pids
练习 2¶
systemd
目标 (RUNLEVELS)¶
systemd
定义并依赖于许多不同的目标来管理系统。在本练习中,我们将重点介绍五个主要目标中的五个。本节中探讨的五个主要目标列出如下
- poweroff.target
- rescue.target
- multi-user.target - 以完整的多用户支持引导系统,没有图形环境
- graphical.target - 以网络、多用户支持和显示管理器引导系统
- reboot.target
提示
目标单元在经典的 SysV init 系统中替换 SysV 运行级别。
要管理 systemd 目标¶
列出服务器上所有(活动 + 非活动 + 失败)可用目标。
[root@localhost ~]# systemctl list-units --type target --all
仅列出当前活动的目标。键入
[root@localhost ~]# systemctl list-units -t target
使用
systemctl
命令查看/获取系统配置为引导进入的默认目标的名称。键入[root@localhost ~]# systemctl get-default multi-user.target
查看默认目标 (multi-user.target) 的单元文件的內容。键入
[root@localhost ~]# systemctl cat multi-user.target # /usr/lib/systemd/system/multi-user.target ........ [Unit] Description=Multi-User System Documentation=man:systemd.special(7) Requires=basic.target Conflicts=rescue.service rescue.target After=basic.target rescue.service rescue.target AllowIsolate=yes
请注意
multi-user.target
单元中配置的一些属性及其值。例如 - Description、Documentation、Requires、After 等属性。basic.target
单元列为multi-user.target
的Requires
属性的值。查看 basic.target 的单元文件。键入[root@localhost ~]# systemctl cat multi-user.target # /usr/lib/systemd/system/basic.target [Unit] Description=Basic System Documentation=man:systemd.special(7) Requires=sysinit.target Wants=sockets.target timers.target paths.target slices.target After=sysinit.target sockets.target paths.target slices.target tmp.mount RequiresMountsFor=/var /var/tmp
systemctl cat
命令只显示给定单元的部分属性和值。要查看目标单元所有属性和值的转储,请使用 show 子命令。show
命令还将显示底层属性。显示 multi-user.target 的所有属性,键入[root@localhost ~]# systemctl show multi-user.target
从 multi-user.target 单元中长属性列表中过滤掉 Id、Requires 和 Description 属性。键入
[root@localhost ~]# systemctl --no-pager show \ --property Id,Requires,Description multi-user.target Id=multi-user.target Requires=basic.target Description=Multi-User System
查看 multi-user.target 启动时调用的服务和资源。换句话说,显示 multi-user.target “需要”什么。键入
[root@localhost ~]# systemctl show --no-pager -p "Wants" multi-user.target Wants=irqbalance.service sshd.service..... ...<SNIP>...
使用
ls
和file
命令来了解传统的init
程序与systemd
程序的关系。键入[root@localhost ~]# ls -l /usr/sbin/init && file /usr/sbin/init lrwxrwxrwx. 1 root root 22 Aug 8 15:33 /usr/sbin/init -> ../lib/systemd/systemd /usr/sbin/init: symbolic link to ../lib/systemd/systemd
要更改默认引导目标¶
设置/更改系统引导进入的默认目标。使用
systemctl set-default
命令将默认目标更改为graphical.target
。键入[root@localhost ~]# systemctl set-default graphical.target
检查新设置的引导目标是否处于活动状态。键入
[root@localhost ~]# systemctl is-active graphical.target inactive
请注意,即使它被设置为默认值,输出显示目标也没有处于活动状态!
要强制系统立即切换到并使用给定的目标,您必须使用
isolate
子命令。键入[root@localhost ~]# systemctl isolate graphical.target
警告
如果使用不当,systemctl isolate 命令可能很危险。这是因为它将立即停止在新目标中未启用的进程,可能包括您当前使用的图形环境或终端!
再次检查
graphical.target
是否正在使用并且处于活动状态。查询并查看
graphical.target
“需要”的其他服务或资源。问题
multi-user.target 和 graphical.target “需要”之间的主要区别是什么?
由于您的系统运行着服务器级操作系统发行版,其中完整的图形桌面环境可能不可取,因此将系统切换回更合适的 multi-user.target。键入
[root@localhost ~]# systemctl isolate multi-user
将默认系统启动目标设置/更改回 multi-user.target。
运行一个快速(和额外的)手动检查,以查看 default.target 符号链接指向哪个目标,方法是运行
[root@localhost ~]# ls -l /etc/systemd/system/default.target
练习 3¶
本节中的练习将向您展示如何配置可能需要随系统自动启动的系统/用户进程和守护进程(也称为服务)。
要查看服务状态¶
以 root 用户身份登录时,列出所有类型为服务的 systemd 单元。键入
root@localhost ~]# systemctl list-units -t service -all
这将显示活动和已加载但处于非活动状态的单元的完整列表。
查看具有服务类型的活动
systemd
单元列表。[root@localhost ~]# systemctl list-units --state=active --type service UNIT LOAD ACTIVE SUB DESCRIPTION atd.service loaded active running Job spooling tools auditd.service loaded active running Security Auditing Service chronyd.service loaded active running NTP client/server crond.service loaded active running Command Scheduler dbus.service loaded active running D-Bus System Message Bus firewalld.service loaded active running firewalld - dynamic firewall daemon ...<SNIP>...
缩小范围并详细了解上一个输出中其中一个服务的配置,即 crond.service。键入
[root@localhost ~]# systemctl cat crond.service
检查
crond.service
是否配置为在系统启动时自动启动。键入[root@localhost ~]# systemctl is-enabled crond.service enabled
查看
crond.service
服务的实时状态。键入[root@localhost ~]# systemctl status crond.service
输出将默认包含最新的 10 个日志行/条目/日志。
查看
crond.service
的状态并抑制显示任何日志行。键入[root@localhost ~]# systemctl -n 0 status crond.service
查看 sshd.service 的状态。
问题
查看
firewalld.service
的状态。firewalld.service
单元是什么?
要停止服务¶
仍在以具有管理权限的用户身份登录时,使用
pgrep
命令查看crond
进程是否出现在系统上运行的进程列表中。[root@localhost ~]# pgrep -a crond 313274 /usr/sbin/crond -n
如果找到匹配的进程名称,
pgrep
命令应该找到并列出crond
的 PID。使用
systemctl
停止crond.service
单元。键入[root@localhost ~]# systemctl stop crond.service
该命令应完成而没有任何输出。
使用
systemctl
查看crond.service
的状态,以查看更改的效果。再次使用
pgrep
查看crond
进程是否仍出现在进程列表中。
要启动服务¶
以管理用户帐户登录。使用
pgrep
命令查看系统上运行的进程列表中是否出现crond
进程。[root@localhost ~]# pgrep -a crond
如果
pgrep
找到匹配的进程名称,它将列出crond
的 PID。使用
systemctl
启动crond.service
单元。键入[root@localhost ~]# systemctl start crond.service
该命令应完成而没有任何输出或可见反馈。
使用
systemctl
查看crond.service
的状态,以查看更改的效果。键入[root@localhost ~]# systemctl -n 0 status crond.service ● crond.service - Command Scheduler Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2023-10-16 11:38:04 EDT; 54s ago Main PID: 313451 (crond) Tasks: 1 (limit: 48282) Memory: 1000.0K CGroup: /system.slice/crond.service └─313451 /usr/sbin/crond -n
问题
从您系统上
systemctl
状态命令的输出中,crond
的 PID 是什么?类似地再次使用
pgrep
查看crond
进程是否现在出现在进程列表中。将 pgrep 显示的 PID 与之前的systemctl
状态crond.service
中显示的 PID 进行比较。[root@localhost ~]# systemctl is-enabled crond.service enabled
要重新启动服务¶
对于许多服务/守护进程,每当对其底层配置文件进行更改时,都需要重新启动或重新加载正在运行的服务/守护进程。这样做是为了使给定的进程/服务/守护进程应用最新的配置更改。
查看 crond.service 的状态。键入
[root@localhost ~]# systemctl -n 0 status crond.service
在输出中,记下
crond
的 PID。运行
systemctl restart
以重新启动crond.service
。键入[root@localhost ~]# systemctl -n 0 status crond.service
该命令应完成而没有任何输出或可见反馈。
再次检查
crond.service
的状态。将最新的 PID 与您在步骤 1 中记下的 PID 进行比较。使用
systemctl
检查crond.service
当前是否处于活动状态。键入[root@localhost ~]# systemctl is-active crond.service active
问题
为什么您认为每次重新启动服务时 PID 都不同?
提示
旧式经典服务命令的功能已被移植到系统d 管理的系统上,以无缝工作。您可以使用以下服务命令来停止、启动、重新启动和查看
smartd
服务的状态。# service smartd status # service smartd stop # service smartd start # service smartd restart
要禁用服务¶
使用
systemctl
检查crond.service
是否已启用以在系统启动时自动启动。键入[root@localhost ~]# systemctl is-enabled crond.service enabled
示例输出显示它是。
禁用
crond.service
的自动启动。键入[root@localhost ~]# systemctl disable crond.service Removed /etc/systemd/system/multi-user.target.wants/crond.service.
再次运行
systemctl is-enabled
命令以查看更改的效果。问题
在您需要远程管理的服务器上,为什么要禁止像
sshd.service
这样的服务在系统启动时自动启动?
要确保禁用(屏蔽)服务¶
即使 systemctl disable
命令可用于禁用服务,如您在前面的练习中所见,其他 systemd
单元(进程、服务、守护进程等)可以在必要时偷偷地重新启用禁用的服务。当一个服务依赖于另一个(已禁用)服务时,就会发生这种情况。
您应该屏蔽该服务以确保禁用 systemd
服务单元并防止意外重新激活。
使用
systemctl
屏蔽crond.service
并防止任何不希望的重新激活,键入[root@localhost ~]# systemctl mask crond.service Created symlink /etc/systemd/system/crond.service → /dev/null.
运行
systemctl is-enabled
命令以查看更改的效果。[root@localhost ~]# systemctl is-enabled crond.service masked
要撤消更改并取消屏蔽
crond.service
,请使用systemctl unmask
命令,方法是运行[root@localhost ~]# systemctl unmask crond.service Removed /etc/systemd/system/crond.service.
要启用服务¶
使用
systemctl
检查crond.service
单元的状态。键入[root@localhost ~]# systemctl status crond.service
该服务应仍处于停止状态。
使用
systemctl enable
命令启用crond.service
以进行自动启动。键入[root@localhost ~]# systemctl enable crond.service Created symlink /etc/systemd/system/multi-user.target.wants/crond.service → /usr/lib/systemd/system/crond.service.
再次使用
systemctl
检查crond.service
是否处于活动状态。键入[root@localhost ~]# systemctl is-active crond.service inactive
问题
您刚刚启用了
crond.service
。为什么它没有运行或在之前的命令中没有列为活动状态?使用
systemctl enable
命令的稍微不同的变体来启用crond.service
并立即启动运行的守护进程。键入[root@localhost ~]# systemctl --now enable crond.service
检查
crond.service
是否现在处于活动状态。键入[root@localhost ~]# systemctl is-active crond.service active
使用
systemctl
确保crond.service
已启动、正在运行并已启用以进行自动启动。
作者:瓦莱·索因卡
贡献者:史蒂文·斯宾塞、甘娜·日尔诺娃