Enzo Li @ eynzof.com

Systemd 入门

2019.08.16

概述


Ubuntu 18.04不再使用init.d,而是使用systemd来管理启动项,网络上的教程很多已经不再适用。 Systemd是Linux系统的一个工具,用于启动<守护进程>,2015年后,大多数发行版已经内置这一工具。它已经替代了管理守护进程的init.drc.d,ubuntu18已经移除init.d。 Systemd中的d代指daemon(守护进程),System D 也是一个英语常用语,意指对问题快速处理的能力。


 # 查看systemd版本
 systemctl --version

系统管理


Systemd不是一个命令,而是一组命令,包含了管理系统的各个功能。

systemctl

主命令,用于从硬件方面管理系统


 # 重启系统
 sudo systemctl reboot

 # 关闭系统
 sudo systemctl poweroff

 # 终止所有进程,并关闭CPU
 sudo systemctl halt

 # 暂停系统
 sudo systemctl suspend

 # 使系统进入休眠模式
 sudo systemctl suspend

 # 使系统进入交互式休眠系统
 sudo systemctl hybrid-sleep

 # 进入安全模式
 sudo systemctl rescue

halt terminates all processes and shuts down the cpu. poweroff is exactly like halt, but it also turns off the unit itself(lights and everything on a PC).

systemd-analyze

用于查看启动耗时


# 查看启动耗时
systemd-analyze

# 查看每个服务的启动耗时
systemd-analyze blame

# 显示启动链
systemd-analyze critical-chain

# 显示指定服务的启动链
systemd-analyze critical-chain atd.service

hostnamectl

用于查看当前主机信息


# 查看本地化设置
localectl

# 设置本地化参数。
sudo localectl set-locale LANG=en_GB.utf8
sudo localectl set-keymap en_GB

timedatectl

查看时区设置


# 查看当前时区设置
timedatectl

# 显示所有可用的时区
timedatectl list-timezones

# 设置当前时区
sudo timedatectl set-timezone America/New_York
sudo timedatectl set-time YYYY-MM-DD
sudo timedatectl set-time HH:MM:SS

loginctl

查看当前登录的用户


# 列出当前session
loginctl list-sessions

# 列出当前登录用户
loginctl list-users

# 列出显示指定用户的信息
loginctl show-user [username]

Unit


定义

Systemd可以管理所有系统资源,这些资源统称为Unit。

以下是unit的分类

  • .service 系统服务
  • .socket 进程通信的socket
  • .device 硬件设备
  • .mount 文件系统挂载点
  • .automount 自动挂载点
  • .swap swap文件
  • .target 多个unit组成的组
  • .path 文件或文件路径
  • .timer 定时器
  • .snapshot systemd的快照,可来回切换
  • .slice 进程组,用来管理进程和资源
  • .scope 非systemd启动的外部进程

使用子指令list-units可以查看当前系统的所有unit


# 列出正在运行的 Unit
systemctl list-units

# 列出所有Unit,包括没有找到配置文件的或者启动失败的
systemctl list-units --all

# 列出所有没有运行的 Unit
systemctl list-units --all --state=inactive

# 列出所有加载失败的 Unit
systemctl list-units --failed

# 列出所有正在运行的、类型为 service 的 Unit
systemctl list-units --type=service

查看Unit状态


子指令systemctl status,可用于查看系统/unit状态


# 显示系统状态
systemctl status

# 显示单个 Unit 的状态
sysystemctl status bluetooth.service

# 显示远程主机的某个 Unit 的状态
systemctl -H root@example.com status httpd.service

以上指令主要供shell使用,systemctl还提供了三个供脚本内部使用的查询指令


# 显示某个 Unit 是否正在运行
systemctl is-active application.service

# 显示某个 Unit 是否处于启动失败状态
systemctl is-failed application.service

# 显示某个 Unit 服务是否建立了启动链接
systemctl is-enabled application.service

管理Unit


以下指令用于启动/停止Unit,最常使用的是service


# 启动服务
$ sudo systemctl start apache.service

# 停止服务
sudo systemctl stop apache.service

# 重启服务
sudo systemctl restart apache.service

# 杀死服务的所有子进程
sudo systemctl kill apache.service

# 重新加载服务的配置文件
sudo systemctl reload apache.service

# 重载所有修改过的配置文件
sudo systemctl daemon-reload

# 显示某个 Unit 的所有底层参数
systemctl show httpd.service

# 显示某个 Unit 的指定属性的值
systemctl show -p CPUShares httpd.service

# 设置某个 Unit 的指定属性
sudo systemctl set-property httpd.service CPUShares=500

Unit的依赖关系


A依赖于B,则systemd启动A时同时启动B


 # 列出某个Unit的所有依赖
 systemctl list-dependencies nginx.service

 # 某些依赖为Target类型,默认不展开显示
 systemctl list-dependencies -all nginx.service

注册开机启动脚本


使用rc.local作为启动脚本,补充必要的Install


# rc.local在systemd中的位置
sudo cd /lib/systemd/system

# 文件内容
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

# This unit gets pulled automatically into multi-user.target by
# systemd-rc-local-generator if /etc/rc.local is executable.

[Unit]
Description=/etc/rc.local Compatibility
ConditionFileIsExecutable=/etc/rc.local
After=network.target

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes

一般的启动配置文件主要分为三部分

  • Unit 启动顺序与依赖关系
  • Service 启动行为/方式/类型
  • Install 如何安装这个启动配置文件

After=network.target得知启动顺序在网络后面,这个配置文件缺少Install

需要为其添加


[Install]
WantedBy=multi-user.target
Alias=rc-local.service

这里需要注意,Ubuntu-18.04是不自带/etc/rc.local文件的,需要自己创建

sudo touch /etc/rc.local

然后把需要启动的脚本写入/etc/rc.local,比如

/home/masonic9/shiori/shiori serve

最后一步。前面我们说 systemd 默认读取 /etc/systemd/system 下的配置文件, 所以还需要在 /etc/systemd/system 目录下创建软链接

 sudo ln -s /lib/systemd/system/rc.local.service /etc/systemd/system/

注册开机启动应用


以shiori为例,在/lib/systemd/system新建一个shiori.service文件,写入以下内容。


[Unit]
Description=Shiori Server

[Service]
type=forking
ExecStart=/home/masonic9/shiori/shiori serve # 应用绝对路径,含启动参数
After=network.target # 在网络启动后启用
# 如果需要自动重启功能
# Restart=always
# RestartSec=3

[Install]
WantedBy=multi-user.target # 运行级别
Alias=shiori.service # 服务名称

启用服务

systemctl enable shiori.service

启动服务

systemctl start shiori.service

查询服务是否成功启动

systemctl status shiori.service

需要修改配置文件的话,修改完后执行以下命令重载

systemctl daemon-reload

补充


在安装了shiori服务后,我发现原来的账户登不上去了。使用journalctl命令查看发现,shiori以root用户运行,可能shiori内部在root目录下另行创建了一套系统


# 查看service运行记录
sudo journalctl -xe

要解决这一问题,以masonic9用户运行即可,参阅参考资料。

WantedBy相关知识


Run Lvl Target Units                        Description
0       runlevel0.target, poweroff.target   Shut down and power off
1       runlevel1.target, rescue.target     Set up a rescue shell
2,3,4   runlevel[234].target,               Set up a non-gfx multi-user shell
        multi-user.target
5       runlevel5.target, graphical.target  Set up a gfx multi-user shell
6       runlevel6.target, reboot.target     Shut down and reboot the system

参考资料