教程 rockylinux tutorial

系统服务管理(systemd)

systemd 是现代 Linux 发行版(包括 Rocky Linux)中默认的初始化系统和服务管理器。它负责在系统启动时启动系统服务,管理运行中的服务,并在系统关闭时正确终止它们。本教程将详细介绍如何在 Rocky Linux 中使用 systemd 管理系统服务,包括服务的启动、停止、重启、状态查询和配置等内容。

systemd 概述

systemd 基础概念

systemd 是一个系统和服务管理器,设计用于替代传统的 SysV init 和 Upstart 初始化系统。它的主要目标是提供更快速的启动速度、更好的并行化任务处理能力和更强大的服务管理功能。

systemd 的核心概念包括:

  • 单元(Units):systemd 管理的基本对象,可以是服务、套接字、挂载点等
  • 服务(Services):长时间运行的进程,如网络服务、数据库等
  • 目标(Targets):类似于传统运行级别的概念,定义了系统的特定运行状态
  • 依赖关系:控制服务的启动顺序和依赖条件
  • 计时器(Timers):替代传统的 cron 任务的定时执行机制

systemd 单元类型

systemd 支持多种类型的单元,每种类型用于管理不同的系统资源:

单元类型 文件名后缀 描述
service .service 系统服务
socket .socket 网络套接字或 IPC 套接字
device .device 设备文件
mount .mount 文件系统挂载点
automount .automount 自动挂载点
swap .swap 交换分区
target .target 目标(类似运行级别)
path .path 文件系统路径
timer .timer 定时器(替代 cron)
slice .slice 资源控制单元
scope .scope 外部创建的进程组

基本服务管理命令

查看服务状态

bash
# 查看单个服务的状态
systemctl status service-name.service

# 示例
systemctl status sshd.service
systemctl status nginx.service

# 可以省略 .service 后缀
systemctl status sshd

# 查看所有服务状态
systemctl list-units --type=service

# 查看所有已启动的服务
systemctl list-units --type=service --state=running

# 查看所有已安装但未运行的服务
systemctl list-units --type=service --state=inactive

控制服务

bash
# 启动服务
systemctl start service-name

# 停止服务
systemctl stop service-name

# 重启服务
systemctl restart service-name

# 重新加载服务配置(不中断服务)
systemctl reload service-name

# 强制重新加载配置并重启服务
systemctl reload-or-restart service-name

# 条件性重启服务(仅当服务正在运行时)
systemctl try-restart service-name

# 暂停服务(挂起)
systemctl suspend service-name

# 恢复暂停的服务
systemctl resume service-name

启用和禁用服务

bash
# 启用服务(系统启动时自动启动)
systemctl enable service-name

# 禁用服务(系统启动时不自动启动)
systemctl disable service-name

# 查看服务是否启用
systemctl is-enabled service-name

# 启用服务但不立即启动
systemctl enable --now service-name

# 禁用服务并立即停止
systemctl disable --now service-name

服务依赖关系

bash
# 查看服务依赖
systemctl list-dependencies service-name

# 查看哪些服务依赖于指定服务
systemctl list-dependencies --reverse service-name

# 示例:查看 SSH 服务依赖
systemctl list-dependencies sshd

系统运行级别(Targets)

运行级别与 Target

systemd 使用 Targets 概念替代了传统的运行级别。以下是主要的 Targets 及其对应的传统运行级别:

systemd Target 传统运行级别 描述
poweroff.target 0 关闭系统
rescue.target 1 单用户模式
multi-user.target 3 多用户文本模式
graphical.target 5 图形用户界面模式
reboot.target 6 重启系统

管理运行级别

bash
# 查看当前运行的 Target
systemctl get-default

# 切换到 multi-user 运行级别
systemctl isolate multi-user.target

# 切换到图形界面运行级别
systemctl isolate graphical.target

# 设置默认运行级别(下次启动时生效)
systemctl set-default multi-user.target
systemctl set-default graphical.target

# 查看可用的 Targets
systemctl list-units --type=target

救援模式和紧急模式

bash
# 进入救援模式
systemctl rescue

# 进入紧急模式
systemctl emergency

系统管理命令

系统状态和控制

bash
# 查看系统运行状态
systemctl status

# 关闭系统
systemctl poweroff
systemctl halt
systemctl shutdown -h now

# 重启系统
systemctl reboot
systemctl shutdown -r now

# 暂停系统
systemctl suspend

# 休眠系统
systemctl hibernate

# 混合休眠(保存到磁盘并挂起)
systemctl hybrid-sleep

系统日志查看

bash
# 查看系统日志
journalctl

# 查看特定服务的日志
journalctl -u service-name

# 实时查看日志
sudo journalctl -f

# 查看特定时间段的日志
journalctl --since "2023-05-01 10:00:00" --until "2023-05-01 12:00:00"

# 查看最近的日志
sudo journalctl -n 100

# 按优先级过滤日志
sudo journalctl -p err..emerg

服务配置文件

服务配置文件位置

systemd 服务配置文件主要存放在以下位置:

  1. /usr/lib/systemd/system/:系统默认服务文件,由软件包管理器维护
  2. /etc/systemd/system/:用户自定义或修改的服务文件,优先级高于 /usr/lib/systemd/system/
  3. /run/systemd/system/:运行时生成的服务文件,重启后会丢失

服务文件结构

服务文件通常包含以下部分:

ini
[Unit]
Description=描述信息
After=依赖的服务或目标
Requires=必须运行的服务
Wants=建议运行的服务

[Service]
Type=服务类型(simple, forking, oneshot, dbus, notify, idle)
ExecStart=启动命令
ExecStop=停止命令
ExecReload=重新加载配置命令
User=运行服务的用户
Group=运行服务的组
WorkingDirectory=工作目录
Restart=重启策略(no, on-success, on-failure, on-abnormal, on-watchdog, on-abort, always)
RestartSec=重启间隔时间

[Install]
WantedBy=目标(如 multi-user.target)

常用服务类型

  • simple:默认类型,systemd 启动服务后继续执行后续操作
  • forking:服务启动后会创建子进程,父进程退出
  • oneshot:服务只执行一次,完成后退出
  • dbus:服务依赖 D-Bus 通信
  • notify:服务启动完成后会发送通知
  • idle:systemd 等待所有其他任务完成后才启动服务

创建和修改服务文件

创建自定义服务

下面是创建自定义服务的步骤:

  1. 创建服务文件:
bash
   sudo vim /etc/systemd/system/my-service.service
  1. 编写服务内容:
ini
   [Unit]
   Description=My Custom Service
   After=network.target
   
   [Service]
   Type=simple
   User=username
   ExecStart=/path/to/executable
   Restart=on-failure
   RestartSec=5s
   
   [Install]
   WantedBy=multi-user.target
  1. 重新加载 systemd 配置:
bash
   sudo systemctl daemon-reload
  1. 启动和启用服务:
bash
   sudo systemctl start my-service
   sudo systemctl enable my-service

修改现有服务

修改现有服务有两种方法:

  1. 直接修改服务文件(不推荐):
bash
   sudo vim /usr/lib/systemd/system/service-name.service
   sudo systemctl daemon-reload
   sudo systemctl restart service-name
  1. 创建服务覆盖目录(推荐):
bash
   sudo mkdir -p /etc/systemd/system/service-name.service.d/
   sudo vim /etc/systemd/system/service-name.service.d/override.conf

在 override.conf 中只包含要修改的部分,例如:

ini
   [Service]
   Restart=on-failure
   RestartSec=10s

然后重新加载并重启:

bash
   sudo systemctl daemon-reload
   sudo systemctl restart service-name

示例:创建 Python 应用服务

ini
[Unit]
Description=Python Web Application
After=network.target

[Service]
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/python3 app.py
Restart=on-failure
RestartSec=10
Environment=PYTHONPATH=/opt/myapp
Environment=APP_ENV=production

[Install]
WantedBy=multi-user.target

使用 systemctl 管理挂载点

查看和控制挂载点

bash
# 查看挂载点状态
systemctl list-units --type=mount

# 查看特定挂载点状态
systemctl status mount-point.mount

# 挂载文件系统
systemctl start mount-point.mount

# 卸载文件系统
systemctl stop mount-point.mount

# 重新挂载文件系统
systemctl reload mount-point.mount

创建自定义挂载单元

bash
# 创建挂载单元文件
sudo vim /etc/systemd/system/data.mount

示例挂载单元内容:

ini
[Unit]
Description=Data Mount Point

[Mount]
What=/dev/sdb1
Where=/mnt/data
Type=ext4
Options=defaults,noatime

[Install]
WantedBy=multi-user.target

启用并挂载:

bash
sudo systemctl daemon-reload
sudo systemctl enable data.mount --now

使用 systemd 定时器

systemd 定时器提供了比传统 cron 任务更灵活的调度机制。

创建定时器

  1. 创建服务文件:
bash
   sudo vim /etc/systemd/system/backup.service

内容:

ini
   [Unit]
   Description=Backup Service
   
   [Service]
   Type=oneshot
   ExecStart=/usr/local/bin/backup-script.sh
  1. 创建定时器文件:
bash
   sudo vim /etc/systemd/system/backup.timer

内容:

ini
   [Unit]
   Description=Run Backup Daily
   
   [Timer]
   OnCalendar=*-*-* 03:00:00  # 每天凌晨 3 点执行
   Persistent=true           # 系统启动后,如果错过执行时间则立即执行
   
   [Install]
   WantedBy=timers.target
  1. 启用定时器:
bash
   sudo systemctl daemon-reload
   sudo systemctl enable backup.timer --now

管理定时器

bash
# 查看所有定时器
systemctl list-timers

# 查看特定定时器状态
systemctl status backup.timer

# 启用定时器
systemctl enable timer-name.timer

# 禁用定时器
systemctl disable timer-name.timer

# 启动定时器(临时启用)
systemctl start timer-name.timer

# 停止定时器
systemctl stop timer-name.timer

高级 systemd 功能

资源控制(CGroup)

systemd 使用 Linux 控制组(CGroup)来管理和限制服务的资源使用。

bash
# 修改服务的资源限制
sudo mkdir -p /etc/systemd/system/service-name.service.d/
sudo vim /etc/systemd/system/service-name.service.d/resource.conf

示例资源限制配置:

ini
[Service]
# CPU 限制
CPUQuota=50%

# 内存限制
MemoryLimit=512M

# 进程数限制
TasksMax=100

重新加载配置:

bash
sudo systemctl daemon-reload
sudo systemctl restart service-name

环境变量

可以为服务设置环境变量,有几种方法:

  1. 直接在服务文件中设置:
ini
   [Service]
   Environment=VAR1=value1 VAR2=value2
  1. 使用环境文件:
ini
   [Service]
   EnvironmentFile=/path/to/environment/file
  1. 使用 systemctl 命令:
bash
   sudo systemctl set-environment VAR1=value1
   sudo systemctl unset-environment VAR1

安全增强

systemd 提供了多种安全功能来限制服务的权限:

ini
[Service]
# 安全上下文设置
PrivateTmp=true            # 使用私有临时目录
ProtectSystem=full         # 保护系统文件只读
ProtectHome=true           # 保护用户主目录
NoNewPrivileges=true       # 禁止提升权限
RestrictNamespaces=true    # 限制命名空间
SystemCallFilter=~@clock  # 过滤系统调用

systemd 日志管理

查看和管理日志

bash
# 查看所有日志(最新的在底部)
sudo journalctl

# 查看特定服务的日志
sudo journalctl -u service-name

# 实时查看日志
sudo journalctl -f

# 查看特定用户的日志
sudo journalctl _UID=1000

# 查看特定时间段的日志
sudo journalctl --since "2023-05-01" --until "2023-05-02"

# 按优先级过滤日志
sudo journalctl -p err

# 查看日志文件大小
sudo journalctl --disk-usage

# 清理日志(保留最新的 500MB)
sudo journalctl --vacuum-size=500M

# 清理指定日期之前的日志
sudo journalctl --vacuum-time=2weeks

配置 journald

journald 配置文件位于 /etc/systemd/journald.conf:

bash
sudo vim /etc/systemd/journald.conf

常用配置选项:

ini
[Journal]
# 持久化日志存储
Storage=persistent

# 日志文件大小限制
SystemMaxUse=500M

# 单个日志文件最大大小
SystemMaxFileSize=100M

# 日志保留时间
MaxFileSec=1month

# 压缩日志
Compress=yes

常见问题排查

服务无法启动

bash
# 查看服务详细状态和错误信息
systemctl status service-name

# 查看服务日志
sudo journalctl -u service-name --no-pager

# 检查服务文件语法
sudo systemd-analyze verify service-name.service

系统启动慢

bash
# 查看启动时间和各个服务的启动时间
systemd-analyze blame

# 查看启动关键路径
systemd-analyze critical-chain

# 生成启动图
systemd-analyze plot > boot.svg

服务依赖问题

bash
# 查看服务依赖图
systemd-analyze dot service-name | dot -Tsvg > service.svg

# 检查服务依赖关系
systemctl list-dependencies service-name

最佳实践

服务配置最佳实践

  1. 使用 Type=forking 还是 Type=simple

    • 对于传统的 fork 型服务,使用 Type=forking
    • 对于现代的前台运行服务,使用 Type=simple
  2. 设置合适的 Restart 策略

    • 对于关键服务,使用 Restart=always
    • 对于可能失败的服务,使用 Restart=on-failure
    • 对于一次性任务,使用 Restart=no
  3. 设置合理的超时时间

ini
   [Service]
   TimeoutStartSec=30
   TimeoutStopSec=10
  1. 添加安全限制
    • 使用 PrivateTmp=true 隔离临时文件
    • 使用 ProtectSystem=full 保护系统文件
    • 使用 NoNewPrivileges=true 防止权限提升

服务管理最佳实践

  1. 始终使用 systemctl 管理服务,避免使用 service 或 init.d 脚本

  2. 修改服务时使用覆盖目录,而不是直接修改原始服务文件

  3. 定期检查服务状态,确保关键服务正常运行

  4. 使用 systemd 定时器替代 cron 任务,获得更好的集成和日志记录

  5. 设置适当的资源限制,防止单个服务消耗过多系统资源

  6. 监控系统日志,及时发现服务问题

总结

systemd 是 Rocky Linux 中强大的系统和服务管理器,提供了比传统 init 系统更多的功能和更好的性能。通过本教程,您学习了如何使用 systemctl 命令管理服务,如何创建和修改服务文件,如何使用 Targets 管理系统运行状态,以及如何使用定时器执行定时任务。

systemd 的设计理念包括并行启动、按需激活服务、基于依赖的服务管理等,这些特性使系统启动更快,资源利用更高效。同时,systemd 还提供了丰富的安全功能,可以限制服务的权限和资源使用,提高系统安全性。

在实际使用中,遵循最佳实践,合理配置和管理服务,不仅可以确保系统稳定运行,还可以提高系统性能和安全性。掌握 systemd 的使用,是成为一名高效的 Rocky Linux 系统管理员的必备技能。