Systemd:Linux服务管理系统完全指南

Systemd:Linux服务管理系统完全指南

Systemd 系统和服务管理器

1. 基础概念

systemd是Linux系统中的一号进程(PID 1),负责:

  • 系统初始化
  • 服务管理
  • 日志管理
  • 设备管理
  • 电源管理
  • 网络管理

2. 核心组件

2.1 系统组件

  • systemd:系统管理守护进程
  • systemctl:主要的管理工具
  • journald:日志管理
  • logind:用户会话管理
  • networkd:网络管理
  • resolved:DNS解析

2.2 目录结构

/etc/systemd/system/    # 系统管理员创建的单元文件
/run/systemd/system/    # 运行时创建的单元文件
/usr/lib/systemd/system/    # 软件包安装的单元文件

3. Unit 配置文件

3.1 Unit类型

.service    # 服务单元
.socket     # 套接字单元
.device     # 设备单元
.mount      # 挂载点单元
.automount  # 自动挂载点
.swap       # 交换分区单元
.target     # 目标单元
.path       # 路径监控单元
.timer      # 定时器单元
.slice      # 资源管理单元
.scope      # 外部创建的进程

3.2 Service单元配置示例

[Unit]
Description=My Service
After=network.target
Requires=network.target

[Service]
Type=simple
ExecStart=/usr/bin/myapp
ExecStop=/usr/bin/myapp --stop
Restart=always
RestartSec=3
User=myuser
Group=mygroup

[Install]
WantedBy=multi-user.target

3.3 常用配置选项

Unit段
Description=    # 描述
Documentation=  # 文档地址
After=         # 在指定单元之后启动
Before=        # 在指定单元之前启动
Requires=      # 强依赖
Wants=         # 弱依赖,依赖失败不影响
Conflicts=     # 冲突单元
Service段
Type=          # 服务类型(simple/forking/oneshot/notify/dbus/idle)
ExecStart=     # 启动命令
ExecStop=      # 停止命令
ExecReload=    # 重载命令
Restart=       # 重启策略
RestartSec=    # 重启间隔
TimeoutSec=    # 超时时间
Environment=   # 环境变量
User=          # 运行用户
Group=         # 运行组
WorkingDirectory=  # 工作目录
Install段
WantedBy=      # 被哪些目标单元需要
RequiredBy=    # 被哪些单元强制需要
Alias=         # 别名
Also=          # 同时安装的其他单元

4. 服务生命周期管理

4.1 基本操作

# 启动服务
systemctl start service-name

# 停止服务
systemctl stop service-name

# 重启服务
systemctl restart service-name

# 重新加载配置
systemctl reload service-name

# 查看服务状态
systemctl status service-name

4.2 启动流程

  1. 解析Unit文件
  2. 检查依赖关系
  3. 启动依赖服务
  4. 执行ExecStartPre
  5. 执行ExecStart
  6. 执行ExecStartPost

4.3 停止流程

  1. 执行ExecStopPre
  2. 执行ExecStop
  3. 发送SIGTERM信号
  4. 等待进程退出
  5. 超时后发送SIGKILL
  6. 执行ExecStopPost

5. 服务依赖管理

5.1 依赖类型

Requires=      # 强依赖,依赖失败则失败
Wants=         # 弱依赖,依赖失败不影响
BindsTo=       # 绑定依赖,依赖停止则停止
Requisite=     # 先决条件,依赖必须已启动
PartOf=        # 组成部分,父服务停止则停止
Conflicts=     # 冲突单元,不能同时运行

5.2 依赖示例

[Unit]
Description=Web Application
After=network.target postgresql.service
Requires=postgresql.service
Wants=redis.service

6. 日志管理

6.1 查看日志

# 查看系统日志
journalctl

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

# 查看实时日志
journalctl -f

# 查看启动以来的日志
journalctl -b

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

6.2 日志配置

[Service]
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp
LogLevelMax=info

7. 资源管理

7.1 CPU限制

[Service]
CPUQuota=50%
CPUWeight=100
CPUAffinity=0,1

7.2 内存限制

[Service]
MemoryLimit=1G
MemoryHigh=800M
MemoryMax=1.2G

7.3 IO限制

[Service]
IOWeight=100
IODeviceWeight=/dev/sda 100
IOReadBandwidthMax=/dev/sda 5M

8. 实用技巧

8.1 服务模板

[Unit]
Description=Instance %i of MyApp
After=network.target

[Service]
ExecStart=/usr/bin/myapp --instance %i
User=myapp-%i

[Install]
WantedBy=multi-user.target

8.2 条件启动

[Unit]
AssertPathExists=/path/to/file
AssertFileNotEmpty=/path/to/config
ConditionPathIsMountPoint=/data

8.3 环境变量

[Service]
Environment=NODE_ENV=production
Environment=PORT=3000
EnvironmentFile=/etc/myapp/env

9. 故障排查

9.1 常见问题

# 查看失败的单元
systemctl --failed

# 查看特定服务的详细信息
systemctl show service-name

# 验证单元文件语法
systemd-analyze verify unit-file

# 查看启动时间
systemd-analyze blame

9.2 调试技巧

# 启用调试日志
systemctl status service-name -l

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

# 重置失败状态
systemctl reset-failed service-name

10. 安全建议

10.1 服务隔离

[Service]
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
NoNewPrivileges=true

10.2 资源限制

[Service]
LimitNOFILE=65535
LimitNPROC=200
LimitCORE=infinity

10.3 访问控制

[Service]
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
SecureBits=keep-caps

11. 进程树管理

11.1 进程树结构

# 查看完整的进程树
systemd-cgls

# 查看特定服务的进程树
systemctl status service-name --full

# 查看所有进程的cgroup层级
systemd-cgtop

11.2 控制组管理

[Service]
# 控制组设置
Slice=system.slice
Delegate=yes
# 子进程控制
KillMode=mixed
KillSignal=SIGTERM
SendSIGHUP=yes
SendSIGKILL=yes

11.3 进程控制选项

[Service]
# 进程生命周期控制
RemainAfterExit=no
GuessMainPID=yes
PIDFile=/run/myapp.pid
NonBlocking=yes

# 子进程管理
TasksMax=8192
TasksAccounting=yes

11.4 进程树清理

# 停止服务及其所有子进程
systemctl kill service-name

# 使用特定信号停止进程树
systemctl kill -s SIGTERM service-name

# 强制终止所有相关进程
systemctl kill -s SIGKILL service-name --kill-who=all

11.5 进程树监控

[Service]
# 监控设置
WatchdogSec=30s
Restart=on-failure
StartLimitIntervalSec=300
StartLimitBurst=5

# 进程状态通知
Type=notify
NotifyAccess=main

11.6 Cgroup控制

[Service]
# Cgroup资源控制
CPUAccounting=yes
MemoryAccounting=yes
IOAccounting=yes
TasksAccounting=yes

# Cgroup命名空间
PrivateMounts=yes
ProtectControlGroups=yes

11.7 进程树示例

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

[Service]
Type=forking
PIDFile=/run/webapp.pid
ExecStart=/usr/bin/webapp start
ExecStop=/usr/bin/webapp stop
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=30
Restart=on-failure

# 进程树控制
TasksMax=infinity
Delegate=yes
RemainAfterExit=no

# Cgroup设置
Slice=system-webapp.slice
CPUAccounting=yes
MemoryAccounting=yes

# 子进程管理
GuessMainPID=yes
NonBlocking=yes

[Install]
WantedBy=multi-user.target

11.8 故障排查技巧

# 查看进程树状态
ps axf

# 查看特定服务的cgroup信息
systemctl show service-name -p ControlGroup

# 检查进程资源使用
systemd-cgtop -p

# 查看进程树限制
systemctl show service-name -p TasksMax

# 分析进程关系
pstree -p `pidof service-name`