这是一个为期5天的详细Linux systemd学习计划。本计划从基础概念和日常操作入手,逐步深入到自定义服务、定时任务和性能分析,旨在让你系统性地掌握systemd的核心功能。
学习准备
- 环境: 一台安装了现代Linux发行版(如Ubuntu 18.04+, CentOS 7+, Debian 9+)的虚拟机或物理机。强烈建议使用虚拟机,因为一些操作(如更改默认target)可能会让你无法进入图形界面,在虚拟机中修复会更容易。
- 知识储备: 熟悉基本的Linux命令行操作(如
ls,cd,cat,sudo)和使用一个文本编辑器(如vim,nano)。 - 心态:
systemd功能强大但逻辑严谨。多动手实践,多看状态,多查日志是学习的关键。
学习计划概览
- 前3天 (核心内容): 掌握
systemd的日常使用、核心概念和自定义服务,足以应对80%的日常运维工作。 - 后2天 (进阶内容): 深入了解高级特性,如定时器、依赖关系和性能优化,让你成为更专业的
systemd使用者。
Day 1: 基础概念与日常服务管理
学习目标:
- 理解
systemd的作用和核心概念。 - 熟练掌握管理系统服务(启动、停止、重启、查看状态)的常用命令。
核心内容:
-
systemd 是什么?(理论部分)
- Init系统简介: 了解Linux系统的第一个进程(PID 1)的作用。
- 为什么是 systemd: 相比传统的 SysVinit 或 Upstart,
systemd提供了更快的启动速度(并行启动)、更强的依赖管理、统一的日志系统等优势。 - 核心概念 - Unit (单元):
systemd管理的一切资源都称为"单元"。- 了解最常见的单元类型:
service: 系统服务(最重要)target: 一组单元的集合,类似于"运行级别"socket: 套接字timer: 定时器path: 路径
-
systemctl- 你的总指挥棒 (实践部分)- 这是与
systemd交互最核心的命令。 - 管理服务生命周期: (以
sshd或nginx服务为例)- 启动服务:
sudo systemctl start sshd.service - 停止服务:
sudo systemctl stop sshd(后缀.service通常可以省略) - 重启服务:
sudo systemctl restart sshd - 重新加载配置:
sudo systemctl reload sshd(服务不中断,仅重新加载配置文件)
- 启动服务:
- 查看服务状态:
- 查看详细状态:
systemctl status sshd(这是最常用、最重要的排错命令,能看到服务是否运行、PID、日志摘要等) - 检查服务是否正在运行:
systemctl is-active sshd
- 查看详细状态:
- 管理开机自启:
- 设置开机自启:
sudo systemctl enable sshd - 禁止开机自启:
sudo systemctl disable sshd - 检查是否开机自启:
systemctl is-enabled sshd
- 设置开机自启:
- 屏蔽服务 (Mask):
sudo systemctl mask sshd(彻底禁用服务,任何方式都无法启动)sudo systemctl unmask sshd(取消屏蔽)
- 这是与
动手实践:
- 选择一个你系统上已安装的服务,如
sshd,crond,nginx或docker。 - 对该服务完整地练习
start,stop,restart,status命令,每次操作后都用status检查其状态变化。 - 练习
enable和disable,并通过is-enabled命令验证。重启虚拟机,确认enable的服务是否自启,disable的服务是否未启动。 - 列出系统中所有正在运行的服务:
systemctl list-units --type=service --state=running
Day 2: Unit 文件与 Target 管理
学习目标:
- 理解
systemdUnit 文件的结构和存放位置。 - 理解
target的概念以及如何切换系统运行级别。
核心内容:
- 深入 Unit 文件 (理论与实践)
- Unit 文件的位置:
systemd会按特定顺序查找 Unit 文件。/usr/lib/systemd/system/: 软件包安装的默认 Unit 文件。不要直接修改这里的文件。/etc/systemd/system/: 系统管理员配置和修改 Unit 文件的地方。这里的配置会覆盖上面目录的同名文件。
- Unit 文件结构: (以
sshd.service为例)- 使用
systemctl cat sshd查看其内容。 - 主要分为三个段:
[Unit]: 通用元数据,如描述 (Description=) 和依赖关系 (After=,Wants=)。[Service]: 服务专属配置,如启动命令 (ExecStart=)、重启策略 (Restart=)、运行用户 (User=)。[Install]: 安装信息,定义在enable时,该服务应被链接到哪个target(WantedBy=)。
- 使用
- Unit 文件的位置:
- Target - 运行模式的集合 (实践部分)
targetunit 用来组织和启动一组其他的 unit,是systemd中对"运行级别"的实现。- 常用 Targets:
multi-user.target: 多用户命令行模式(类似运行级别3)。graphical.target: 图形界面模式(类似运行级别5)。rescue.target: 救援模式。reboot.target,poweroff.target: 重启与关机。
- 管理 Target:
- 查看当前默认 target:
systemctl get-default - 设置默认 target:
sudo systemctl set-default multi-user.target(警告:在有图形界面的系统上执行此命令,下次重启将进入命令行模式!) - 切换到其他 target:
sudo systemctl isolate graphical.target(在命令行模式下执行此命令可启动图形界面)
- 查看当前默认 target:
动手实践:
- 使用
systemctl cat命令查看sshd.service和crond.service的 unit 文件内容,尝试理解每一行的含义。 - 在你的虚拟机中,执行
systemctl get-default查看当前的默认 target。 - 执行
sudo systemctl set-default multi-user.target。 - 执行
sudo reboot重启虚拟机,观察系统是否直接进入了命令行界面。 - 在命令行界面登录后,执行
sudo systemctl set-default graphical.target,再次重启,确认系统恢复到图形界面。
Day 3: 创建自定义 Service 与日志管理
学习目标:
- 能够为自己的应用程序或脚本编写一个简单的
systemdservice 文件。 - 掌握使用
journalctl查看和过滤系统日志。
核心内容:
-
编写你的第一个 Service (核心实践)
- 场景: 我们有一个简单的脚本,希望它能像系统服务一样在后台运行,并由
systemd管理。 - 步骤:
-
创建脚本: 在
/usr/local/bin下创建一个简单的脚本my_script.sh。bash#!/bin/bash while true; do echo "Hello from my_script! Logging at $(date)" sleep 10 done给它执行权限:
sudo chmod +x /usr/local/bin/my_script.sh -
创建 Unit 文件: 在
/etc/systemd/system/目录下创建my_app.service。ini[Unit] Description=My Simple Application Service After=network.target [Service] ExecStart=/usr/local/bin/my_script.sh Restart=always User=nobody Group=nobody [Install] WantedBy=multi-user.target -
通知 systemd: 创建或修改 Unit 文件后,必须 运行此命令使其生效:
sudo systemctl daemon-reload -
管理你的新服务: 现在你可以像管理其他服务一样管理它了!
sudo systemctl start my_appsystemctl status my_appsudo systemctl enable my_appsudo systemctl stop my_app
-
- 场景: 我们有一个简单的脚本,希望它能像系统服务一样在后台运行,并由
-
journalctl-systemd的日志管家 (实践部分)systemd有自己的日志系统journald,所有服务(包括自定义服务)的stdout和stderr都会被捕获到这里。- 常用命令:
- 查看所有日志(从旧到新):
journalctl - 反向查看所有日志(从新到旧):
journalctl -r - 实时跟踪日志:
journalctl -f(类似tail -f) - 查看特定服务的日志:
journalctl -u my_app.service - 结合
-f跟踪特定服务日志:journalctl -f -u my_app.service - 按时间过滤:
- 查看今天的所有日志:
journalctl --since "today" - 查看过去一小时的日志:
journalctl --since "1 hour ago"
- 查看今天的所有日志:
- 按优先级过滤(如错误):
journalctl -p err
- 查看所有日志(从旧到新):
动手实践:
- 完整地按照上述步骤,创建并运行你自己的
my_app.service。 - 使用
systemctl status检查服务是否正常运行。 - 使用
journalctl -u my_app.service查看你的脚本输出的 "Hello..." 日志。 - 停止服务,修改脚本中的
echo内容,然后重启服务,使用journalctl -f -u my_app实时观察日志变化。 - 尝试查看
sshd服务在过去一天的日志。
Day 4: 进阶 - 定时器与依赖管理
学习目标:
- 使用
systemd Timer替代cron创建定时任务。 - 理解 Unit 文件中
Wants,Requires,After,Before的含义。
核心内容:
-
Timer Units - 现代化的 Cron (实践部分)
systemdtimer 提供了比cron更灵活和强大的定时任务功能。一个定时任务由两个文件组成:.timer文件(定义何时运行)和.service文件(定义运行什么)。- 步骤:
-
创建 Service 文件: 创建
/etc/systemd/system/my_backup.service,定义要执行的任务。ini[Unit] Description=My Backup Service Logic [Service] Type=oneshot ExecStart=/bin/bash -c 'echo "Performing backup at $(date)" >> /tmp/backup.log'注意
Type=oneshot,表示这个服务执行完一个任务就退出。 -
创建 Timer 文件: 创建同名的
.timer文件/etc/systemd/system/my_backup.timer。ini[Unit] Description=Run my_backup.service every minute [Timer] OnBootSec=1min # 系统启动1分钟后执行一次 OnUnitActiveSec=1m # 服务上次执行成功后1分钟再次执行 # OnCalendar=*-*-* *:*:00 # 也可以用类似cron的日历格式 [Install] WantedBy=timers.target -
激活和管理:
sudo systemctl daemon-reload- 启动并自启 Timer:
sudo systemctl enable --now my_backup.timer - 查看所有 timers 状态:
systemctl list-timers --all
-
-
依赖关系指令 (理论部分)
- 排序依赖:
After=和Before=After=network.target: 表示本服务应该在network.target启动之后才启动。Before=sshd.service: 表示本服务应该在sshd.service启动之前启动。- 这只规定了启动顺序,没有强制依赖。
- 需求依赖:
Wants=和Requires=Wants=redis.service: 表示本服务希望redis.service也一起启动。如果redis启动失败,本服务不受影响。这是最常见的依赖。Requires=database.service: 表示本服务强依赖 于database.service。如果database启动失败,systemd将不会启动本服务。
- 排序依赖:
动手实践:
- 完整地创建
my_backup.service和my_backup.timer。 - 激活 timer 后,使用
systemctl list-timers和tail -f /tmp/backup.log来验证任务是否按时执行。 - 阅读你系统中
docker.service或nginx.service的 Unit 文件,分析它的After=和Wants=字段,理解它的启动依赖。
Day 5: 进阶 - 系统分析与用户服务
学习目标:
- 使用
systemd-analyze分析系统启动性能。 - 了解如何以普通用户身份运行
systemd服务。
核心内容:
-
系统性能分析 -
systemd-analyze(实践部分)systemd记录了详细的启动过程耗时,可以用systemd-analyze工具进行分析。- 常用命令:
- 查看总启动耗时:
systemd-analyze - 列出各服务启动耗时排行:
systemd-analyze blame(非常有用,可以快速找到拖慢启动速度的服务) - 生成启动过程的 SVG 矢量图:
systemd-analyze plot > /tmp/boot_plot.svg - 显示关键链 (critical chain):
systemd-analyze critical-chain(显示哪些服务阻塞了后续服务的启动)
- 查看总启动耗时:
-
用户级别的 systemd 服务 (理论与实践)
systemd不仅可以为系统(root)管理服务,也可以为每个登录用户管理服务。这对于运行一些用户级别的后台应用(如开发工具、同步客户端)非常有用。- 特点:
- Unit 文件放在
~/.config/systemd/user/目录下。 - 使用
systemctl --user命令进行管理(无需sudo)。 - 服务会随用户登录而启动,随用户退出而停止。
- Unit 文件放在
- 实践:
- 在
~/.config/systemd/user/目录下创建一个my_user_app.service文件。 - 内容与系统服务类似,但
[Install]部分通常是WantedBy=default.target。 - 使用
systemctl --user daemon-reload加载。 - 使用
systemctl --user start my_user_app启动。 - 使用
systemctl --user status my_user_app查看状态。
- 在
动手实践:
- 在你的系统上运行
systemd-analyze blame,看看哪个服务是启动最慢的"拖油瓶"。 - 尝试将 Day 3 创建的
my_app.service改造成一个用户服务,并放在用户目录下进行管理。注销再登录,看看服务是否自动启动。 - (选做)探索
systemd的其他组件,如logind(loginctl命令)、resolved(resolvectl命令)。
总结: 通过这 5 天的学习,你将从一个 systemd 的初学者成长为一个熟练的使用者。关键在于将理论与实践相结合,不断地通过 status 和 journalctl 来观察和验证你的操作。