tl;dr
应用场景:对日常系统启动过程进行管理,优化启动速度。
1. systemd原理
1.1 基础概念-Unit
Systemd将系统初始化过程中所有的操作步骤都被抽象为Unit 对应于之前SysVinit时代的Daemon的超集
,根据不同的操作内容,Unit被细分为多个分类:
- service :
类似于SysVinit时代的Daemon
,代表一个后台服务进程,比如 mysqld。这是最常用的一类。
- target :
Unit组
。此类配置单元为其他配置单元进行逻辑分组。它们本身实际上并不做什么,只是引用其他配置单元而已。这样便可以对配置单元做一个统一的控制。这样就可以实现大家都已经非常熟悉的运行级别概念。比如想让系统进入图形化模式,需要运行许多服务和配置命令,这些操作都由一个个的配置单元表示,将所有这些配置单元组合为一个目标(target),就表示需要将这些配置单元全部执行一遍以便进入目标所代表的系统运行状态。 (例如:multi-user.target 相当于在传统使用 SysV 的系统中运行级别 5) - 其他Unit
- timer:定时器配置单元用来定时触发用户定义的操作,这类配置单元取代了 atd、crond 等传统的定时服务。
- snapshot :与 target 配置单元相似,快照是一组配置单元。它保存了系统当前的运行状态。
- socket :此类配置单元封装系统和互联网中的一个 套接字 。当下,systemd 支持流式、数据报和连续包的 AF_INET、AF_INET6、AF_UNIX socket 。每一个套接字配置单元都有一个相应的服务配置单元 。相应的服务在第一个"连接"进入套接字时就会启动(例如:nscd.socket 在有新连接后便启动 nscd.service)。
- device :此类配置单元封装一个存在于 Linux 设备树中的设备。每一个使用 udev 规则标记的设备都将会在 systemd 中作为一个设备配置单元出现。
- mount :此类配置单元封装文件系统结构层次中的一个挂载点。Systemd 将对这个挂载点进行监控和管理。比如可以在启动时自动将其挂载;可以在某些条件下自动卸载。Systemd 会将/etc/fstab 中的条目都转换为挂载点,并在开机时处理。
- automount :此类配置单元封装系统结构层次中的一个自挂载点。每一个自挂载配置单元对应一个挂载配置单元 ,当该自动挂载点被访问时,systemd 执行挂载点中定义的挂载行为。
- swap: 和挂载配置单元类似,交换配置单元用来管理交换分区。用户可以用交换配置单元来定义系统中的交换分区,可以让这些交换分区在启动时被激活。
Unit落地到实体就是Unit配置文件,文件名后缀就是该Unit的类型名字。
1.2 相关目录和文件
- /etc/systemd/ 开机启动的unit配置文件们,一般都是符号连接到/lib/systemd/
- /lib/systemd/ 所有的unit配置文件们
1.3 Systemd做了那些牛逼的事情
-
提高并发启动能力,加快了系统启动时间
按需启动服务
Systemd 可以提供按需启动的能力,只有在某个服务被真正请求的时候才启动它。当该服务结束,systemd 可以关闭它,等待下次需要时再次启动它。
- System解决Unit依赖和事物处理
每个Unit的配置文件都会指定其运行所需的依赖关系(Unit配置文件中[Unit]字段描述),依赖关系有两种:
- Requires 强依赖,依赖的Unit如果不能正常启动,则配置的这个Unit也启动失败
-
Wants 弱依赖,依赖的Unit如果不能正常启动,则不影响这个Unit的启动
Unit一旦形成循环依赖,systemd 将尝试去掉 wants 关键字指定的依赖看看是否能打破循环。如果无法修复,systemd 会报错:
Unit配置文件强弱依赖示例:
$ systemctl cat sshd.service
[Unit]
Before=a.service 指定启动顺序,在之前启动
After=network.target sshd-keygen.service 指定启动顺序,在之后启动
Wants=sshd-keygen.service 指定弱依赖关系
Requires=bb.service 指定强依赖关系
Unit配置文件所在的同目录下,有可能会有同名的.wants子目录,该子目录下的文件等同于Unit配置文件的Wants字段,指定弱依赖关系需要的Unit:
ray@ray-ThinkPad-X250:/lib/systemd/system$ ls -al | grep .wants -C 2
-rw-r--r-- 1 root root 879 Oct 2 16:33 basic.target
drwxr-xr-x 2 root root 4096 Oct 14 23:09 basic.target.wants
-rw-r--r-- 1 root root 358 Oct 2 16:33 busnames.target
drwxr-xr-x 2 root root 4096 Oct 14 23:05 busnames.target.wants
-rw-r--r-- 1 root root 585 Oct 2 16:33 system-update.target
drwxr-xr-x 2 root root 4096 Oct 14 23:13 system-update.target.wants
-rw-r--r-- 1 root root 405 Oct 2 16:33 timers.target
drwxr-xr-x 2 root root 4096 Oct 14 23:05 timers.target.wants
2. Systemd的日常使用
2.1 systemd的使用效果
ray@ray-ThinkPad-X250:/etc/systemd$ ps -ef | head
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Oct17 ? 00:00:02 /sbin/init splash
root 2 0 0 Oct17 ? 00:00:00 [kthreadd]
root 3 2 0 Oct17 ? 00:00:00 [ksoftirqd/0]
root 5 2 0 Oct17 ? 00:00:00 [kworker/0:0H]
root 7 2 0 Oct17 ? 00:00:08 [rcu_sched]
root 8 2 0 Oct17 ? 00:00:00 [rcu_bh]
root 9 2 0 Oct17 ? 00:00:00 [migration/0]
root 10 2 0 Oct17 ? 00:00:00 [lru-add-drain]
root 11 2 0 Oct17 ? 00:00:00 [watchdog/0]
ray@ray-ThinkPad-X250:/etc/systemd$ ls -al /sbin/init
lrwxrwxrwx 1 root root 20 Oct 2 16:33 /sbin/init -> /lib/systemd/systemd
ray@ray-ThinkPad-X250:/etc/systemd$
2.2 systemctl 命令
1. 查看指定Unit状态
Unit开机启动状态(对应Loaded行)
- enabled:开机启动
- disabled:开机不启动
- static:静态被动服务,不能被设置为enable和disable,只能被其他enabled的服务调用
- mask:隐藏状态,不能被启动(开机自动、人工操作)。
可透過 systemctl unmask 命令将其回复正常状态
Unit当前运行状态(对应Active行)
- active (running):Unit正在运行。
- active (exited):Unit运行一次,且正常结束。如Bash脚本,无需常驻内存的Unit。
- active (waiting):Unit正在运行,且正在等候其他事物的交互。如打印机。
- inactive:Unit没有在运行。
disabled状态和mask状态区别
disabled示例:
mask示例:
2. 查看所有Unit状态
- systemctl list-units [--type=TYPE] [--all] 列出所有加载的Unit
ray@ray-ThinkPad-X250:~$ systemctl list-units | head
UNIT LOAD ACTIVE SUB DESCRIPTION
proc-sys-fs-binfmt_misc.automount loaded active running Arbitrary Executable File Formats File System Automount Point
sys-devices-pci0000:00-0000:00:02.0-drm-card0-card0\x2deDP\x2d1-intel_backlight.device loaded active plugged /sys/devices/pci0000:00/0000:00:02.0/drm/card0/card0-eDP-1/intel_backlight
sys-devices-pci0000:00-0000:00:03.0-sound-card0.device loaded active plugged Broadwell-U Audio Controller
sys-devices-pci0000:00-0000:00:14.0-usb2-2\x2d7-2\x2d7:1.0-bluetooth-hci0.device loaded active plugged /sys/devices/pci0000:00/0000:00:14.0/usb2/2-7/2-7:1.0/bluetooth/hci0
sys-devices-pci0000:00-0000:00:19.0-net-enp0s25.device loaded active plugged Ethernet Connection (3) I218-LM
sys-devices-pci0000:00-0000:00:1b.0-sound-card1.device loaded active plugged Wildcat Point-LP High Definition Audio Controller
sys-devices-pci0000:00-0000:00:1c.1-0000:03:00.0-net-wlp3s0.device loaded active plugged Wireless 7265 (Wireless-N 7265)
sys-devices-pci0000:00-0000:00:1f.2-ata1-host0-target0:0:0-0:0:0:0-block-sda-sda1.device loaded active plugged SanDisk_SDSSDXPS480G 1
sys-devices-pci0000:00-0000:00:1f.2-ata1-host0-target0:0:0-0:0:0:0-block-sda-sda2.device loaded active plugged SanDisk_SDSSDXPS480G 2
ray@ray-ThinkPad-X250:~$
- systemctl list-unit-files [--type=TYPE] 列出所有安装的Unit
ray@ray-ThinkPad-X250:~$ systemctl list-unit-files | head
UNIT FILE STATE
proc-sys-fs-binfmt_misc.automount static
-.mount generated
boot.mount generated
dev-hugepages.mount static
dev-mqueue.mount static
proc-sys-fs-binfmt_misc.mount static
snap-ubuntu\x2dcore-216.mount enabled
snap-ubuntu\x2dcore-352.mount enabled
snap-ubuntu\x2dcore-423.mount enabled
ray@ray-ThinkPad-X250:~$
ray@ray-ThinkPad-X250:~$ systemctl list-unit-files --type=socket
UNIT FILE STATE
acpid.socket enabled
apport-forward.socket enabled
avahi-daemon.socket enabled
cups.socket enabled
dbus.socket static
dm-event.socket enabled
lvm2-lvmetad.socket enabled
lvm2-lvmpolld.socket enabled
saned.socket disabled
snapd.socket enabled
syslog.socket static
systemd-fsckd.socket static
systemd-initctl.socket static
systemd-journald-audit.socket static
systemd-journald-dev-log.socket static
systemd-journald.socket static
systemd-networkd.socket disabled
systemd-rfkill.socket static
systemd-udevd-control.socket static
systemd-udevd-kernel.socket static
uuidd.socket enabled
21 unit files listed.
ray@ray-ThinkPad-X250:~$
3. 查看target(Unit组)的状态及切换
systemd将多个Unit归类到target,以方便实现批量的操作。
在启动阶段的target对应于SysVinit里的init 1/2/3/5等模式下的一些列操作。
查看启动的target:
ray@ray-ThinkPad-X250:~$ systemctl list-units --type=target
UNIT LOAD ACTIVE SUB DESCRIPTION
basic.target loaded active active Basic System
cryptsetup.target loaded active active Encrypted Volumes
getty.target loaded active active Login Prompts
graphical.target loaded active active Graphical Interface
local-fs-pre.target loaded active active Local File Systems (Pre)
local-fs.target loaded active active Local File Systems
multi-user.target loaded active active Multi-User System
network.target loaded active active Network
nss-user-lookup.target loaded active active User and Group Name Lookups
paths.target loaded active active Paths
remote-fs.target loaded active active Remote File Systems
slices.target loaded active active Slices
sockets.target loaded active active Sockets
sound.target loaded active active Sound Card
swap.target loaded active active Swap
sysinit.target loaded active active System Initialization
time-sync.target loaded active active System Time Synchronized
timers.target loaded active active Timers
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
18 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
ray@ray-ThinkPad-X250:~$
target为了实现与SysVinit的兼容,建立了一些runlevel的target,与init对应:
ray@ray-ThinkPad-X250:~$ ll -d /lib/systemd/system/runlevel*.target
lrwxrwxrwx 1 root root 15 Oct 2 16:33 /lib/systemd/system/runlevel0.target -> poweroff.target
lrwxrwxrwx 1 root root 13 Oct 2 16:33 /lib/systemd/system/runlevel1.target -> rescue.target
lrwxrwxrwx 1 root root 17 Oct 2 16:33 /lib/systemd/system/runlevel2.target -> multi-user.target
lrwxrwxrwx 1 root root 17 Oct 2 16:33 /lib/systemd/system/runlevel3.target -> multi-user.target
lrwxrwxrwx 1 root root 17 Oct 2 16:33 /lib/systemd/system/runlevel4.target -> multi-user.target
lrwxrwxrwx 1 root root 16 Oct 2 16:33 /lib/systemd/system/runlevel5.target -> graphical.target
lrwxrwxrwx 1 root root 13 Oct 2 16:33 /lib/systemd/system/runlevel6.target -> reboot.target
ray@ray-ThinkPad-X250:~$
切换target:
systemctl isolate multi-user.target
systemctl isolate graphical.target
获取、设置默认的target
ray@ray-ThinkPad-X250:~$ systemctl get-default
graphical.target
ray@ray-ThinkPad-X250:~$ systemctl set-default multi-user.target
4. 查看Unit依赖关系
systemctl list-dependencies [unit] [--reverse]
ray@ray-ThinkPad-X250:~$ systemctl get-default
graphical.target
ray@ray-ThinkPad-X250:~$
ray@ray-ThinkPad-X250:~$ systemctl list-dependencies
default.target
● ├─accounts-daemon.service
● ├─apport.service
● ├─grub-common.service
● ├─irqbalance.service
● ├─lightdm.service
● ├─speech-dispatcher.service
● ├─systemd-update-utmp-runlevel.service
● ├─ureadahead.service
● └─multi-user.target
● ├─anacron.service
● ├─apport.service
● ├─avahi-daemon.service
ray@ray-ThinkPad-X250:~$ systemctl list-dependencies multi-user.target
multi-user.target
● ├─anacron.service
● ├─apport.service
● ├─avahi-daemon.service
● ├─binfmt-support.service
● ├─cgmanager.service
● ├─cgproxy.service
● ├─click-system-hooks.service
● ├─cron.service
● ├─cups-browsed.service
ray@ray-ThinkPad-X250:~$ systemctl list-dependencies multi-user.target --reverse
multi-user.target
● ├─failsafe-graphical.target
● └─graphical.target
ray@ray-ThinkPad-X250:~$
2.3 systemd-analyze命令
systemd-analyze 启动时间汇总信息
systemd-analyze blame 启动时间列表信息
systemd-analyze critical-chain 启动时间列表信息(以依赖方式组织)
systemd-analyze critical-chain atd.service
ray@ray-ThinkPad-X250:~$ systemd-analyze
Startup finished in 5.189s (kernel) + 7.155s (userspace) = 12.344s
ray@ray-ThinkPad-X250:~$ systemd-analyze blame
5.153s nmbd.service
3.725s snapd.refresh.service
1.014s apt-daily.service
798ms dev-mapper-ubuntu\x2d\x2dvg\x2droot.device
644ms user@1000.service
630ms click-system-hooks.service
477ms lightdm.service
474ms networking.service
459ms plymouth-quit-wait.service
318ms snapd.firstboot.service
304ms lvm2-monitor.service
267ms systemd-udev-trigger.service
248ms dev-loop1.device
245ms dev-loop0.device
233ms vboxdrv.service
228ms dev-loop2.device
205ms apparmor.service
187ms systemd-resolved.service
152ms winbind.service
135ms keyboard-setup.service
132ms systemd-timesyncd.service
130ms irqbalance.service
116ms systemd-tmpfiles-setup.service
110ms binfmt-support.service
108ms thermald.service
107ms speech-dispatcher.service
105ms systemd-logind.service
97ms apport.service
94ms smbd.service
82ms grub-common.service
ray@ray-ThinkPad-X250:~$ systemd-analyze critical-chain
The time after the unit is active or started is printed after the "@" character.
The time the unit takes to start is printed after the "+" character.
graphical.target @7.121s
└─multi-user.target @7.121s
└─nmbd.service @1.967s +5.153s
└─network.target @1.949s
└─wpa_supplicant.service @2.650s +10ms
└─basic.target @1.477s
└─sockets.target @1.476s
└─snapd.socket @1.449s +26ms
└─sysinit.target @1.448s
└─apparmor.service @1.243s +205ms
└─local-fs.target @1.178s
└─boot.mount @1.166s +11ms
└─systemd-fsck@dev-disk-by\x2duuid-256c30d5\x2d2af9\x2d41c
└─dev-disk-by\x2duuid-256c30d5\x2d2af9\x2d41ca\x2d971d\x
2.4 systemd中其他好用的命令集
ray@ray-ThinkPad-X250:~$ hostnamectl
Static hostname: ray-ThinkPad-X250
Icon name: computer-laptop
Chassis: laptop
Machine ID: 0f17fde0902045bcbe0695d043c66c95
Boot ID: f0058c222353453f84a33e925e145263
Operating System: Ubuntu 16.10
Kernel: Linux 4.8.0-25-generic
Architecture: x86-64
ray@ray-ThinkPad-X250:~$
ray@ray-ThinkPad-X250:~$
ray@ray-ThinkPad-X250:~$ hostnamectl
Static hostname: ray-ThinkPad-X250
Icon name: computer-laptop
Chassis: laptop
Machine ID: 0f17fde0902045bcbe0695d043c66c95
Boot ID: f0058c222353453f84a33e925e145263
Operating System: Ubuntu 16.10
Kernel: Linux 4.8.0-25-generic
Architecture: x86-64
ray@ray-ThinkPad-X250:~$
ray@ray-ThinkPad-X250:~$ localectl
System Locale: LANG=en_US.UTF-8
LC_NUMERIC=zh_CN.UTF-8
LC_TIME=zh_CN.UTF-8
LC_MONETARY=zh_CN.UTF-8
LC_PAPER=zh_CN.UTF-8
LC_NAME=zh_CN.UTF-8
LC_ADDRESS=zh_CN.UTF-8
LC_TELEPHONE=zh_CN.UTF-8
LC_MEASUREMENT=zh_CN.UTF-8
LC_IDENTIFICATION=zh_CN.UTF-8
VC Keymap: us
X11 Layout: us
X11 Model: pc105
ray@ray-ThinkPad-X250:~$
ray@ray-ThinkPad-X250:~$ timedatectl
Local time: Tue 2016-10-18 15:51:42 CST
Universal time: Tue 2016-10-18 07:51:42 UTC
RTC time: Tue 2016-10-18 07:51:42
Time zone: Asia/Shanghai (CST, +0800)
Network time on: yes
NTP synchronized: yes
RTC in local TZ: no
ray@ray-ThinkPad-X250:~$
ray@ray-ThinkPad-X250:~$ loginctl
SESSION UID USER SEAT
c2 1000 ray seat0
1 sessions listed.
ray@ray-ThinkPad-X250:~$
ray@ray-ThinkPad-X250:~$
ray@ray-ThinkPad-X250:~$ loginctl list-sessions
SESSION UID USER SEAT
c2 1000 ray seat0
1 sessions listed.
ray@ray-ThinkPad-X250:~$
ray@ray-ThinkPad-X250:~$ loginctl list-users
UID USER
1000 ray
1 users listed.
ray@ray-ThinkPad-X250:~$
ray@ray-ThinkPad-X250:~$ who
ray tty7 2016-10-17 21:19 (:0)
ray@ray-ThinkPad-X250:~$
ray@ray-ThinkPad-X250:~$ who -a
system boot 2016-10-17 21:19
LOGIN tty1 2016-10-17 21:19 1272 id=tty1
run-level 5 2016-10-17 21:19
ray + tty7 2016-10-17 21:19 18:32 2017 (:0)
ray@ray-ThinkPad-X250:~$
ray@ray-ThinkPad-X250:~$
2.5 Systemd和SysVinit对应关系表
参考URL
systemd 官方wiki
SysVinit to Systemd Cheatsheet
IBM 浅析 Linux 初始化 init 系统,第 3 部分: Systemd
The Self-Explanatory Boot
鳥哥的 Linux 私房菜 第十七章、認識系統服務 (daemons)
鳥哥的 Linux 私房菜 第十九章、開機流程、模組管理與 Loader
Linux 守护进程的启动方法
Systemd 入门教程:命令篇
Systemd 入门教程:实战篇
理解Systemd单元和单元文件
systemd详解