云计算百科
云计算领域专业知识百科平台

Systemd 学习总结

儿时练功易,老来学艺难。

导航

  • 0 前言
  • 1 工具介绍
  • 2 配置结构
  • 3 Unit 实例
    • 3.0 通用块
      • 3.0.1 Unit 块参数
      • 3.0.2 Install 块参数
    • 3.1 Service
    • 3.2 Target
    • 3.3 Timer
    • 3.4 Path
    • 3.5 Slice
    • 3.5 Mount
    • 3.6 Automount
  • 4 命令管理
    • 4.1 systemctl 命令用法
    • 4.2 journalctl 命令用法
  • 5 杂七杂八

0、前言

当我们打开 Linux 主机以命令行模式或图形化模式进入系统之后,系统就已经为我们提供了很多的服务,如:打印服务、计划任务服务、邮件服务等等,那么这些服务是如何被启动起来的呢?在此之前我们先了解一下 Linux 主机的启动过程: 在这里插入图片描述

  • 点击主机开机按钮,CPU 开始加载固件程序(即 BIOS 上电自检),待加载完毕之后 BIOS 便获得了 CPU 的控制权,然后 BIOS 会去加载开机启动顺序中指定的系统入口点(安装系统的光驱、硬盘的入口点)。
  • 待 BIOS 加载了入口点处的引导装载程序 (GRUB2)之后,CPU 控制权此时便到了 GRUB2 的手里,GRUB2 接着开始加载硬盘中安装的 Linux 内核。
  • 待 Linux 内核初始化完成之后,CPU 的控制权此时便到了 Linux 内核手中,往后 CPU 的控制权便一直掌握在 Linux 内核手中。
  • 但 Linux 内核对于用户来说并不可直接被使用、而且也并未提供什么功能,于是它又雇佣了一个管家(init、systemd)并授予了一些权利,来代替它去做一些系统管理的事情。而这个管家便是 Linux 内核掌权之后启动的第一个外部程序,也是未来所有其它进程之父。
  • 早期 各 Linux 发行商为自家 Linux 内核配备的管家是 init 这个程序,该管家的特点是:(1)基于脚本式的方式去管理服务,服务的启动/停止/状态查看都是通过 /etc/init.d/ 下的 bash 脚本来实现的。(2)开机启动各种服务的时候,只能一个一个依序进行,不能够并行启动。(3)服务之间的依赖问题需要管理员手动处理。(4)系统环境切换依赖于 /etc/rc*.d/ 中的脚本。

    如今 各 Linux 发行商为自家 Linux 内核配备的管家基本都是 systemd 这个程序,该管家的特点是:(1)基于配置文件(服务单位 Unit )的方式去管理服务,服务的管理更灵活、更简单。(2)支持并行启动开机自启应用。(3)服务之间的依赖会自动检查,并自动唤醒。(4)兼容旧有的 init 服务脚本启动方式。

    由于如今的 Linux 使用的服务管理方式多是 Systemd,因此学会它还是很有必要的。

    注:Linxu 内核启动的第一个程序是 systemd,而 systemd 启动的第一个服务单元是 default.target,它一般被命令 systemctl set-default multi-user.target 链接到了 multi-user.target 或 graphical.target。

    当 systemd 启动任何服务单元 Unit 文件的时候,systemd 首先去启动参数 Requires 和目录 /etc/systemd/system/a.target.requires/ 关联的服务,然后再开始启动参数 Wants 和目录 /etc/systemd/system/a.target.want/ 关联的服务。

    systemd 找寻 default.target 单元文件时的目录查找顺序:

    /etc/systemd/system/default.target

    /run/systemd/system/default.target

    /usr/local/lib/systemd/system/default.target

    /usr/lib/systemd/system/default.target

    /lib/systemd/system/default.target

    1、工具介绍

    Systemd 是基于服务单位 Unit 来管理守护进程和系统资源的,它将这些服务单位 Unit 划分成了 service、target、timer、path、socket 等 12 种不同的类型,每种类型分别对应着不同的功能和应用场景以方便管理员使用。此外,Systemd 还维护着一个名为 journald 的日志系统来记录它所管理的服务在运行时产生的各种日志信息。 在这里插入图片描述

    如图所见,Systemd 在 Linux 系统中的地位很重要,因为它必须确保系统启动并准备就绪,所以它承担的事情也比较多,例如:

    • 它会启动所有你需要的后台服务,例如网络、打印、容器、数据库等。【后台服务管理】
    • 它会自动挂载所有不同的文件系统和磁盘,以便可以随时访问。【开机挂载】
    • 一旦进入图形提示符,它就会处理用户登录、息屏和关机。【用户登录与会话管理】
    • 它会自动清理临时垃圾文件,或者每天自动备份数据。【定时任务】
    • 它会实时收集并归档内核、系统服务以及各种软件打印出来的日志。【日志记录】

    2、配置结构

    Systemd 管理的服务所对应的服务单元 Unit 文件的存放路径如下(注:这些路径存在 优先级覆盖关系):

    目录路径作用与特点适用场景
    /etc/systemd/system/ 最高优先级。存放管理员手动创建或修改的单元文件,以及开机自启服务的软链接。 用户自定义服务、修改系统默认配置。
    /run/systemd/system/ 中等优先级。存放系统运行期间动态生成的临时单元文件(重启后丢弃)。 程序运行时临时产生的服务、挂载点。
    /lib/systemd/system/ (或 /usr/lib/systemd/system/) 最低优先级。存放通过软件包管理器(如 apt、dnf)安装的服务默认配置。 系统与软件自带的原始配置,请勿直接修改。

    此外,在修改单元配置文件时,官方建议不要直接在源文件(即 /usr/lib/systemd/system/* 中的单元文件)中进行修改,而是优先在 /etc/systemd/system/* 中进行修改。例如,如果你想额外修改 vsftpd.service 的话,则应该按如下方式处理:

    目录路径作用说明
    /usr/lib/systemd/system/vsftpd.service 官方释出的预设设定档,不要动。
    /etc/systemd/system/vsftpd.service.d/custom.conf 在 /etc/systemd/system 底下建立与设定档相同档名的目录,但是要加上 .d 的副档名。然后在该目录下建立设定档即可。另外,设定档最好附档名取名为 .conf 较佳! 在这个目录下的档案会“累加其他设定”进入 /usr/lib/systemd/system/vsftpd.service 内。
    /etc/systemd/system/vsftpd.service.wants/* 此目录内的档案为连结档,设定相依服务的连结。意思是启动了 vsftpd.service 之后,最好再加上这目录底下建议的服务。
    /etc/systemd/system/vsftpd.service.requires/* 此目录内的档案为连结档,设定相依服务的连结。意思是在启动 vsftpd.service 之前,需要事先启动哪些服务的意思。

    最终,当执行 systemctl start vsftpd.service 命令时,systemctl 会将以上 4 个目录文件中的配置信息都聚合起来形成一份运行时 service 服务单元去执行。不过这种用法个人觉得还是太麻烦,还不如直接拷贝一份源文件在 /etc/systemd/system/vsftpd.service 然后直接修改它来的容易。

    3、Unit 实例

    Systemd 所划分的 12 种 Unit 类型如下:

    Unit 类型文件后缀作用常见用途
    Service Unit .service 管理系统服务/进程 启动 nginx、docker、ssh
    Target Unit .target 管理一组 Unit 的集合 类似运行级别
    Timer Unit .timer 定时任务 替代 cron
    Path Unit .path 监控文件路径变化 文件变化触发任务
    Slice Unit .slice 管理资源分组 CPU/内存限制
    Mount Unit .mount 管理文件系统挂载 自动挂载磁盘
    Automount Unit .automount 按需挂载文件系统 延迟挂载
    Swap Unit .swap 管理 swap 分区/文件 开启交换空间
    Scope Unit .scope 管理外部进程 用户会话、容器
    Socket Unit .socket 管理 socket 通信 socket 激活服务
    Device Unit .device 管理硬件设备 磁盘、USB 设备
    Snapshot Unit .snapshot 保存当前状态 系统状态快照

    3.0、通用块

    每种 Unit 配置文件的语法格式基本都是由 3 大块组成:通用的【Unit 块 + Install 块】,以及独属于每种 Unit 类型专属的【Service 块、Timer 块、Path 块等】。下面我将展示 通用块【Unit 块 + Install 块】的常用参数,而关于每种 Unit 专属块 的常用参数则在各自的小节进行展示。

    3.0.1、Unit 块参数

    【Unit 块】常用参数列表:

    设定参数参数意义说明
    Description 对当前 Unit 的功能进行简短描述,执行 systemctl status 时通常可以看到。
    Documentation 指定该 Unit 的相关文档地址,可以是 man:、info: 或 URL。
    Requires 强依赖关系。当前 Unit 启动时,会尝试启动这里指定的 Unit;如果依赖 Unit 被停止或启动失败,当前 Unit 通常也会受到影响。
    Wants 弱依赖关系。当前 Unit 启动时,会尝试启动这里指定的 Unit;但依赖 Unit 启动失败,一般不会导致当前 Unit 失败。
    Requisite 要求指定 Unit 已经处于 active 状态,否则当前 Unit 不会启动;它本身不会主动启动依赖 Unit。
    BindsTo 比 Requires 更强的绑定关系。依赖 Unit 消失或变为 inactive 时,当前 Unit 也会停止。
    PartOf 建立停止/重启传播关系。当指定 Unit 被停止或重启时,当前 Unit 也会执行相应操作。
    Conflicts 表示两个 Unit 不能同时运行。启动一个 Unit 时,会停止与它存在 Conflicts 关系的 Unit。
    Before 指定当前 Unit 必须在某些 Unit 之前启动。只负责启动顺序,不建立依赖关系。
    After 指定当前 Unit 必须在某些 Unit 之后启动。只负责启动顺序,不建立依赖关系。
    Before / After 可以同时使用。例如 After=network.target 表示当前 Unit 的启动顺序排在 network.target 后面。
    Condition… 启动前进行条件检查。条件不满足时,Unit 会被跳过,而不是认为启动失败。
    Assert… 启动前进行断言检查。条件不满足时,Unit 启动会被认为失败。
    DefaultDependencies 是否自动添加 systemd 默认依赖关系,默认通常为 yes。
    OnFailure 当前 Unit 启动失败时,自动激活指定的 Unit。
    OnSuccess 当前 Unit 成功停止/完成后,自动激活指定的 Unit。
    JobTimeoutSec 设置等待该 Unit Job 完成的超时时间。
    StartLimitIntervalSec 在指定时间窗口内限制 Unit 的启动次数。
    StartLimitBurst 指定时间窗口内允许的最大启动次数,通常与 StartLimitIntervalSec 配合使用。

    3.0.2、Install 块参数

    【Install 块】常用参数列表:

    设定参数参数意义说明
    WantedBy 指定当前 Unit 应该被哪个 Target 以 Wants 关系拉起。执行 systemctl enable 时,会在对应 Target 的 .wants/ 目录中创建符号链接。
    RequiredBy 与 WantedBy 类似,但建立的是 Requires 关系,启用当前 Unit 时会在对应 Target 的 .requires/ 目录建立链接。
    Also 当执行 systemctl enable 或 disable 当前 Unit 时,同时对指定的其他 Unit 执行相应操作。
    Alias 为当前 Unit 创建别名。启用 Unit 时,会建立对应的符号链接,使得可以通过别名操作同一个 Unit。

    3.1、Service

    单元介绍:最基本的单元,主要用来启动服务进程,同时也是 target、timer、path、socket 这些单元所需的基本单元。

    期望目标:一条命令启动/停止 nginx 服务进程。

    # cat nginx.service

    [Unit]
    Description=Nginx Web Server
    After=network.target

    [Service]
    ExecStart=/usr/sbin/nginx
    ExecStop=/usr/sbin/nginx -s stop
    Restart=always

    [Install]
    WantedBy=multi-user.target

    【Service 块】常用参数列表:

    设定参数参数意义说明
    Type 指定服务的启动类型,常见有 simple、exec、forking、oneshot、dbus、notify、idle。
    ExecStart 指定启动服务时执行的命令,是最核心的 Service 参数之一。
    ExecStartPre 在 ExecStart 之前执行的命令,常用于启动前检查或准备工作。
    ExecStartPost ExecStart 成功后执行的命令。
    ExecReload 执行 systemctl reload xxx 时运行的命令,用于让程序重新加载配置。
    ExecStop 执行 systemctl stop xxx 时运行的命令。
    ExecStopPost 服务停止后执行的命令,常用于清理工作。
    Restart 指定服务退出后是否自动重新启动,例如 no、on-success、on-failure、always。
    RestartSec 服务自动重启前等待多长时间。
    RestartPreventExitStatus 指定某些退出状态码时禁止自动重启。
    RestartForceExitStatus 指定某些退出状态码时强制触发自动重启。
    User 指定服务进程以哪个用户身份运行。
    Group 指定服务进程使用的用户组。
    WorkingDirectory 指定服务进程的工作目录。
    Environment 设置服务运行时的环境变量。
    EnvironmentFile 从指定文件读取环境变量。
    ExecSearchPath 指定执行程序时搜索可执行文件的路径。
    PIDFile 指定服务 PID 文件的位置,常用于 Type=forking 的服务。
    RemainAfterExit 对 Type=oneshot 等服务有用,表示命令执行结束后 Unit 是否继续保持 active 状态。
    TimeoutStartSec 设置服务启动超时时间。
    TimeoutStopSec 设置服务停止超时时间。
    TimeoutAbortSec 服务被中止时允许等待的时间。
    KillMode 指定停止服务时 systemd 如何处理服务进程,例如 control-group、process、mixed。
    KillSignal 指定停止服务时首先发送的信号,默认通常为 SIGTERM。
    SuccessExitStatus 指定哪些退出状态被认为是正常退出。
    StandardOutput 指定标准输出的去向,例如 journal、null、file: 等。
    StandardError 指定标准错误输出的去向。
    SyslogIdentifier 设置写入 journal 时使用的标识名称。
    Nice 设置进程的 CPU 调度优先级。
    OOMScoreAdjust 调整进程被 Linux OOM Killer 杀死时的优先级。
    LimitNOFILE 限制进程能够打开的最大文件描述符数量。
    LimitNPROC 限制进程能够创建的进程/线程数量。
    PrivateTmp 为服务提供独立的 /tmp 和 /var/tmp 环境。
    ProtectSystem 限制服务对系统目录的写权限,提高安全性。
    ProtectHome 限制服务访问 /home、/root、/run/user 等目录。
    NoNewPrivileges 禁止服务进程通过 execve() 获取新的特权,提高安全性。

    由于 Type 是 [Service] 中非常重要的参数,因此下面将对该参数进行详细说明:

    Type含义
    simple ExecStart 启动的进程就是主进程,systemd 启动命令后通常就认为服务已经启动。
    exec 类似 simple,但会等待程序真正成功执行后再认为启动成功。
    forking 程序启动后会 fork 到后台,传统守护进程常使用这种方式。
    oneshot 执行一次命令后退出,常用于脚本、初始化任务。
    notify 程序通过 systemd 的通知机制主动告诉 systemd “我已经启动完成”。
    dbus 程序成功获得指定 D-Bus 名称后认为启动完成。
    idle 等待其他任务完成后再启动,主要用于调整启动时机。

    3.2、Target

    单元介绍:搭配 service 或其他类型的 Unit 使用,可以理解为是 一组 Unit 的集合,它本身通常不执行程序,而是用来组织和控制多个 service、mount、socket 等 Unit 的启动顺序。

    期望目标:通过一条命令便可同时启动这些 web 业务服务:nginx、mysql、redis。

    # cat nginx.service mysql.service redis.service
    ...省略...

    # cat myapp.target

    [Unit]
    Description=My Application Stack

    Requires=nginx.service mysql.service redis.service

    After=nginx.service mysql.service redis.service

    【Target 块】常用参数列表:

    注:该 Unit 的配置文件无专属块参数,只需要通用的 Unit、Install 块即可。

    3.3、Timer

    单元介绍:搭配 service 使用,可以理解为是 service 的专属定时器,时间单位可精细到秒。【注:cron 的最小时间单位是分钟】

    期望目标:定时执行服务程序。

    # cat backup.service

    [Unit]
    Description=backup file

    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/file-backup.sh

    # cat backup.timer

    [Unit]
    Description=backup my server timer

    [Timer]
    OnBootSec=2hrs # 开机后 2 小时开始执行一次这个 backup.service。
    OnUnitActiveSec=2days # 自从第一次执行后,未来每两天要执行一次 backup.service。

    [Install]
    WantedBy=multi-user.target

    注:持续计时参数。

    # 每天凌晨执行备份。
    [Timer]
    OnCalendar=*-*-* 02:00:00
    Persistent=true

    【Timer 块】常用参数列表:

    设定参数参数意义说明
    OnBootSec 系统启动后经过指定时间后触发 Timer,例如 OnBootSec=5min 表示系统启动 5 分钟后执行。
    OnStartupSec systemd 用户实例或系统实例启动后经过指定时间触发。系统级 Timer 中通常与 OnBootSec 类似。
    OnUnitActiveSec 被触发的 Unit 上一次被激活后,经过指定时间再次触发。例如 OnUnitActiveSec=1h 表示服务激活后每隔 1 小时再次触发。
    OnUnitInactiveSec 被触发的 Unit 变为 inactive 后,经过指定时间再次触发。
    OnCalendar 按日历时间触发,例如 OnCalendar=daily、OnCalendar=*-*-* 02:00:00。
    OnActiveSec Timer 本身被激活后经过指定时间触发。
    OnFailureSec Timer 所关联的 Unit 失败后经过指定时间触发。
    Persistent 是否补执行错过的任务。设置为 true 后,如果机器关机期间错过了定时任务,下一次启动时会补执行。
    AccuracySec Timer 触发时间允许的误差范围,用于让 systemd 合并多个定时任务以减少系统唤醒。
    RandomizedDelaySec 在计划触发时间基础上增加随机延迟,可避免大量机器同时执行任务。
    Unit 指定 Timer 触发哪个 Unit。默认情况下,xxx.timer 通常触发同名的 xxx.service。

    3.4、Path

    单元介绍:搭配 service 使用,当某个文件的内容/状态出现变动时,触发对绑定 service 的启动。

    期望目标:当文件 /tmp/test.txt 被修改(echo hello >> /tmp/test.txt)时,系统会自动执行 file-change.sh 脚本。

    # cat file-change.service

    [Unit]
    Description=Handle file change

    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/file-change.sh

    # cat file-change.path

    [Unit]
    Description=Monitor test file

    [Path]
    PathModified=/tmp/test.txt

    [Install]
    WantedBy=multi-user.target

    【Path 块】常用参数列表:

    设定参数参数意义说明
    PathExists 指定路径存在时触发关联的 Service。
    PathExistsGlob 使用通配符匹配路径,只要匹配的路径存在就触发 Service。
    PathChanged 指定文件或目录发生变化时触发 Service。
    PathModified 指定文件被修改时触发 Service。相比 PathChanged,更关注文件内容修改。
    DirectoryNotEmpty 指定目录不为空时触发 Service,常用于监控“文件投递目录”。
    Unit 指定 Path Unit 触发哪个 Unit。默认情况下,xxx.path 通常触发同名的 xxx.service。
    MakeDirectory 创建监控路径不存在的父目录。

    3.5、Slice

    单元介绍:搭配 service 使用,让加入到同一个资源组的服务共用同一个环境的资源,可以起到限制进程无限使用系统资源的作用。

    期望目标:让 nginx 服务所能使用的最大 CPU 不超过 40%,最大内存不超过 2G。

    # cat nginx.service

    [Unit]
    Description=Nginx Web Server
    After=network.target

    [Service]
    ExecStart=/usr/sbin/nginx
    ExecStop=/usr/sbin/nginx -s stop
    Restart=always
    Slice=web.slice

    [Install]
    WantedBy=multi-user.target

    # cat web.slice

    [Slice]
    CPUQuota=40%
    MemoryMax=2G

    【Slice 块】常用参数列表:

    设定参数参数意义说明
    CPUQuota 限制该 Slice 最多使用多少 CPU,例如 CPUQuota=50% 表示最多使用 50% 的一个 CPU 核心。
    MemoryMax 设置该 Slice 可使用的最大内存,超过限制后可能触发 OOM 处理。
    MemoryHigh 设置内存使用的“高水位”,超过后 systemd 会对该 Slice 施加内存压力控制,但通常不会像 MemoryMax 那样直接作为硬限制。
    MemoryMin 设置该 Slice 应获得的最低内存保障。
    MemoryLow 设置内存保护的低水位。
    TasksMax 限制该 Slice 中最多允许创建多少个进程/线程。
    IOWeight 设置磁盘 I/O 权重,用于不同 Slice 之间的 I/O 资源竞争。
    IODeviceWeight 针对特定设备设置 I/O 权重。
    BlockIOAccounting 是否统计该 Slice 的块设备 I/O 使用情况。
    CPUAccounting 是否统计 CPU 使用情况。
    MemoryAccounting 是否统计内存使用情况。
    TasksAccounting 是否统计任务数量。

    3.6、Mount

    单元介绍:该 Unit 相当于是对系统 fatab/mount 的另一种实现,同时也是 Automount 自动挂载单元的基本 Unit。

    期望目标:通过 systemctl start data.mount 将 sdb1 这个分区挂载到 /data 目录下。

    # cat data.mount

    [Unit]
    Description=Mount data disk

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

    [Install]
    WantedBy=multi-user.target

    【Mount 块】常用参数列表:

    设定参数参数意义说明
    What 指定要挂载的设备、磁盘分区、LVM、NFS 等来源,例如 /dev/sdb1。
    Where 指定挂载点,例如 /data。这是 Mount Unit 最核心的参数之一。
    Type 指定文件系统类型,例如 ext4、xfs、nfs 等。
    Options 指定挂载参数,相当于 mount -o 后面的参数,例如 defaults,noatime。
    SloppyOptions 是否允许部分无法识别的挂载选项被忽略。
    LazyUnmount Unit 停止时是否使用 lazy unmount。
    ForceUnmount Unit 停止时是否强制卸载。
    DirectoryMode 如果挂载点目录不存在,指定创建目录时使用的权限。
    TimeoutSec 设置挂载操作的超时时间。

    3.7、Automount

    单元介绍:搭配 mount 单元使用,当指定的目录被读取时,自动触发对绑定 mount 的启动。

    期望目标:正常情况下,backup.mount 这个分区并不会被挂载,但是当执行 ls /backup 的时候,这个分区才会被挂载。

    # cat backup.mount

    [Unit]
    Description=NFS Backup Mount

    [Mount]
    What=192.168.1.10:/backup
    Where=/backup
    Type=nfs
    Options=defaults

    # 注意,这里没有配置 WantedBy= 选项,因为它不需要通过开机启动。

    # cat backup.automount

    [Unit]
    Description=Automount backup directory

    [Automount]
    Where=/backup
    TimeoutIdleSec=300

    [Install]
    WantedBy=multi-user.target

    注:mount 一般用于开机自启,而 automount 则用于按需自启。

    【Automount 块】常用参数列表:

    设定参数参数意义说明
    Where 指定自动挂载点,例如 /data。
    DirectoryMode 如果挂载点目录不存在,指定创建目录时的权限。
    TimeoutIdleSec 指定挂载点空闲多长时间后自动卸载。例如 TimeoutIdleSec=10min。

    4、命令管理

    4.1、systemctl 命令用法

    systemd 用来管理服务的命令只有一条,即 systemctl,以下便是关于该命令最常见的用法:

    # ——————– 1. 服务管理 ——————–

    # 启动/停止/重启/重载/查看服务
    systemctl start/stop/restart/reload/status nginx

    # 设置/取消/开机自启,以及禁止/取消禁止服务被自启
    systemctl enable/disable/mask/unmask nginx

    # 判断服务 是否自启/是否正在运行/是否启动失败
    systemctl is-enabled/is-active/is-failed nginx

    # ——————– 2. 服务状态查看 ——————–

    # 查看系统中所有已安装的 Unit 文件的预设状态
    systemctl list-unit-files

    # 查看所有 Unit 的运行状态,包括 inactive
    systemctl list-units –all

    # 按 Unit 类型查看当前启动的 Unit
    systemctl list-units –type=service
    systemctl list-units –type=socket
    systemctl list-units –type=timer
    systemctl list-units –type=mount
    systemctl list-units –type=target

    # 查看启动失败的 Unit
    systemctl list-units –state=failed # 等价于 systemctl –failed

    # 查看所有 Socket 服务的状态,不论是否启动
    systemctl list-sockets

    # 查看所有 Timer 服务的状态,不论是否启动
    systemctl list-timers

    # 查看所有 Path 服务的状态,不论是否启动
    systemctl list-paths

    # 查看所有 Automount 服务的状态,不论是否启动
    systemctl list-automounts

    # ——————– 3. Unit 文件管理 ——————–

    # 查看 Unit 的属性信息
    systemctl show nginx

    # 查看 Unit 文件内容
    systemctl cat nginx

    # 编辑 Unit 文件(修改内容会被添加到 /etc/systemd/system/nginx.service.d/override.conf 文件中)
    systemctl edit nginx

    # 编辑完整 Unit 文件(可直接在原来的基础上进行修改)
    systemctl edit –full nginx

    # 修改 Unit 文件后重新加载 systemd
    systemctl daemon-reload

    # ——————– 4. Unit 依赖查询 ——————–

    # 查看 Unit 的依赖关系
    systemctl list-dependencies nginx

    # 查看反向依赖
    systemctl list-dependencies –reverse nginx

    # ——————– 5. Target 管理 ——————–

    # 查看默认 Target
    systemctl get-default

    # 设置默认 Target
    systemctl set-default multi-user.target

    # 切换到指定 Target
    systemctl isolate multi-user.target

    # 查看 Target 的依赖
    systemctl list-dependencies multi-user.target

    # ——————– 6. 系统操作 ——————–

    # 重启系统
    systemctl reboot

    # 关机
    systemctl poweroff

    # 挂起
    systemctl suspend

    # 休眠
    systemctl hibernate

    # 进入救援模式
    systemctl rescue

    # 进入紧急模式
    systemctl emergency

    4.2、journalctl 命令用法

    前面我们说过,systemd 不仅可以用来管理服务,同时它还提供了一个日志记录服务 journald 来记录服务单元的日志活动,而查看日志的命令也只有一条,即 journalctl,以下便是关于该命令最常见的用法:

    # ——————– 1. 查看日志 ——————–

    # 查看全部日志
    journalctl

    # 查看当前启动的内核日志
    journalctl -k

    # 查看指定服务的全部日志
    journalctl -u nginx

    # 查看最近 N 条日志
    journalctl -n 50

    # 查看最新日志并自动跳到末尾
    journalctl -e

    # 实时跟踪日志(类似 tail -f)
    journalctl -f

    # 显示完整时间等信息
    journalctl -o short-full

    # ——————– 2. 按时间查看日志 ——————–

    # 查看今天的日志
    journalctl –since today

    # 查看最近 30 分钟的日志
    journalctl –since "30 min ago"

    # 查看指定时间之后的日志
    journalctl –since "2026-08-11 10:00:00"

    # 查看指定时间之前的日志
    journalctl –until "2026-08-11 12:00:00"

    # 查看指定时间范围的日志
    journalctl –since "2026-08-11 10:00:00" –until "2026-08-11 12:00:00"

    # 查看某服务最近 1 小时的日志
    journalctl -u nginx –since today

    # ——————– 3. 按日志级别过滤 ——————–

    # 查看 error 及更严重的日志
    journalctl -p err

    # 查看 warning 到 emergency
    journalctl -p warning..emerg

    # 常见日志级别:
    #
    # 0 emerg 紧急
    # 1 alert 必须立即处理
    # 2 crit 严重错误
    # 3 err 错误
    # 4 warning 警告
    # 5 notice 注意
    # 6 info 信息
    # 7 debug 调试

    # ——————– 4. 按关键词搜索 ——————–

    # 搜索包含关键字的日志
    journalctl -g "error"

    # 搜索指定服务中的关键词
    journalctl -u nginx -g "error"

    # 忽略大小写搜索
    journalctl -g "error" –case-sensitive=false

    # ——————– 5. 日志空间占用 ——————–

    # 查看 journal 日志占用空间
    journalctl –disk-usage

    # 删除超过指定时间的日志
    journalctl –vacuum-time=30d

    5、杂七杂八

    (1)参考文档:阮一峰的网络日志、ArchWiki、官方手册

    (2)systemctl 子命令 daemon-reload 和 reload 的区别 :

    命令功能
    systemctl daemon-reload 让 systemd 重新读取 Unit 配置文件,以便 systemctl 在管理服务的时候能够按照最新的 Unit 配置文件内容做出反应。
    systemctl reload nginx.service 让某个正在运行的服务重新加载自己的配置文件,例如:让 nginx 服务重新加载自己的配置文件 nginx.conf 的参数内容。

    (3)为什么执行开机自启命令 systemctl enable *.service 的时候,命令会在 /etc/systemd/system/multi-user.target.wants/ 目录中添加服务的软链接?

    开机自启说白了就是让服务能够跟随 multi-user.target 服务单元一起被启动,而在服务单元 Unit 的配置文件中,这一功能是可以通过参数 Wants 实现的,因此你是可以通过修改 /etc/systemd/system/multi-user.target 配置文件来做到让指定服务开机自启的。

    但我们前面也说过,系统预置的 Unit 文件一般不要随便改动。于是官方又为其设计了 /etc/systemd/system/multi-user.target.wants/ 目录,其功能与 Unit 文件中的 Wants 参数的作用是一样的,不用随便修改文件只需把指定服务的软链接放进去就可以,也不用老是在修改完 Unit 文件之后需要频繁执行 systemctl daemon-reload 加载信息,可谓是相当灵活。

    注:服务对应的 Unit 文件(此处以 nginx.service 为例)中 [Install] 块下的 WantedBy = multi-user.target 是指,当执行 systemctl enable nginx.service 时,便会为 nginx.service 创建软链接,链接目标便是在 multi-user.target 的 wants 文件夹下面,即 /etc/systemd/system/multi-user.target 。

    (4)Unit 模板单元示例(此处以 vsftpd 为例):

    以前,如果我们想运行多个 FTP 实例,那我们会为其配置多个配置文件(如 ftpd1.conf、ftpd2.conf、ftpd3.conf 等),然后按照 vsftpd /etc/vsftpd/ftpd1.conf、vsftpd /etc/vsftpd/ftpd2.conf、vsftpd /etc/vsftpd/ftpd3.conf 的方式去一一启动。

    但现在,我们管理服务都是通过 systemd 进行的,那该如何实现通过 systemctl 达到一键开启多个实例的效果呢?这就轮到 Unit 模板单元来展示了。

    用法其实也很简单,就是将常规的 vsftpd.service 文件中关于配置文件变动的地方改成变量的形式就好了,如下:

    # cat /usr/lib/systemd/system/vsftpd@.service

    [Unit]
    Description=Vsftpd ftp daemon
    After=network.target
    PartOf=vsftpd.target

    [Service]
    Type=forking
    ExecStart=/usr/sbin/vsftpd /etc/vsftpd/ftpd%I.conf

    #[Install]
    #WantedBy=vsftpd.target
    # 注意:该配置来自鸟哥私房菜。此处并非是 multi-user.target,而是一个自建的 vsftpd.target,这一点似乎有说法,但我觉得直接注释即可,作用不大。

    如此一来,我们想启动 ftpd2.conf 配置文件的实例就执行 systemctl start vsftpd@2.service,想启动 ftpd3.conf 的实例,就执行 systemctl start vsftpd@3.service 。可这样还是有个不方便的地方,那就是如果我们想将三个实例都启动起来,就需要连续执行 3 次启动命令,而且这种模板服务似乎也不能够进行开机自启。

    注:在 systemctl start vsftpd@1.service 中,@ 后面的字串会被当做参数赋值给配置文件中的变量 %I。

    这时候我们就可以用到 target 这个 Unit 了,让它来帮我们实现一键启动多个模板实例的效果。

    我的博客园
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Systemd 学习总结
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!