Linux 系统、内核及 systemd 服务等相关知识
一、系统启动流程
1、硬件初始化
UEFi或BIOS初始化,运行POST开机自检;
按预设的引导顺序选择启动设备,一般为BIOS+MBR 架构:读取硬盘的 MBR(主引导记录),获取引导加载程序的位置;
2、引导加载程序(grub2)
grub2 解析并加载装载程序的配置文件:/boot/grub2/grub.cfg;
grub2 根据配置指定的内核路径,将 Linux 内核文件从 /boot 分区读取到内存中。内核将初始化硬件驱动并管理系统资源;
grub2 加载配置对应的临时根文件系统(initramfs,包含了根分区挂载所需的驱动,可以实现根文件系统的挂载);
grub2 将控制权移交给内核;
3、内核初始化
内核自检并初始化所有已识别的硬件(如网卡、磁盘等);
核心解压:内核将 initramfs 解压并挂载为临时根文件系统;
在 initramfs 中找到并执行 systemd 程序开始进行系统初始化,其PID 为1(centos7 之后已用systemd代替 init,init 是 systemd 的软链接);
4、系统初始化(systemd 初始化)
systemd 首先读取 target配置(/etc/systemd/system/default.target),确定系统默认运行级别;
systemd 启动 sysinit.target 初始化系统(如加载模块、设置主机名等);
执行根切换,从 initramfs 根文件系统切换到磁盘根目录,卸载 initramfs ;
systemd 启动 local-fs.target 挂载所有的本地文件系统(如 /home,/var等);
systemd 启动 basic.target 准备操作系统(系统初始化的核心功能,如初始化网络等,为后续 multi-user.target 提供基础环境);
systemd 继续启动 multi-user.target 下的本机与服务器服务;
systemd 执行 multi-user.target 下的 /etc/rc.d/rc.local;
systemd 执行 multi-user.target 下的 getty.target 及登录服务 sshd.service,为终端提供登录界面,等待用户登录;
若为图形模式,systemd 执行 graphical.target 需要的服务,显示图形登录界面;
二、内核设计流派及特点
设计流派 | 核心思想 | 典型例子 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|---|
单内核(Monolithic Kernel) | 所有核心功能(进程管理、内存管理、文件系统、设备驱动等)集中在同一内核空间,通过函数调用直接交互。 | Linux、传统 Unix(如 Solaris)、FreeBSD | 1. 功能间通信效率极高(无进程间通信开销); 2. 实现简单,开发门槛较低; 3. 适合对性能要求高的场景。 | 1. 模块耦合度高,一个模块故障可能导致整个内核崩溃; 2. 扩展性差,新增功能需重新编译或加载内核模块; 3. 安全性依赖整体设计,单点漏洞影响范围大。 | 通用操作系统(服务器、PC)、嵌入式系统(追求性能) |
微内核(Microkernel) | 内核仅保留最核心功能(进程间通信 IPC、地址空间管理、线程调度),其他功能(文件系统、设备驱动、网络协议)作为 “用户态服务进程” 运行。 | Minix、QNX、L4 系列(如 seL4) | 1. 模块化极强,服务进程独立运行,单个服务故障不影响内核; 2. 可靠性、安全性高(内核攻击面小); 3. 易于扩展和维护(新增服务无需修改内核)。 | 1. 服务间依赖 IPC 通信,开销较大(上下文切换、消息传递),性能可能降低; 2. 设计复杂,需处理服务间依赖和通信协议。 | 高可靠性场景(工业控制、车载系统、航空航天) |
混合内核(Hybrid Kernel) | 融合单内核与微内核优点:核心功能(如调度、内存管理)保留在内核空间,非核心功能(如文件系统)部分放内核空间、部分放用户空间,平衡效率与模块化。 | Windows NT/10、Mac OS X(XNU)、Linux(模块化扩展后) | 1. 关键路径(如进程调度)效率接近单内核; 2. 非核心功能可独立扩展,降低整体耦合度; 3. 兼顾性能与可靠性。 | 1. 设计复杂,需精细划分内核 / 用户态功能边界; 2. 部分模块仍在内核空间,故障可能影响整体。 | 桌面操作系统(Windows、macOS)、兼顾性能与扩展性的场景 |
外核(Exokernel) | 内核仅负责 “硬件资源保护与分配”(如 CPU 时间、内存页、I/O 端口),应用程序通过 “库操作系统(LibOS)” 直接管理分配到的资源,最大限度释放硬件灵活性。 | MIT Exokernel、Nemesis | 1. 应用程序可定制资源管理策略,适合特殊场景(如高性能计算、实时系统); 2. 资源利用率极高。 | 1. 开发复杂度极高(应用需处理底层资源管理); 2. 兼容性差,难以支持通用应用。 | 专用高性能计算、定制化嵌入式系统 |
三、systemd 服务
从 CentOS 7 版本之后开始用 systemd 实现 init 进程,系统启动和服务器守护进程管理器,负责在系统启动或运行时,激活系统资源,服务器进程和其它进程。
1、文件位置
/etc/systemd/system/:用户自定义或修改的服务配置(推荐在此目录添加自定义服务)。
/run/systemd/system/:运行时生成的临时服务配置(重启后可能丢失)。
/usr/lib/systemd/system/(或 /lib/systemd/system/):软件包默认安装的服务配置(如 sshd.service、nginx.service)。
2、控制单元
在 systemd 中,unit是一个基本概念,表示一个系统功能或服务。unit表示不同类型的systemd对象,systemd会根据配置文件和设置,启动各种units,包括服务(service)、设备(device)、挂载点(mount)、监听(socket)等。每个unit都有一个名称和一个类型,systemd使用依赖关系来确保正确的启动顺序。
常见Unit类型说明
单元类型(Type) | 文件扩展名 | 核心定义 | 主要作用 | 示例 |
---|---|---|---|---|
service | .service | 管理后台服务进程的单元 | 控制服务的启动、停止、重启、重载等全生命周期(如 Web 服务、数据库服务) | sshd.service 、nginx.service |
target | .target | 组织和关联其他单元的 “目标单元”,类似传统运行级别 | 通过依赖关系整合单元,形成特定系统状态(如多用户模式、图形界面模式) | multi-user.target 、graphical.target |
socket | .socket | 管理进程间通信的套接字(TCP/UDP 端口、UNIX 域套接字) | 支持 “套接字激活”,有连接 / 请求时自动启动对应服务,减少资源占用 | sshd.socket 、nginx.socket |
mount | .mount | 管理文件系统挂载的单元 | 控制挂载时机和参数(替代 /etc/fstab 的部分功能) | home.mount 、mnt_data.mount |
automount | .automount | 实现文件系统 “按需自动挂载” 的单元,依赖 mount 单元 | 访问目录时自动挂载,闲置后自动卸载(适合不常用分区 / 网络存储) | mnt_backup.automount |
timer | .timer | 实现定时任务或周期性任务的单元 | 按时间规则触发其他单元(通常是 service ),替代传统 cron 部分功能 | logrotate.timer 、backup.timer |
path | .path | 监控文件 / 目录变化的单元 | 当文件 / 目录发生指定变化(如创建、修改)时,触发对应单元(如重载服务) | nginx-reload.path |
slice | .slice | 管理进程资源分配(CPU、内存等)的单元 | 实现进程资源隔离,限制分组进程的资源使用上限 | user-1000.slice 、system-nginx.slice |
scope | .scope | 管理临时进程组的单元(通常动态创建,非手动配置) | 跟踪非 service 单元的临时进程,便于统一管理其生命周期 | 由 systemd-run 生成的临时进程组 |
3、服务管理
命令格式:
systemctl COMMAND name.service [name2.service] ...
service COMMAND name
常用命令:
操作类型 | systemctl 命令 | service /chkconfig 命令 |
---|---|---|
启动服务 | systemctl start name1.service [name2.service] ... | service name start |
停止服务 | systemctl stop name.service | service name stop |
重启服务 | systemctl restart name.service | service name restart |
查看状态 | systemctl status name.service | service name status |
禁止服务启动(屏蔽) | systemctl mask name.service | |
恢复可启动(取消屏蔽) | systemctl unmask name.service | |
当前是否是启动状态 | systemctl is-active name.service | |
查看 service 服务脚本内容 | systemctl cat name.service | |
查看所有已经激活的服务 | systemctl list-units --type service 或 systemctl list-units -t service | |
查看所有服务 | systemctl list-units --type service --all 或 systemctl list-units -t service -a | |
设定服务开机启动 | systemctl enable name.service | chkconfig name on |
设定服务开机禁止启动 | systemctl disable name.service | chkconfig name off |
查看所有服务开机启动状态 | systemctl list-unit-files --type service --all 或 systemctl list-unit-files -t service -a | chkconfig --list |
查看服务在不同运行级别下的启用禁用 | ls /etc/systemd/system/*.wants/name.service | chkconfig --list name |
查看服务是否开机自启 | systemctl is-enabled name.service | |
列出失败的服务 | systemctl --failed --type=service | |
开机启动并立即启动 | systemctl enable --now name.service | |
开机禁用并立即禁用 | systemctl disable --now name.service | |
查看服务的依赖 | systemctl list-dependencies name.service | |
杀进程 | systemctl kill unitname |
常用快捷模式切换:
切换至救援模式:systemctl rescue
切换至紧急模式:systemctl emergency
关机:systemctl halt|poweroff
重启:systemctl reboot
挂起:systemctl suspend
休眠:systemctl hibernate
休眠并挂起:systemctl hybrid-sleep
命令示例:
查看服务运行状态
停止服务
启动服务
修改服务脚本(脚本标题由“Command Scheduler”变更为“Regular background program processing daemon”)
查看是否是开机启动
禁用开机启动
设为开机启动,并且立即启动
4、配置结构解读
service unit file文件通常由三部分组成:[Unit]、[Service]、[Install]。
框架示例:
[Unit]
# 服务元数据、依赖关系等[Service]
# 服务运行参数(启动命令、用户、重启策略等)[Install]
# 服务安装配置(开机自启关联的目标等)
[Unit] :元数据与依赖管理
参数 | 作用说明 |
---|---|
Description | 服务的简短描述(如 Description=OpenSSH server )。 |
Documentation | 服务文档地址(如 Documentation=man:sshd(8) )。 |
After | 定义服务的启动顺序:当前服务在指定服务 / 目标之后启动(如 After=network.target 表示在网络启动后启动)。 |
Before | 与 After 相反:当前服务在指定服务之前启动(如 Before=nginx.service )。 |
Requires | 强依赖:依赖的服务必须启动,若依赖服务启动失败,当前服务也会失败(如 Requires=dbus.service )。 |
Wants | 弱依赖:依赖的服务尽量启动,若依赖服务启动失败,当前服务仍可继续启动(推荐优先使用,如 Wants=network-online.target )。 |
Conflicts | 冲突关系:若指定服务启动,当前服务必须停止(如 Conflicts=firewalld.service )。 |
[Service] :服务运行核心配置
参数 | 作用说明 |
---|---|
Type | 服务类型(决定 systemd 如何判断服务是否启动成功): - simple (默认):服务启动后直接在前台运行,无需 fork 子进程;- forking :服务启动后会 fork 子进程,父进程退出(传统后台服务常用,如 sshd );- oneshot :服务一次性执行完就退出(如初始化脚本,需配合 RemainAfterExit=yes 保持 “激活” 状态);- notify :服务启动后通过 sd_notify() 函数通知 systemd 已就绪(如 nginx 部分版本)。 |
ExecStart | 启动服务的命令(必填),如 ExecStart=/usr/sbin/sshd -D 。 |
ExecStop | 停止服务的命令(可选),如 ExecStop=/bin/kill $MAINPID ($MAINPID 为服务主进程 ID)。 |
ExecReload | 重载服务配置的命令(可选),如 ExecReload=/bin/kill -HUP $MAINPID (发送 HUP 信号重载)。 |
User /Group | 服务运行的用户 / 组(默认 root),如 User=nginx 表示以 nginx 用户运行。 |
WorkingDirectory | 服务运行的工作目录,如 WorkingDirectory=/var/www 。 |
Environment | 设置环境变量,如 Environment="PORT=8080" "LOG_LEVEL=info" 。 |
EnvironmentFile | 从文件加载环境变量(文件需绝对路径),如 EnvironmentFile=/etc/sysconfig/nginx 。 |
Restart | 服务退出后是否重启: - no (默认):不重启;- on-failure :非 0 退出码时重启;- always :无论退出码如何都重启;- on-abnormal :意外退出(如被信号杀死)时重启。 |
RestartSec | 重启服务前的等待时间(秒),如 RestartSec=5 表示失败后等待 5 秒再重启。 |
LimitNOFILE | 服务可打开的最大文件描述符数(突破系统限制),如 LimitNOFILE=65535 。 |
[Install] :服务安装与自启配置
参数 | 作用说明 |
---|---|
WantedBy | 服务被哪个目标(target)“需要”:启用服务时,会在目标的 .wants 目录创建软链接,实现开机自启。常用目标: multi-user.target (多用户命令行模式,服务器常用)、graphical.target (图形界面模式)。示例: WantedBy=multi-user.target 表示服务随多用户模式启动。 |
RequiredBy | 与 WantedBy 类似,但为 “强依赖”:若目标启动,服务必须启动(较少用)。 |
Alias | 服务的别名,启用 / 禁用时可使用别名,如 Alias=my-service 。 |
对于新创建的 unit 文件,或者修改了的 unit 文件,要通知 systemd 重载此配置文件(systemctl daemon-reload),或者选择重启系统。