303 lines
12 KiB
Markdown
303 lines
12 KiB
Markdown
---
|
||
title: "Systemd 笔记"
|
||
date: 2019-10-30T11:32:04+08:00
|
||
lastmod: 2019-10-30T11:32:04+08:00
|
||
tags: ["systemd", "systemctl", "journalctl"]
|
||
categories: ["OS"]
|
||
---
|
||
|
||
## 系统资源(unit)分类
|
||
Unit | 描述
|
||
---- | ----
|
||
Service | 系统服务,默认
|
||
Target | 多个 unit 构成的一个组
|
||
Device | 硬件设备
|
||
Mount | 文件系统的挂载点
|
||
Automount | 自动挂载点
|
||
Path | 文件或路径
|
||
Scope | 不是由 systemd 启动的外部进程
|
||
Slice | 进程组
|
||
Snapshot | systemd 快照,可以切回某个快照
|
||
Socket | 进程间通信的 socket
|
||
Swap | swap 文件
|
||
Timer | 定时器
|
||
|
||
## Target 与传统 runlevel 对应关系
|
||
传统运行等级 | 新版 target 命名 | 链接名
|
||
---- | ---- | ----
|
||
Runlevel 0 | runlevel0.target | poweroff.target
|
||
Runlevel 1 | runlevel1.target | rescue.target
|
||
Runlevel 2 | runlevel2.target | multi-user.target
|
||
Runlevel 3 | runlevel3.target | multi-user.target
|
||
Runlevel 4 | runlevel4.target | multi-user.target
|
||
Runlevel 5 | runlevel5.target | graphical.target
|
||
Runlevel 6 | runlevel6.target | reboot.target
|
||
|
||
## systemctl 命令
|
||
- 查看版本
|
||
```bash
|
||
systemctl --version
|
||
```
|
||
- 系统操作
|
||
```bash
|
||
systemctl reboot # 重启
|
||
systemctl poweroff # 关闭系统,切断电源
|
||
systemctl halt # 停止 CPU 工作
|
||
systemctl suspend # 暂停系统
|
||
systemctl hibernate # 让系统进入休眠状态
|
||
systemctl hybrid-sleep # 让系统进入交互式休眠状态
|
||
systemctl rescue # 启动进入救援状态(单用户状态)
|
||
systemctl status # 显示系统状态
|
||
```
|
||
- 查看全部 Unit
|
||
```bash
|
||
systemctl list-unit-files # 列出所有 Unit 配置文件
|
||
# enabled 已建立启动链接
|
||
# disabled 没建立启动链接
|
||
# static 该配置文件没有[Install]部分,无法执行,只能作为其他 Unit 配置文件的依赖
|
||
# masked 该配置文件被禁止建立启动链接
|
||
systemctl list-unit-files --type=service # 列出指定类型的 Unit 配置文件
|
||
systemctl list-units # 列出正在运行的 Unit
|
||
systemctl list-units --all # 列出所有 Unit,包括没有找到配置文件的或者启动失败的
|
||
systemctl list-units --all --state=inactive # 列出所有没有运行的 Unit
|
||
systemctl list-units --failed # 列出所有加载失败的 Unit
|
||
systemctl list-units --type=service # 列出所有正在运行的、类型为 service 的 Unit
|
||
```
|
||
- 查看一个 Unit
|
||
```bash
|
||
systemctl list-dependencies nginx.service # 显示一个 Unit 的所有依赖
|
||
systemctl list-dependencies --all nginx.service # 显示一个 Unit 的所有依赖,展开 target
|
||
systemctl cat nginx.service # 查看一个 Unit 配置文件
|
||
systemctl show httpd.service # 显示一个 Unit 的所有底层参数
|
||
systemctl show -p CPUShares httpd.service # 显示一个 Unit 的指定属性的值
|
||
systemctl status nginx.service # 显示单个 Unit 的状态
|
||
systemctl -H root@ssh_server status nginx.service # 显示远程主机的某个 Unit 的状态 (ssh 连接)
|
||
systemctl is-active nginx.service # 显示某个 Unit 是否正在运行
|
||
systemctl is-failed nginx.service # 显示某个 Unit 是否处于启动失败状态
|
||
systemctl is-enabled nginx.service # 显示某个 Unit 服务是否建立了启动链接
|
||
```
|
||
- 操作一个 Unit
|
||
```bash
|
||
systemctl reload apache.service # 重新加载一个服务的配置文件
|
||
systemctl set-property httpd.service CPUShares=500 # 设置一个服务的指定属性
|
||
systemctl start apache.service # 立即启动一个服务
|
||
systemctl stop apache.service # 立即停止一个服务
|
||
systemctl restart apache.service # 重启一个服务
|
||
systemctl kill apache.service # 杀死一个服务的所有子进程
|
||
systemctl enable nginx.service # 建立启动链接,激活开机启动
|
||
systemctl disable nginx.service # 删除启动链接,取消开机启动
|
||
```
|
||
- 重新加载全部修改过的 Unit 配置文件
|
||
```bash
|
||
systemctl daemon-reload
|
||
```
|
||
|
||
## systemd-analyze 命令
|
||
- 查看启动耗时
|
||
```bash
|
||
systemd-analyze
|
||
```
|
||
- 查看每个服务的启动耗时
|
||
```bash
|
||
systemd-analyze blame
|
||
```
|
||
- 显示瀑布状的启动过程流
|
||
```bash
|
||
systemd-analyze critical-chain
|
||
```
|
||
- 显示指定服务的启动流
|
||
```bash
|
||
systemd-analyze critical-chain atd.service
|
||
```
|
||
|
||
## journalctl 命令
|
||
- 查看所有日志(默认只保存本次启动的日志)
|
||
```bash
|
||
journalctl
|
||
```
|
||
- 查看内核日志(不显示应用日志)
|
||
```bash
|
||
journalctl -k
|
||
```
|
||
- 查看系统启动日志
|
||
```bash
|
||
journalctl -b # 本次启动的日志
|
||
journalctl -b -0 # 本次启动的日志
|
||
journalctl -b -1 # 查看上一次启动的日志(需更改设置)
|
||
```
|
||
- 查看指定时间的日志
|
||
```bash
|
||
journalctl --since="2012-10-30 18:17:16"
|
||
journalctl --since "20 min ago"
|
||
journalctl --since yesterday
|
||
journalctl --since "2018-11-11" --until "2019-01-01 01:00"
|
||
journalctl --since 09:00 --until "1 hour ago"
|
||
```
|
||
- 显示尾部的最新日志
|
||
```bash
|
||
journalctl -n # 最近 10 行
|
||
journalctl -n 20 # 最近 20 行日志
|
||
```
|
||
- 实时滚动显示最新日志
|
||
```bash
|
||
journalctl -f
|
||
```
|
||
- 查看指定服务的日志
|
||
```bash
|
||
journalctl /usr/lib/systemd/systemd
|
||
```
|
||
- 查看指定进程的日志
|
||
```bash
|
||
journalctl _PID=1
|
||
```
|
||
- 查看某个路径的脚本的日志
|
||
```bash
|
||
journalctl /usr/bin/bash
|
||
```
|
||
- 查看指定用户的日志
|
||
```bash
|
||
journalctl _UID=33 --since today
|
||
```
|
||
- 查看某个 Unit 的日志
|
||
```bash
|
||
journalctl -u nginx.service
|
||
journalctl -u nginx.service --since today
|
||
```
|
||
- 实时滚动显示某个 Unit 的最新日志
|
||
```bash
|
||
journalctl -u nginx.service -f
|
||
```
|
||
- 合并显示多个 Unit 的日志
|
||
```bash
|
||
journalctl -u nginx.service -u php-fpm.service --since today
|
||
```
|
||
- 查看指定优先级(及其以上级别)的日志,共有8级
|
||
- 0: emerg
|
||
- 1: alert
|
||
- 2: crit
|
||
- 3: err
|
||
- 4: warning
|
||
- 5: notice
|
||
- 6: info
|
||
- 7: debug
|
||
```bash
|
||
journalctl -p err -b
|
||
```
|
||
- 日志默认分页输出,--no-pager 改为正常的标准输出
|
||
```bash
|
||
journalctl --no-pager
|
||
```
|
||
- 以 JSON 格式(单行)输出
|
||
```bash
|
||
journalctl -b -u nginx.service -o json
|
||
```
|
||
- 以 JSON 格式(多行)输出,可读性更好
|
||
```bash
|
||
journalctl -b -u nginx.serviceqq -o json-pretty
|
||
```
|
||
- 显示日志占据的硬盘空间
|
||
```bash
|
||
journalctl --disk-usage
|
||
```
|
||
- 指定日志文件占据的最大空间
|
||
```bash
|
||
journalctl --vacuum-size=1G
|
||
```
|
||
- 指定日志文件保存多久
|
||
```bash
|
||
journalctl --vacuum-time=1years
|
||
```
|
||
|
||
## 其他相似命令
|
||
- hostnamectl
|
||
- localectl
|
||
- timedatectl
|
||
- loginctl
|
||
|
||
## Unit 配置文件
|
||
### [Unit]
|
||
- Description: 简短描述
|
||
- Documentation: 文档地址
|
||
- Requires: 当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败
|
||
- Wants: 与当前 Unit 配合的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败
|
||
- BindsTo: 与Requires类似,它指定的 Unit 如果退出,会导致当前 Unit 停止运行
|
||
- Before: 如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动
|
||
- After: 如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之前启动
|
||
- Conflicts: 这里指定的 Unit 不能与当前 Unit 同时运行
|
||
- Condition...: 当前 Unit 运行必须满足的条件,否则不会运行
|
||
- Assert...: 当前 Unit 运行必须满足的条件,否则会报启动失败
|
||
### [Service]
|
||
- WorkingDirectory: 设置进程的工作目录
|
||
- 特殊值 "~" 表示 User= 用户的家目录
|
||
- 设为一个以 RootDirectory= 为基准的绝对路径
|
||
- 例如当 RootDirectory=/sysroot 并且 WorkingDirectory=/work/dir 时,实际的工作目录将是 /sysroot/work/dir
|
||
- 当 systemd 作为系统实例运行时,此选项的默认值是 /
|
||
- 当 systemd 作为用户实例运行时,此选项的默认值是对应用户的家目录
|
||
- 给目录加上 "-" 前缀,表示即使此目录不存在,也不算致命错误
|
||
- 未设置 RootDirectory=/RootImage= 选项,那么为 WorkingDirectory= 设置的绝对路径 将以主机(或容器)的根目录(也就是运行 systemd 的系统根目录)为基准
|
||
- RootDirectory: 设置以 chroot(2) 方式执行进程时的根目录
|
||
- 必须设为一个以主机(或容器)的根目录(也就是运行 systemd 的系统根目录)为基准的绝对路径
|
||
- 设置了此选项,必须确保进程及其辅助文件在 chroot() 监狱中确实可用
|
||
- User/Group: 设置进程在执行时使用的用户与组
|
||
- TimeoutSec: 定义 Systemd 停止当前服务之前等待的秒数
|
||
- Environment: 指定环境变量
|
||
- EnvironmentFile: 环境参数文件,内部 key=value 格式,在当前文件中使用 $key 获取 value
|
||
- ExecStart: 启动时执行的命令
|
||
- ExecReload: 重启服务时执行的命令
|
||
- ExecStop: 停止服务时执行的命令
|
||
- ExecStartPre: 启动服务之前执行的命令
|
||
- ExecStartPost: 启动服务之后执行的命令
|
||
- ExecStopPost: 停止服务之后执行的命令
|
||
- "-" 配置项前的减号"-"表示"抑制错误",发生错误时不影响后续命令执行
|
||
- Type
|
||
- simple: 默认,ExecStart 启动的进程就是主进程
|
||
- forking: ExecStart 启动时 fork 子进程,之后该父进程退出,子进程成为主进程
|
||
- oneshot: 类似 Simple,只执行一次
|
||
- dbus: 类似 Simple,等待 D-Bus 信号启动
|
||
- notify: 类似 Simple,启动完成后发出通知信号
|
||
- idle: 类似 Simple,等到其他任务执行完成后才会启动该服务
|
||
- RemainAfterExit=yes: 进程退出后服务保持运行
|
||
- KillMode
|
||
- control-group: 默认,杀掉所有子进程
|
||
- process: 只杀主进程
|
||
- mixed: 主进程收到 SIGTERM 信号,子进程收到 SIGKILL 信号
|
||
- none: 不杀进程,只执行服务的 stop 命令
|
||
- Restart
|
||
- no: 默认,退出后不重启
|
||
- on-success: 正常退出时重启
|
||
- on-failure: 非正常退出、被信号终止或超时重启
|
||
- on-abnormal: 被信号终止和超时重启
|
||
- on-abort: 收到没有捕捉到的信号终止时重启
|
||
- on-watchdog: 超时退出,才会重启
|
||
- always: 不管是什么退出原因,总是重启
|
||
- RestartSec: 系统重启前等待的秒数
|
||
### [Install]
|
||
- WantedBy: 它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants 后缀构成的子目录中
|
||
- RequiredBy: 它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required 后缀构成的子目录中
|
||
- Alias: 当前 Unit 可用于启动的别名
|
||
- Also: 当前 Unit 激活(enable)时,会被同时激活的其他 Unit
|
||
|
||
## Unit 配置文件占位符
|
||
占位符 | 作用 | 描述
|
||
---- | ---- | ----
|
||
%n | 完整的服务名称 |
|
||
%N | 不转义的完整服务名称 |
|
||
%p | 前缀名 | 对于实例化的服务,这是前@前面的部分,对于其它的服务,是指去掉后缀(即类型)的部分
|
||
%P | 不转义的前缀名 |
|
||
%i | 实例名称 | 对于实例化的服务,这是指 @和后缀之间的部分
|
||
%I | 不转义的实例名 |
|
||
%f | 不转义的文件名 | 这可以不转义的实例名(如果可用)或前缀名,带有/前缀
|
||
%c | 服务的控制组路径 |
|
||
%r | systemd 的根控制组路径 |
|
||
%R | systemd 的根控制组路径的父目录 |
|
||
%t | 运行时 Socket 目录 | 这可以是 /run (系统管理器) 或 $XDG_RUNTIME_DIR (用户管理器)
|
||
%u | 用户名 | 这是服务配置的用户或systemd运行实例的用户(如果没有配置的话)
|
||
%U | 用户 UID | 这是服务配置的用户UID或systemd运行实例的用户UID(如果没有配置的话)
|
||
%h | 用户家目录 | 这是服务配置的用户家目录或systemd运行实例的用户家目录(如果没有配置的话)
|
||
%s | 用户Shell | 这是服务配置的用户shell或systemd运行实例的用户shell(如果没有配置的话)
|
||
%m | 机器 ID | 运行系统的机器 ID,格式是一个字符串
|
||
%b | 启动 ID | 运行系统的启动 ID,格式是一个字符串
|
||
%H | 主机名 | 运行系统的主机名
|
||
%% | 转义 % | 一个单百分号
|
||
|