Too young, too simple. Sometimes, naive & stupid

强迫将自己的操作迁移到Systemd(一)

很久没更新博客了,原因有一下几个, 一是写这个东西真得很耗时(就算是借鉴博客文档),二是报了个自考(3月份报的4科,4月份考试),结果今天连考试都没去,因为书都没看完。

Systemd 并不是简单的把service、chkconfig等变成systemctl,而是管天管地管空气;为什么要强迫自己使用systemd?作为菜鸡的我,始终坚信,不管装什么软件都是用最新的,一方面能使自己体验到最新的技术(当然也会掉进深渊大坑),一方面强迫自己不去搜现成的博客,防止自己跟着大佬的脚步,一路复制粘贴就成功。

最近发现自己真得是什么都不会,你看别人工程师介绍自己的时候, 都可以说自己是xx工程师, 比如网络,安全存储系统 ,别人一问我 “你是做什么的阿?”,我只能说:“emmmm,就打打杂。”其实内心想说自己会linux, 然而 根本就不会阿, 任何一个模块 追踪到细节都不怎么了解,(当然了,有些模块压根就不知道)算下来,我也就是会 apt yum , 会 servce systemctl 会 ls rm ,还会终极神器(reboot) ,我要开始下一阶段的学习了,开始学习一些细节,以后好吹逼,今天,我们从systemd开始。

systemd是什么?

systemd是一套Linux系统的基本构建模块。它提供了一个作为PID 1运行的系统和服务管理器,并启动系统的其余部分。systemd提供了积极的并行化功能,使用套接字和D-Bus激活来启动服务,提供按需启动守护进程,使用Linux控制组跟踪进程,维护挂载和自动挂载点,并实现精心设计的基于事务的基于依赖关系的服务控制逻辑。systemd支持SysV和LSB初始化脚本,并作为sysvinit的替代品。其他部分包括日志守护程序,用于控制基本系统配置的实用程序,如主机名,日期,区域设置,维护登录用户列表以及运行容器和虚拟机,系统帐户,运行时目录和设置以及守护进程以管理简单网络配置,网络时间同步,日志转发和名称解析。

比较Linux的三个最相关的init系统:sysvinit,Upstart和systemd

常规特性

sysvinit Upstart systemd
通过D-Bus连接 no yes yes
无壳启动 no no yes
包括模块化C编码的早期启动服务 no no yes
预读 no no yes
基于Socket的激活 no no yes
基于Socket的激活:inetd兼容性 no no yes
基于总线的激活 no no yes
基于设备的激活 no no yes
使用udev规则配置设备依赖关系 no no yes
基于路径的激活(inotify) no no yes
基于计时器的激活 no no yes
装载处理 no no yes
fsck处理 no no yes
配额处理 no no yes
自动处理 no no yes
交换处理 no no yes
系统状态的快照 no no yes
XDG_RUNTIME_DIR支持 no no yes
可选地杀死剩余的用户注销进程 no no yes
Linux控制组集成 no no yes
为启动的服务生成审计记录 no no yes
SELinux集成 no no yes
PAM整合 no no yes
加密的硬盘处理(LUKS) no no yes
SSL证书/ LUKS密码处理,包括 Plymouth,console,wall,TTY和GNOME代理 no no yes
网络环回设备处理 no no yes
binfmt_misc处理 no no yes
系统范围的区域设置处理 no no yes
控制台和键盘设置 no no yes
用于创建,删除,清理临时和不稳定文件的基础架构 no no yes
处理/proc/sys/sysctl no no yes
普利茅斯整合 no yes yes
保存/恢复随机种子 no no yes
内核模块的静态加载 no no yes
自动串行控制台处理 no no yes
独特的机器ID处理 no no yes
动态主机名称和机器元数据处理 no no yes
可靠的终止服务 no no yes
早期启动/dev/log日志记录 no no yes
最小的基于kmsg的syslog守护进程用于嵌入式使用 no no yes
重新生成服务崩溃而不会丢失连接 no no yes
无缝升级服务 no no yes
图形用户界面 no no yes
内置的分析和工具 no no yes
实例化服务 no yes yes
PolicyKit集成 no no yes
客户端工具内置的远程访问/群集支持 no no yes
可以列出服务的所有进程 no no yes
可以识别进程的服务 no no yes
自动每个服务CPU cgroups可以平衡它们之间的CPU使用率 no no yes
自动每个用户的cgroups no no yes
SysV兼容性 yes yes yes
SysV服务可以像本地服务一样进行控制 yes no yes
SysV兼容/dev/initctl yes no yes
完全序列化状态重新执行 yes no yes
交互式启动 no no0 yes
容器支持(作为高级chroot()替换) no no yes
基于依赖关系的启动 no no yes
无需编辑文件即可禁用服务 yes no yes
无需编辑文件即可屏蔽服务 no no yes
强大的系统在PID 1内关闭 no no yes
内置kexec支持 no no yes
动态服务生成 no no yes
上游支持各种其他操作系统组件 yes no yes
服务文件在发行版之间兼容 no no yes
信号传递到服务 no no yes
在关机前可靠地终止用户会话 no no yes
utmp/wtmp支持 yes yes yes
轻松可写,可扩展和可解析的服务文件,适用于使用企业管理工具进行操作 no no yes

可用的本地服务设置

sysvinit Upstart systemd
OOM 调整 no yes yes
工作目录 no yes yes
根目录 (chroot()) no yes yes
环境变量 no yes yes
环境变量(来自外部的文件) no no yes
资源限制 no some yes
umask no yes yes
User/Group/Supplementary Groups no no yes
IO调度类/优先级 no no yes
CPU Scheduling Nice Value no yes yes
CPU Scheduling Policy/Priority no no yes
CPU Scheduling Reset on fork() control no no yes
CPU affinity no no yes
Timer Slack no no yes
功能Control no no yes
安全位 Control no no yes
Control Group Control no no yes
High-level file system namespace control: making directories inacessible no no yes
High-level file system namespace control: making directories read-only no no yes
High-level file system namespace control: private /tmp no no yes
High-level file system namespace control: mount inheritance no no yes
Input on Console yes yes yes
Output on Syslog no no yes
Output on kmsg/dmesg no no yes
Output on arbitrary TTY no no yes
Kill signal control no no yes
Conditional execution: by identified CPU virtualization/container no no yes
Conditional execution: by file existance no no yes
Conditional execution: by security framework no no yes
Conditional execution: by kernel command line no no yes

关于Systemd的管理

启动

传统上,启动Linux系统时,屏幕上会显示很多小消息。当我们致力于加速和平行启动过程时,这些消息只能在更短和更短的时间内看到,并且可读性越来越差 - 如果完全显示它们,我们现在使用像普利茅斯这样的图形启动闪屏技术。尽管如此,启动屏幕的信息仍然非常相关,因为它显示了每个启动过程中正在启动的服务,它是否启动成功或失败(使用绿色或红色 [OK][失败]指标)。为了改善启动快速和并行化的机器的情况,并使这些信息在运行时更好地提供,我们向systemd添加了一项功能,该功能跟踪并记住每个服务是否启动成功,是否以非零退出代码,是否超时,是否在启动和运行时都异常终止(通过段错误或类似方式)。只需在shell中输入systemctl,就可以查询所有服务的状态,包括systemd native和SysV/LSB服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
[root@kubernetes-node1 ~]# systemctl
UNIT LOAD ACTIVE SUB DESCRIPTION
proc-sys-fs-binfmt_misc.automount loaded active waiting Arbitrary Executable File Formats File System Automount Point
sys-devices-pci0000:00-0000:00:11.0-0000:02:01.0-ata1-host1-target1:0:0-1:0:0:0-block-sr0.device loaded active plugged VMware_Virtual_SATA_CDRW_Drive
sys-devices-pci0000:00-0000:00:15.0-0000:03:00.0-host0-target0:0:0-0:0:0:0-block-sda-sda1.device loaded active plugged Virtual_disk 1
sys-devices-pci0000:00-0000:00:15.0-0000:03:00.0-host0-target0:0:0-0:0:0:0-block-sda-sda2.device loaded active plugged LVM PV KJs0yz-aG67-nkFK-eELZ-LiLs-K
sys-devices-pci0000:00-0000:00:15.0-0000:03:00.0-host0-target0:0:0-0:0:0:0-block-sda.device loaded active plugged Virtual_disk
sys-devices-pci0000:00-0000:00:16.0-0000:0b:00.0-net-ens192.device loaded active plugged VMXNET3 Ethernet Controller
sys-devices-platform-floppy.0-block-fd0.device loaded active plugged /sys/devices/platform/floppy.0/block/fd0
sys-devices-platform-serial8250-tty-ttyS0.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS0
sys-devices-platform-serial8250-tty-ttyS1.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS1
sys-devices-platform-serial8250-tty-ttyS2.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS2
sys-devices-platform-serial8250-tty-ttyS3.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS3
sys-devices-virtual-block-dm\x2d0.device loaded active plugged /sys/devices/virtual/block/dm-0
sys-devices-virtual-block-dm\x2d1.device loaded active plugged /sys/devices/virtual/block/dm-1
sys-devices-virtual-net-cni0.device loaded active plugged /sys/devices/virtual/net/cni0
sys-devices-virtual-net-docker0.device loaded active plugged /sys/devices/virtual/net/docker0
sys-devices-virtual-net-flannel.1.device loaded active plugged /sys/devices/virtual/net/flannel.1
sys-devices-virtual-net-veth551eaded.device loaded active plugged /sys/devices/virtual/net/veth551eaded
sys-module-configfs.device loaded active plugged /sys/module/configfs
sys-subsystem-net-devices-cni0.device loaded active plugged /sys/subsystem/net/devices/cni0
sys-subsystem-net-devices-docker0.device loaded active plugged /sys/subsystem/net/devices/docker0
sys-subsystem-net-devices-ens192.device loaded active plugged VMXNET3 Ethernet Controller
sys-subsystem-net-devices-flannel.1.device loaded active plugged /sys/subsystem/net/devices/flannel.1
sys-subsystem-net-devices-veth551eaded.device loaded active plugged /sys/subsystem/net/devices/veth551eaded
-.mount loaded active mounted /
boot.mount loaded active mounted /boot
dev-hugepages.mount loaded active mounted Huge Pages File System
dev-mqueue.mount loaded active mounted POSIX Message Queue File System
run-user-0.mount loaded active mounted /run/user/0
sys-kernel-config.mount loaded active mounted Configuration File System
sys-kernel-debug.mount loaded active mounted Debug File System
var-lib-kubelet-pods-aea86e6c\x2d3cb7\x2d11e8\x2dbb32\x2d00505696e13c-volumes-kubernetes.io\x7esecret-kube\x2dproxy\x2dtoken\x2d6tgqt.mount loaded active mo
var-lib-kubelet-pods-aebaceba\x2d3cb7\x2d11e8\x2dbb32\x2d00505696e13c-volumes-kubernetes.io\x7esecret-kube\x2ddns\x2dtoken\x2dhzzmv.mount loaded active moun
var-lib-kubelet-pods-f461fa39\x2d3cb7\x2d11e8\x2dbb32\x2d00505696e13c-volumes-kubernetes.io\x7esecret-flannel\x2dtoken\x2drf77r.mount loaded active mounted
brandbot.path loaded active waiting Flexible branding
systemd-ask-password-plymouth.path loaded active waiting Forward Password Requests to Plymouth Directory Watch
systemd-ask-password-wall.path loaded active waiting Forward Password Requests to Wall Directory Watch
docker-121185d5f53ead31d941319e3042395f45b6cb8c1d7dd93fa89b773434b79b27.scope loaded active running libcontainer container 121185d5f53ead31d941319e3042395
docker-121a05887cfe505afc373824dbeb5265752b13f1e604312b5942fec6b2972978.scope loaded active running libcontainer container 121a05887cfe505afc373824dbeb526
docker-15ff649777e6904c365d82f043d1d961f2418c81da6f87758736ee44418ade08.scope loaded active running libcontainer container 15ff649777e6904c365d82f043d1d96
docker-17344939037d910e213e62acbe564f6c8b104d4fb000bc393ca360ff01972c5c.scope loaded active running libcontainer container 17344939037d910e213e62acbe564f6
docker-2995b17f7b1cf824c99ac68bd414f3784dc82942c427f26f7a08a3a384c20612.scope loaded active running libcontainer container 2995b17f7b1cf824c99ac68bd414f37
docker-656d2e92ba35f027e0e92fffac799555bd6ccff39524851ffe2d8808fdb6c907.scope loaded active running libcontainer container 656d2e92ba35f027e0e92fffac79955
docker-8b8770f404adda78586dc7235f6d0e056b821c83d06e3d662c34ae4474f85259.scope loaded active running libcontainer container 8b8770f404adda78586dc7235f6d0e0
docker-8e47ef924ee32f6d6107f7fb20632743824e9d8dfdce456c3692b13fbf6f9e52.scope loaded active running libcontainer container 8e47ef924ee32f6d6107f7fb2063274
docker-8f92f56afabea9689b1d9fb996318d5e2aad26c2c369fd246c15b86ba064b15f.scope loaded active running libcontainer container 8f92f56afabea9689b1d9fb996318d5
docker-a0e3d010c40a7732eff4c36160792a681f4e437c1cf34a71e9af990b7ecf0343.scope loaded active running libcontainer container a0e3d010c40a7732eff4c36160792a6
docker-a1f2c42182828f2f82ac581878034b185572eaa823ad807eaf503df39f820031.scope loaded active running libcontainer container a1f2c42182828f2f82ac581878034b1
docker-a87c101f9b6ea444a750c0f0b84cd71aada64fd6d707ea5aa48722603b2aba21.scope loaded active running libcontainer container a87c101f9b6ea444a750c0f0b84cd71
docker-bea14b22d6090441b8f4bc9f89fe416d06875b272816f2a0ffb30cb7f77509d5.scope loaded active running libcontainer container bea14b22d6090441b8f4bc9f89fe416
docker-cdc819cd61bc462cf5e86d0177899c228337c3894032964b3bc5a9fde7178f3c.scope loaded active running libcontainer container cdc819cd61bc462cf5e86d0177899c2
docker-cfdcde0fa4265b33d40c2059c070af0ae1ef7649d7933168bfa4cc12a5da5c59.scope loaded active running libcontainer container cfdcde0fa4265b33d40c2059c070af0
docker-eae566bf29ac4a378a7a9f651907830779fee7b213e15b090c5471d725a50601.scope loaded active running libcontainer container eae566bf29ac4a378a7a9f651907830
session-129.scope loaded active abandoned Session 129 of user root
session-130.scope loaded active running Session 130 of user root
session-131.scope loaded active running Session 131 of user root
auditd.service loaded active running Security Auditing Service
crond.service loaded active running Command Scheduler
dbus.service loaded active running D-Bus System Message Bus
docker.service loaded active running Docker Application Container Engine
getty@tty1.service loaded active running Getty on tty1
irqbalance.service loaded active running irqbalance daemon
kdump.service loaded active exited Crash recovery kernel arming
kmod-static-nodes.service loaded active exited Create list of required static device nodes for the current kernel
kubelet.service loaded active running kubelet: The Kubernetes Node Agent
lvm2-lvmetad.service loaded active running LVM2 metadata daemon
lvm2-monitor.service loaded active exited Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progr
lvm2-pvscan@8:2.service loaded active exited LVM2 PV scan on device 8:2
network.service loaded active exited LSB: Bring up/down networking
NetworkManager-wait-online.service loaded active exited Network Manager Wait Online
NetworkManager.service loaded active running Network Manager
polkit.service loaded active running Authorization Manager
postfix.service loaded active running Postfix Mail Transport Agent
rhel-dmesg.service loaded active exited Dump dmesg to /var/log/dmesg
rhel-import-state.service loaded active exited Import network configuration from initramfs
rhel-readonly.service loaded active exited Configure read-only root support
rsyslog.service loaded active running System Logging Service
sshd.service loaded active running OpenSSH server daemon
systemd-journal-flush.service loaded active exited Flush Journal to Persistent Storage
systemd-journald.service loaded active running Journal Service
systemd-logind.service loaded active running Login Service
systemd-random-seed.service loaded active exited Load/Save Random Seed
systemd-remount-fs.service loaded active exited Remount Root and Kernel File Systems
systemd-sysctl.service loaded active exited Apply Kernel Variables
systemd-tmpfiles-setup-dev.service loaded active exited Create Static Device Nodes in /dev
systemd-tmpfiles-setup.service loaded active exited Create Volatile Files and Directories
systemd-udev-trigger.service loaded active exited udev Coldplug all Devices
systemd-udevd.service loaded active running udev Kernel Device Manager
systemd-update-utmp.service loaded active exited Update UTMP about System Boot/Shutdown
systemd-user-sessions.service loaded active exited Permit User Sessions
systemd-vconsole-setup.service loaded active exited Setup Virtual Console
tuned.service loaded active running Dynamic System Tuning Daemon
-.slice loaded active active Root Slice
kubepods-besteffort-podaea86e6c_3cb7_11e8_bb32_00505696e13c.slice loaded active active libcontainer container kubepods-besteffort-podaea86e6c_3cb7_11e8_b
kubepods-besteffort-podd0f5be64eb96701ecb2dfd99040bdae9.slice loaded active active libcontainer container kubepods-besteffort-podd0f5be64eb96701ecb2d
kubepods-besteffort-podf461fa39_3cb7_11e8_bb32_00505696e13c.slice loaded active active libcontainer container kubepods-besteffort-podf461fa39_3cb7_11e8_b
kubepods-besteffort.slice loaded active active libcontainer container kubepods-besteffort.slice
kubepods-burstable-pod099f1c2b79126109140a1f77e211df00.slice loaded active active libcontainer container kubepods-burstable-pod099f1c2b79126109140a1
kubepods-burstable-pod498af058d9a8b33f17a3c7deeec06574.slice loaded active active libcontainer container kubepods-burstable-pod498af058d9a8b33f17a3c
kubepods-burstable-podaebaceba_3cb7_11e8_bb32_00505696e13c.slice loaded active active libcontainer container kubepods-burstable-podaebaceba_3cb7_11e8_bb
kubepods-burstable-podda46e5eb58febd64dd66deab8e98a51b.slice loaded active active libcontainer container kubepods-burstable-podda46e5eb58febd64dd66d
kubepods-burstable.slice loaded active active libcontainer container kubepods-burstable.slice
kubepods.slice loaded active active libcontainer container kubepods.slice
system-getty.slice loaded active active system-getty.slice
system-lvm2\x2dpvscan.slice loaded active active system-lvm2\x2dpvscan.slice
system-selinux\x2dpolicy\x2dmigrate\x2dlocal\x2dchanges.slice loaded active active system-selinux\x2dpolicy\x2dmigrate\x2dlocal\x2dchanges.slice
system.slice loaded active active System Slice
user-0.slice loaded active active User Slice of root
user.slice loaded active active User and Session Slice
dbus.socket loaded active running D-Bus System Message Bus Socket
dm-event.socket loaded active listening Device-mapper event daemon FIFOs
lvm2-lvmetad.socket loaded active running LVM2 metadata daemon socket
lvm2-lvmpolld.socket loaded active listening LVM2 poll daemon socket
systemd-initctl.socket loaded active listening /dev/initctl Compatibility Named Pipe
systemd-journald.socket loaded active running Journal Socket
systemd-shutdownd.socket loaded active listening Delayed Shutdown Socket
systemd-udevd-control.socket loaded active running udev Control Socket
systemd-udevd-kernel.socket loaded active running udev Kernel Socket
basic.target loaded active active Basic System
cryptsetup.target loaded active active Encrypted Volumes
getty.target loaded active active Login Prompts
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-online.target loaded active active Network is Online
network.target loaded active active Network
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
swap.target loaded active active Swap
sysinit.target loaded active active System Initialization
timers.target loaded active active Timers
docker-cleanup.timer loaded active waiting Run docker-cleanup every hour
systemd-tmpfiles-clean.timer loaded active waiting Daily Cleanup of Temporary Directories

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.

134 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
lines 111-142/142 (END)

看一下ACTIVE列,它显示了服务的高级状态(或者实际上任何类型的systemd维护的单元,它们不仅仅是服务),它是否active(即正在运行), inactive(即未运行)还是处于任何其他状态。现在,让我们用systemctl status 命令查看kubelet :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@kubernetes-node1 ~]# systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/etc/systemd/system/kubelet.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: active (running) since Tue 2018-04-10 20:06:36 CST; 4 days ago
Docs: http://kubernetes.io/docs/
Main PID: 28032 (kubelet)
CGroup: /system.slice/kubelet.service
└─28032 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --pod-manifes...

Apr 15 03:01:39 kubernetes-node1 kubelet[28032]: W0415 03:01:39.424039 28032 container_manager_linux.go:791] CPUAccounting not enabled for pid: 28032
Apr 15 03:01:39 kubernetes-node1 kubelet[28032]: W0415 03:01:39.424051 28032 container_manager_linux.go:794] MemoryAccounting not enabled for pid: 28032
Apr 15 03:06:39 kubernetes-node1 kubelet[28032]: W0415 03:06:39.424458 28032 container_manager_linux.go:791] CPUAccounting not enabled for pid: 28707
Apr 15 03:06:39 kubernetes-node1 kubelet[28032]: W0415 03:06:39.424498 28032 container_manager_linux.go:794] MemoryAccounting not enabled for pid: 28707
Apr 15 03:06:39 kubernetes-node1 kubelet[28032]: W0415 03:06:39.424634 28032 container_manager_linux.go:791] CPUAccounting not enabled for pid: 28032
Apr 15 03:06:39 kubernetes-node1 kubelet[28032]: W0415 03:06:39.424646 28032 container_manager_linux.go:794] MemoryAccounting not enabled for pid: 28032
Apr 15 03:11:39 kubernetes-node1 kubelet[28032]: W0415 03:11:39.425017 28032 container_manager_linux.go:791] CPUAccounting not enabled for pid: 28707
Apr 15 03:11:39 kubernetes-node1 kubelet[28032]: W0415 03:11:39.425052 28032 container_manager_linux.go:794] MemoryAccounting not enabled for pid: 28707
Apr 15 03:11:39 kubernetes-node1 kubelet[28032]: W0415 03:11:39.425213 28032 container_manager_linux.go:791] CPUAccounting not enabled for pid: 28032
Apr 15 03:11:39 kubernetes-node1 kubelet[28032]: W0415 03:11:39.425227 28032 container_manager_linux.go:794] MemoryAccounting not enabled for pid: 28032

哪个服务拥有哪个进程?

在大多数Linux系统上,默认运行的进程数量很大。知道哪个过程做什么和它属于哪里变得越来越困难。一些服务甚至维护了一些工作进程,这些工作进程通过许多额外的进程来混淆“ ps ”输出,而这些进程往往不易识别。如果守护进程产生任意的第三方进程,如Apache对CGI进程的操作,或者cron对用户作业做的那样,这会更加复杂。

对此的一点补救通常是进程继承树,如“ ps xaf ”所示。然而,这通常是不可靠的,因为其父进程死亡的进程被重新设置为PID 1,因此关于继承的所有信息都会丢失。如果一个过程“双重分叉”,那么它就会失去与启动过程的关系。(实际上这应该是一个功能,并且依赖于传统的Unix守护进程逻辑。)此外,进程可以使用PR_SETNAME或修补argv [0]来自由更改其名称,从而使其更难识别它们。

在systemd中,我们将产生的每个进程放在以其服务命名的控制组中。最基本的控制组(或cgroup)只是一组进程,可以按层次结构排列并单独标记。当进程产生其他进程时,这些孩子将自动成为父cgroup的成员。离开cgroup对于非特权进程是不可能的。因此,cgroups可以作为一种有效的方式来标记它们所属服务之后的进程,并确保该服务无法从标签中逃脱,无论它多长时间分叉或重命名它自己。此外,这可以用来安全地杀死一个服务及其创建的所有进程。

可能用于关联systemd服务和进程的两个命令。第一个是众所周知的ps命令,该命令已经更新以显示沿着其他处理细节的cgroup信息。这就是它的外观:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
[root@kubernetes-node1 ~]# ps xawf -eo pid,user,cgroup,args
PID USER CGROUP COMMAND
2 root - [kthreadd]
3 root - \_ [ksoftirqd/0]
5 root - \_ [kworker/0:0H]
7 root - \_ [migration/0]
8 root - \_ [rcu_bh]
9 root - \_ [rcu_sched]
10 root - \_ [watchdog/0]
11 root - \_ [watchdog/1]
12 root - \_ [migration/1]
13 root - \_ [ksoftirqd/1]
15 root - \_ [kworker/1:0H]
16 root - \_ [watchdog/2]
17 root - \_ [migration/2]
18 root - \_ [ksoftirqd/2]
20 root - \_ [kworker/2:0H]
21 root - \_ [watchdog/3]
22 root - \_ [migration/3]
23 root - \_ [ksoftirqd/3]
25 root - \_ [kworker/3:0H]
26 root - \_ [watchdog/4]
27 root - \_ [migration/4]
28 root - \_ [ksoftirqd/4]
30 root - \_ [kworker/4:0H]
31 root - \_ [watchdog/5]
32 root - \_ [migration/5]
33 root - \_ [ksoftirqd/5]
35 root - \_ [kworker/5:0H]
36 root - \_ [watchdog/6]
37 root - \_ [migration/6]
38 root - \_ [ksoftirqd/6]
40 root - \_ [kworker/6:0H]
41 root - \_ [watchdog/7]
42 root - \_ [migration/7]
43 root - \_ [ksoftirqd/7]
45 root - \_ [kworker/7:0H]
47 root - \_ [kdevtmpfs]
48 root - \_ [netns]
49 root - \_ [khungtaskd]
50 root - \_ [writeback]
51 root - \_ [kintegrityd]
52 root - \_ [bioset]
53 root - \_ [kblockd]
54 root - \_ [md]
60 root - \_ [kswapd0]
61 root - \_ [ksmd]
62 root - \_ [khugepaged]
63 root - \_ [crypto]
71 root - \_ [kthrotld]
73 root - \_ [kmpath_rdacd]
74 root - \_ [kpsmoused]
76 root - \_ [ipv6_addrconf]
95 root - \_ [deferwq]
133 root - \_ [kauditd]
318 root - \_ [scsi_eh_0]
320 root - \_ [scsi_tmf_0]
321 root - \_ [vmw_pvscsi_wq_0]
326 root - \_ [ata_sff]
334 root - \_ [scsi_eh_1]
335 root - \_ [scsi_tmf_1]
336 root - \_ [scsi_eh_2]
337 root - \_ [scsi_tmf_2]
338 root - \_ [scsi_eh_3]
339 root - \_ [scsi_tmf_3]
340 root - \_ [scsi_eh_4]
341 root - \_ [scsi_tmf_4]
342 root - \_ [scsi_eh_5]
343 root - \_ [scsi_tmf_5]
344 root - \_ [scsi_eh_6]
345 root - \_ [scsi_tmf_6]
346 root - \_ [scsi_eh_7]
347 root - \_ [scsi_tmf_7]
348 root - \_ [scsi_eh_8]
349 root - \_ [scsi_tmf_8]
350 root - \_ [scsi_eh_9]
351 root - \_ [scsi_tmf_9]
352 root - \_ [scsi_eh_10]
353 root - \_ [scsi_tmf_10]
354 root - \_ [scsi_eh_11]
355 root - \_ [scsi_tmf_11]
356 root - \_ [scsi_eh_12]
357 root - \_ [scsi_tmf_12]
358 root - \_ [scsi_eh_13]
359 root - \_ [scsi_tmf_13]
360 root - \_ [scsi_eh_14]
361 root - \_ [scsi_tmf_14]
362 root - \_ [scsi_eh_15]
363 root - \_ [scsi_tmf_15]
364 root - \_ [scsi_eh_16]
365 root - \_ [scsi_tmf_16]
366 root - \_ [scsi_eh_17]
367 root - \_ [scsi_tmf_17]
368 root - \_ [scsi_eh_18]
369 root - \_ [scsi_tmf_18]
370 root - \_ [scsi_eh_19]
371 root - \_ [scsi_tmf_19]
372 root - \_ [scsi_eh_20]
373 root - \_ [scsi_tmf_20]
374 root - \_ [scsi_eh_21]
375 root - \_ [scsi_tmf_21]
376 root - \_ [scsi_eh_22]
377 root - \_ [scsi_tmf_22]
378 root - \_ [scsi_eh_23]
379 root - \_ [scsi_tmf_23]
380 root - \_ [scsi_eh_24]
381 root - \_ [scsi_tmf_24]
382 root - \_ [scsi_eh_25]
383 root - \_ [scsi_tmf_25]
384 root - \_ [scsi_eh_26]
385 root - \_ [scsi_tmf_26]
386 root - \_ [scsi_eh_27]
387 root - \_ [scsi_tmf_27]
388 root - \_ [scsi_eh_28]
389 root - \_ [scsi_tmf_28]
390 root - \_ [scsi_eh_29]
391 root - \_ [scsi_tmf_29]
392 root - \_ [scsi_eh_30]
393 root - \_ [scsi_tmf_30]
422 root - \_ [kworker/u16:31]
424 root - \_ [scsi_eh_31]
425 root - \_ [scsi_tmf_31]
426 root - \_ [scsi_eh_32]
427 root - \_ [scsi_tmf_32]
439 root - \_ [ttm_swap]
470 root - \_ [kworker/0:1H]
512 root - \_ [kdmflush]
513 root - \_ [bioset]
524 root - \_ [kdmflush]
525 root - \_ [bioset]
538 root - \_ [bioset]
539 root - \_ [xfsalloc]
540 root - \_ [xfs_mru_cache]
541 root - \_ [xfs-buf/dm-0]
542 root - \_ [xfs-data/dm-0]
543 root - \_ [xfs-conv/dm-0]
544 root - \_ [xfs-cil/dm-0]
545 root - \_ [xfs-reclaim/dm-]
546 root - \_ [xfs-log/dm-0]
547 root - \_ [xfs-eofblocks/d]
548 root - \_ [xfsaild/dm-0]
549 root - \_ [kworker/2:1H]
678 root - \_ [nfit]
716 root - \_ [xfs-buf/sda1]
717 root - \_ [xfs-data/sda1]
718 root - \_ [xfs-conv/sda1]
719 root - \_ [xfs-cil/sda1]
720 root - \_ [xfs-reclaim/sda]
721 root - \_ [xfs-log/sda1]
722 root - \_ [xfs-eofblocks/s]
723 root - \_ [xfsaild/sda1]
754 root - \_ [edac-poller]
758 root - \_ [kworker/6:1H]
759 root - \_ [kworker/1:1H]
895 root - \_ [kworker/7:1H]
1449 root - \_ [kworker/4:1H]
1505 root - \_ [kworker/3:1H]
2704 root - \_ [kworker/5:1H]
27415 root - \_ [kworker/5:2]
27509 root - \_ [kworker/u16:0]
6438 root - \_ [kworker/6:6]
14906 root - \_ [kworker/1:2]
17063 root - \_ [kworker/4:2]
23243 root - \_ [kworker/5:0]
25698 root - \_ [kworker/7:1]
29952 root - \_ [kworker/2:0]
5454 root - \_ [kworker/4:1]
15305 root - \_ [kworker/2:1]
4251 root - \_ [kworker/7:2]
737 root - \_ [kworker/6:1]
31964 root - \_ [kworker/1:0]
11086 root - \_ [kworker/0:2]
27526 root - \_ [kworker/3:1]
31567 root - \_ [kworker/3:0]
789 root - \_ [kworker/0:1]
1157 root - \_ [kworker/3:2]
1 root - /usr/lib/systemd/systemd --switched-root --system --deserialize 21
619 root 10:devices:/system.slice,5: /usr/lib/systemd/systemd-journald
631 root 10:devices:/system.slice,5: /usr/lib/systemd/systemd-udevd
642 root 10:devices:/system.slice,5: /usr/sbin/lvmetad -f
775 root 10:devices:/system.slice,5: /sbin/auditd
799 polkitd 10:devices:/system.slice,5: /usr/lib/polkit-1/polkitd --no-debug
801 dbus 10:devices:/system.slice,5: /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
807 root 10:devices:/system.slice,5: /usr/sbin/NetworkManager --no-daemon
808 root 10:devices:/system.slice,5: /usr/sbin/irqbalance --foreground
810 root 10:devices:/system.slice,5: /usr/lib/systemd/systemd-logind
811 root 10:devices:/system.slice,5: /usr/sbin/rsyslogd -n
822 root 10:devices:/system.slice,5: /usr/sbin/crond -n
828 root 10:devices:/system.slice/sy /sbin/agetty --noclear tty1 linux
1067 root 10:devices:/system.slice,5: /usr/sbin/sshd -D
30318 root 10:devices:/user.slice,5:me \_ sshd: root@pts/0
30330 root 10:devices:/user.slice,5:me | \_ -bash
3792 root 10:devices:/user.slice,5:me | \_ ps xawf -eo pid,user,cgroup,args
30321 root 10:devices:/user.slice,5:me \_ sshd: root@notty
30323 root 10:devices:/user.slice,5:me \_ /usr/libexec/openssh/sftp-server
1068 root 10:devices:/system.slice,5: /usr/bin/python -Es /usr/sbin/tuned -l -P
1273 root 10:devices:/system.slice,5: /usr/libexec/postfix/master -w
1278 postfix 10:devices:/system.slice,5: \_ qmgr -l -t unix -u
31586 postfix 10:devices:/system.slice,5: \_ pickup -l -t unix -u
28032 root 10:devices:/system.slice,5: /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubel
28707 root 10:devices:/system.slice,5: /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=dock
28718 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-i
29263 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current 656d2e92ba35f027e0e92fffac799555bd6ccff39524851ffe2d8808fdb6c907
29282 root 11:perf_event:/kubepods.sli | \_ /pause
29302 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current 15ff649777e6904c365d82f043d1d961f2418c81da6f87758736ee44418ade08
29320 root 11:perf_event:/kubepods.sli | \_ /pause
29336 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current a1f2c42182828f2f82ac581878034b185572eaa823ad807eaf503df39f820031
29388 root 11:perf_event:/kubepods.sli | \_ /pause
29337 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current 121185d5f53ead31d941319e3042395f45b6cb8c1d7dd93fa89b773434b79b27
29387 root 11:perf_event:/kubepods.sli | \_ /pause
29364 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current a87c101f9b6ea444a750c0f0b84cd71aada64fd6d707ea5aa48722603b2aba21
29410 root 11:perf_event:/kubepods.sli | \_ /pause
29413 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current eae566bf29ac4a378a7a9f651907830779fee7b213e15b090c5471d725a50601
29477 root 11:perf_event:/kubepods.sli | \_ /pause
29416 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current 8b8770f404adda78586dc7235f6d0e056b821c83d06e3d662c34ae4474f85259
29476 root 11:perf_event:/kubepods.sli | \_ /pause
29604 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current 8e47ef924ee32f6d6107f7fb20632743824e9d8dfdce456c3692b13fbf6f9e52
29636 root 11:perf_event:/kubepods.sli | \_ kube-apiserver --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,
29725 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current cdc819cd61bc462cf5e86d0177899c228337c3894032964b3bc5a9fde7178f3c
29776 root 11:perf_event:/kubepods.sli | \_ /usr/local/bin/kube-proxy --config=/var/lib/kube-proxy/config.conf
29992 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current bea14b22d6090441b8f4bc9f89fe416d06875b272816f2a0ffb30cb7f77509d5
30010 root 11:perf_event:/kubepods.sli | \_ /kube-dns --domain=cluster.local. --dns-port=10053 --config-dir=/kube-dns-config --v=2
30052 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current 121a05887cfe505afc373824dbeb5265752b13f1e604312b5942fec6b2972978
30070 root 11:perf_event:/kubepods.sli | \_ /dnsmasq-nanny -v=2 -logtostderr -configDir=/etc/k8s/dns/dnsmasq-nanny -restartDnsmasq=true -- -k --c
30109 root 11:perf_event:/kubepods.sli | \_ /usr/sbin/dnsmasq -k --cache-size=1000 --no-negcache --log-facility=- --server=/cluster.local/127
30110 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current 17344939037d910e213e62acbe564f6c8b104d4fb000bc393ca360ff01972c5c
30127 65534 11:perf_event:/kubepods.sli | \_ /sidecar --v=2 --logtostderr --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.cluster.local,5,S
30168 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current a0e3d010c40a7732eff4c36160792a681f4e437c1cf34a71e9af990b7ecf0343
30186 root 11:perf_event:/kubepods.sli | \_ /opt/bin/flanneld --ip-masq --kube-subnet-mgr
10409 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current 2995b17f7b1cf824c99ac68bd414f3784dc82942c427f26f7a08a3a384c20612
10432 root 11:perf_event:/kubepods.sli | \_ etcd --advertise-client-urls=https://127.0.0.1:2379 --client-cert-auth=true --data-dir=/var/lib/etcd
13536 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current 8f92f56afabea9689b1d9fb996318d5e2aad26c2c369fd246c15b86ba064b15f
13554 root 11:perf_event:/kubepods.sli | \_ kube-controller-manager --kubeconfig=/etc/kubernetes/controller-manager.conf --cluster-signing-cert-f
13594 root 10:devices:/system.slice,5: \_ /usr/bin/docker-containerd-shim-current cfdcde0fa4265b33d40c2059c070af0ae1ef7649d7933168bfa4cc12a5da5c59
13612 root 11:perf_event:/kubepods.sli \_ kube-scheduler --leader-elect=true --kubeconfig=/etc/kubernetes/scheduler.conf --address=127.0.0.1
28378 root 10:devices:/user.slice,5:me /usr/sbin/anacron -s

提供相同信息的另一种方式是systemd附带systemd-cgls工具。它在树中显示cgroup层次结构。它的输出如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
[root@kubernetes-node1 ~]# systemd-cgls
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
├─kubepods.slice
│ ├─kubepods-besteffort.slice
│ │ ├─kubepods-besteffort-podf461fa39_3cb7_11e8_bb32_00505696e13c.slice
│ │ │ ├─docker-a0e3d010c40a7732eff4c36160792a681f4e437c1cf34a71e9af990b7ecf0343.scope
│ │ │ │ └─30186 /opt/bin/flanneld --ip-masq --kube-subnet-mgr
│ │ │ └─docker-a1f2c42182828f2f82ac581878034b185572eaa823ad807eaf503df39f820031.scope
│ │ │ └─29388 /pause
│ │ ├─kubepods-besteffort-podaea86e6c_3cb7_11e8_bb32_00505696e13c.slice
│ │ │ ├─docker-cdc819cd61bc462cf5e86d0177899c228337c3894032964b3bc5a9fde7178f3c.scope
│ │ │ │ └─kube-proxy
│ │ │ │ └─29776 /usr/local/bin/kube-proxy --config=/var/lib/kube-proxy/config.conf
│ │ │ └─docker-a87c101f9b6ea444a750c0f0b84cd71aada64fd6d707ea5aa48722603b2aba21.scope
│ │ │ └─29410 /pause
│ │ └─kubepods-besteffort-podd0f5be64eb96701ecb2dfd99040bdae9.slice
│ │ ├─docker-2995b17f7b1cf824c99ac68bd414f3784dc82942c427f26f7a08a3a384c20612.scope
│ │ │ └─10432 etcd --advertise-client-urls=https://127.0.0.1:2379 --client-cert-auth=true --data-dir=/var/lib/etcd --cert-file=/etc/kubernetes/pki/etcd/se
│ │ └─docker-15ff649777e6904c365d82f043d1d961f2418c81da6f87758736ee44418ade08.scope
│ │ └─29320 /pause
│ └─kubepods-burstable.slice
│ ├─kubepods-burstable-podaebaceba_3cb7_11e8_bb32_00505696e13c.slice
│ │ ├─docker-17344939037d910e213e62acbe564f6c8b104d4fb000bc393ca360ff01972c5c.scope
│ │ │ └─30127 /sidecar --v=2 --logtostderr --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.cluster.local,5,SRV --probe=dnsmasq,127.0.0.1:53,kuberne
│ │ ├─docker-121a05887cfe505afc373824dbeb5265752b13f1e604312b5942fec6b2972978.scope
│ │ │ ├─30070 /dnsmasq-nanny -v=2 -logtostderr -configDir=/etc/k8s/dns/dnsmasq-nanny -restartDnsmasq=true -- -k --cache-size=1000 --no-negcache --log-faci
│ │ │ └─30109 /usr/sbin/dnsmasq -k --cache-size=1000 --no-negcache --log-facility=- --server=/cluster.local/127.0.0.1#10053 --server=/in-addr.arpa/127.0.0
│ │ ├─docker-bea14b22d6090441b8f4bc9f89fe416d06875b272816f2a0ffb30cb7f77509d5.scope
│ │ │ └─30010 /kube-dns --domain=cluster.local. --dns-port=10053 --config-dir=/kube-dns-config --v=2
│ │ └─docker-eae566bf29ac4a378a7a9f651907830779fee7b213e15b090c5471d725a50601.scope
│ │ └─29477 /pause
│ ├─kubepods-burstable-pod498af058d9a8b33f17a3c7deeec06574.slice
│ │ ├─docker-8f92f56afabea9689b1d9fb996318d5e2aad26c2c369fd246c15b86ba064b15f.scope
│ │ │ └─13554 kube-controller-manager --kubeconfig=/etc/kubernetes/controller-manager.conf --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt --contro
│ │ └─docker-8b8770f404adda78586dc7235f6d0e056b821c83d06e3d662c34ae4474f85259.scope
│ │ └─29476 /pause
│ ├─kubepods-burstable-podda46e5eb58febd64dd66deab8e98a51b.slice
│ │ ├─docker-8e47ef924ee32f6d6107f7fb20632743824e9d8dfdce456c3692b13fbf6f9e52.scope
│ │ │ └─29636 kube-apiserver --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestrictio
│ │ └─docker-656d2e92ba35f027e0e92fffac799555bd6ccff39524851ffe2d8808fdb6c907.scope
│ │ └─29282 /pause
│ └─kubepods-burstable-pod099f1c2b79126109140a1f77e211df00.slice
│ ├─docker-cfdcde0fa4265b33d40c2059c070af0ae1ef7649d7933168bfa4cc12a5da5c59.scope
│ │ └─13612 kube-scheduler --leader-elect=true --kubeconfig=/etc/kubernetes/scheduler.conf --address=127.0.0.1
│ └─docker-121185d5f53ead31d941319e3042395f45b6cb8c1d7dd93fa89b773434b79b27.scope
│ └─29387 /pause
├─user.slice
│ └─user-0.slice
│ ├─session-131.scope
│ │ ├─30321 sshd: root@notty
│ │ └─30323 /usr/libexec/openssh/sftp-server
│ ├─session-130.scope
│ │ ├─ 4343 systemd-cgls
│ │ ├─ 4344 less
│ │ ├─30318 sshd: root@pts/0
│ │ └─30330 -bash
│ └─session-129.scope
│ └─28378 /usr/sbin/anacron -s
└─system.slice
├─kubelet.service
│ └─28032 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --pod-manifest-path=/et
├─tuned.service
│ └─1068 /usr/bin/python -Es /usr/sbin/tuned -l -P
├─sshd.service
│ └─1067 /usr/sbin/sshd -D
├─postfix.service
│ ├─ 1273 /usr/libexec/postfix/master -w
│ ├─ 1278 qmgr -l -t unix -u
│ └─31586 pickup -l -t unix -u
├─docker.service
│ ├─10409 /usr/bin/docker-containerd-shim-current 2995b17f7b1cf824c99ac68bd414f3784dc82942c427f26f7a08a3a384c20612 /var/run/docker/libcontainerd/2995b17f7
│ ├─13536 /usr/bin/docker-containerd-shim-current 8f92f56afabea9689b1d9fb996318d5e2aad26c2c369fd246c15b86ba064b15f /var/run/docker/libcontainerd/8f92f56af
│ ├─13594 /usr/bin/docker-containerd-shim-current cfdcde0fa4265b33d40c2059c070af0ae1ef7649d7933168bfa4cc12a5da5c59 /var/run/docker/libcontainerd/cfdcde0fa
│ ├─28707 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgrou
│ ├─28718 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --stat
│ ├─29263 /usr/bin/docker-containerd-shim-current 656d2e92ba35f027e0e92fffac799555bd6ccff39524851ffe2d8808fdb6c907 /var/run/docker/libcontainerd/656d2e92b
│ ├─29302 /usr/bin/docker-containerd-shim-current 15ff649777e6904c365d82f043d1d961f2418c81da6f87758736ee44418ade08 /var/run/docker/libcontainerd/15ff64977
│ ├─29336 /usr/bin/docker-containerd-shim-current a1f2c42182828f2f82ac581878034b185572eaa823ad807eaf503df39f820031 /var/run/docker/libcontainerd/a1f2c4218
│ ├─29337 /usr/bin/docker-containerd-shim-current 121185d5f53ead31d941319e3042395f45b6cb8c1d7dd93fa89b773434b79b27 /var/run/docker/libcontainerd/121185d5f
│ ├─29364 /usr/bin/docker-containerd-shim-current a87c101f9b6ea444a750c0f0b84cd71aada64fd6d707ea5aa48722603b2aba21 /var/run/docker/libcontainerd/a87c101f9
│ ├─29413 /usr/bin/docker-containerd-shim-current eae566bf29ac4a378a7a9f651907830779fee7b213e15b090c5471d725a50601 /var/run/docker/libcontainerd/eae566bf2
│ ├─29416 /usr/bin/docker-containerd-shim-current 8b8770f404adda78586dc7235f6d0e056b821c83d06e3d662c34ae4474f85259 /var/run/docker/libcontainerd/8b8770f40
│ ├─29604 /usr/bin/docker-containerd-shim-current 8e47ef924ee32f6d6107f7fb20632743824e9d8dfdce456c3692b13fbf6f9e52 /var/run/docker/libcontainerd/8e47ef924
│ ├─29725 /usr/bin/docker-containerd-shim-current cdc819cd61bc462cf5e86d0177899c228337c3894032964b3bc5a9fde7178f3c /var/run/docker/libcontainerd/cdc819cd6
│ ├─29992 /usr/bin/docker-containerd-shim-current bea14b22d6090441b8f4bc9f89fe416d06875b272816f2a0ffb30cb7f77509d5 /var/run/docker/libcontainerd/bea14b22d
│ ├─30052 /usr/bin/docker-containerd-shim-current 121a05887cfe505afc373824dbeb5265752b13f1e604312b5942fec6b2972978 /var/run/docker/libcontainerd/121a05887
│ ├─30110 /usr/bin/docker-containerd-shim-current 17344939037d910e213e62acbe564f6c8b104d4fb000bc393ca360ff01972c5c /var/run/docker/libcontainerd/173449390
│ └─30168 /usr/bin/docker-containerd-shim-current a0e3d010c40a7732eff4c36160792a681f4e437c1cf34a71e9af990b7ecf0343 /var/run/docker/libcontainerd/a0e3d010c
├─crond.service
│ └─822 /usr/sbin/crond -n
├─rsyslog.service
│ └─811 /usr/sbin/rsyslogd -n
├─systemd-logind.service
│ └─810 /usr/lib/systemd/systemd-logind
├─irqbalance.service
│ └─808 /usr/sbin/irqbalance --foreground
├─NetworkManager.service
│ └─807 /usr/sbin/NetworkManager --no-daemon
├─dbus.service
│ └─801 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
├─polkit.service
│ └─799 /usr/lib/polkit-1/polkitd --no-debug
├─auditd.service
│ └─775 /sbin/auditd
├─lvm2-lvmetad.service
│ └─642 /usr/sbin/lvmetad -f
├─systemd-udevd.service
│ └─631 /usr/lib/systemd/systemd-udevd
├─system-getty.slice
│ └─getty@tty1.service
│ └─828 /sbin/agetty --noclear tty1 linux
└─systemd-journald.service
└─619 /usr/lib/systemd/systemd-journald

正如你所看到的,这个命令显示了他们的cgroup进程以及服务,因为systemd在服务之后标记了cgroup。例如,您可以轻松看到审计服务 auditd.service生成三个单独的进程, auditdaudispsedispatch

如果仔细观察,您会注意到已将一些进程分配给cgroup /user/1。在这一点,简单地将它留在该systemd中,不仅在cgroup中维护服务,还在用户会话进程中维护服务。

如何将SysV Init脚本转换为systemd服务文件?

传统上,Unix和Linux服务(守护进程)通过SysV init脚本启动。这些是Bourne Shell脚本,通常驻留在诸如/etc/rc.d/init.d/的目录中,当使用诸如startstoprestart控制之类的一些标准化参数之一调用时 ,即启动,停止或重新启动有问题的服务。对于这个开始通常包括调用后台程序二进制文件,然后派生一个后台进程(更准确地说daemonizes)。Shell脚本通常很慢,很难阅读,非常冗长和脆弱。虽然它们非常灵活(毕竟它们只是代码),但有些事情很难与shell脚本正确配合,例如命令执行parallized执行,正确监督进程或只是配置执行上下文的所有细节。systemd提供了与这些shell脚本的兼容性,但由于指出了缺陷,建议为安装的所有守护程序安装本机systemd服务文件。另外,与SysV初始化脚本相比,它必须根据分发系统进行调整。服务文件与任何运行systemd的分发版(现在变得越来越多)兼容。接下来的内容是一个简洁的指南,指导如何使用SysV初始化脚本并将其转换为本地systemd服务文件。理想的情况下,上游项目应该将systemd服务文件发布并安装到它们的tarball中。如果您已经根据指导原则成功转换了一个SysV脚本,那么将该文件作为补丁提交给上游可能是一个好主意。如何准备这样的补丁将在稍后的部分中讨论,使用systemd手册页出货包含大量关于此的有用信息。

所以,让我们直接作为一个例子,我们将把ABRT守护进程的init脚本转换为一个systemd服务文件。ABRT是每个Fedora安装的标准组件,并且是Automatic Bug Reporting Tool的缩写,它很好地描述了它的功能,即它是用于收集崩溃转储的服务。

转换这种脚本时的第一步是读取它,并从通常非常长的脚本中提取有用的信息。在几乎所有情况下,脚本都由大部分样板代码组成,这些代码在所有init脚本中都相同或至少非常相似,并且通常从一个到另一个复制和粘贴。那么,让我们从上面链接的脚本中提取有趣的信息:

  • 该服务的描述字符串是“ 用于检测应用程序崩溃的守护程序 ”。事实证明,标题注释包括多余的描述字符串,其中一些描述的实际服务较少,但是启动脚本的init脚本较少。systemd服务也包含描述,它应该描述服务而不是服务文件。
  • LSB头包含依赖信息。systemd由于其围绕基于套接字的激活而设计,通常不需要(或很少)手动配置的依赖关系。(有关套接字激活的详细信息,在这种情况下,对$syslog(对abrtd进行编码需要syslog守护进程)的依赖关系 是唯一有价值的信息。虽然头文件列出了另一个依赖项($local_fs),但这对于systemd是冗余的,因为正常的系统服务始终在所有本地文件系统可用的情况下启动。
  • LSB头部表明这个服务应该以运行级别3(多用户)和5(图形)开始。
  • 守护进程二进制文件是/usr/sbin/abrtd

这已经是了。这个115行shell脚本的全部剩余内容仅仅是样板文件或其他冗余代码:处理同步和序列化启动(即与锁文件有关的代码)或输出状态消息(即代码调用回显)的代码,或者干脆解析动词。

从上面提取的信息中,我们现在可以编写我们的systemd服务文件:

1
2
3
4
5
6
7
8
9
10
[Unit]
Description=Daemon to detect crashing apps
After=syslog.target

[Service]
ExecStart=/usr/sbin/abrtd
Type=forking

[Install]
WantedBy=multi-user.target

对该文件内容的一点解释: [Unit]部分包含有关服务的一般信息。systemd不仅管理系统服务,还管理系统的设备,挂载点,定时器和其他组件。systemd中所有这些对象的通用术语是一个单元[单元]部分对其信息进行编码,这些信息不仅适用于服务,还适用于其他单元类型systemd维护。在这种情况下,我们设置以下单元设置:我们设置描述字符串并配置守护程序应在Syslog [2]之后启动,类似于原始初始化脚本的LSB标头中编码的内容。对于这个Syslog依赖关系,我们创建了一个After=类型的依赖关系`在systemd单元syslog.target上。后者是systemd中的一个特殊目标单元,并且是引入syslog实现的标准化名称。请注意,After=`类型的依赖关系只编码建议的顺序,但实际上并不会导致在abrtd时启动syslog - 而这正是我们想要的,因为即使没有syslog,abrtd实际上也能正常工作。但是,如果两者都开始(通常它们是),那么它们的顺序就由这种依赖性来控制。

下一部分是[Service],它编码有关服务本身的信息。它包含所有那些仅适用于服务的设置,而不包括系统维护的其他类型的单元(挂载点,设备,定时器…)。这里使用两个设置: ExecStart=在启动服务时获取执行二进制文件的路径。使用Type=我们配置服务如何通知init系统启动完成。由于传统的Unix守护进程在分叉并初始化后台守护进程后返回父进程,我们将类型设置为分叉这里。这告诉systemd等待启动二进制返回,然后考虑进程在守护进程之后仍然运行。

最后一节是[Install]。它编码关于建议的安装应该是什么样子的信息,即在哪些情况下以及由哪些触发器启动服务。在这种情况下,我们简单地说,当多用户。目标单元被激活时,该服务应该开始。这是一个特殊的单元,它基本上扮演着经典的SysV Runlevel 3 的角色。WantedBy=设置在运行时对守护进程影响不大。它只能由systemctl enable命令读取 ,这是在systemd中启用服务的推荐方式。该命令将确保我们的小服务在multi-user.target立即自动激活。

就是这样。现在我们已经有了一个最小的工作systemd服务文件。为了测试它,我们将它复制到 /etc/systemd/system/abrtd.service并调用systemctl daemon-reload。这将使systemd注意到它,现在我们可以使用它启动服务:systemctl start abrtd.service。我们可以通过systemctl status abrtd.service来验证状态。我们可以通过systemctl stop abrtd.service再次停止它。最后,我们可以启用它,以便systemctl enable abrtd.service在将来的引导中默认激活它。

1
2
3
4
5
6
7
8
9
10
11
[Unit]
Description=ABRT Automated Bug Reporting Tool
After=syslog.target

[Service]
Type=dbus
BusName=com.redhat.abrt
ExecStart=/usr/sbin/abrtd -d -s

[Install]
WantedBy=multi-user.target

那么,我们改变了什么?有两件事:我们稍微改进了描述字符串。但更重要的是,我们将服务类型更改为dbus并配置了服务的D-Bus总线名称。我们为什么这样做?正如所提到的经典SysV服务 守护进程启动后,通常涉及双重分叉和从任何终端分离。当通过脚本调用守护进程时,这是非常有用和必要的,但在使用适当的进程保护程序(如systemd)时,这是不必要的(并且很慢),并且会适得其反。原因在于分叉守护进程通常与systemd启动的原始进程没有什么关系(在所有的守护进程方案的整个想法是去除这个关系之后),因此systemd很难在fork之后找出完成哪个进程属于服务实际上是主进程,哪些进程可能只是辅助进程。但是,这些信息对于实施高级保姆至关重要,即监督过程,异常终止的自动重生,collectig崩溃和退出代码信息等。为了让systemd更容易找出守护进程的主进程,我们将服务类型更改为 dbus。这种服务类型的语义适用于所有在D-Bus系统总线上取名的服务,作为其初始化的最后一步。ABRT就是其中之一。通过这个设置,systemd将生成ABRT进程,该进程将不再分叉(这是通过-d -s开关配置到守护进程中),并且只要com.redhat.abrt出现,systemd就会认为服务已完全启动公交车。这样systemd产生的进程是守护进程的主要进程,systemd有一个可靠的方法来确定守护进程何时完全启动,并且systemd可以很容易地监督它。

这就是它的全部。我们现在有一个简单的systemd服务文件,它比在115中编码的原始SysV init脚本编码10行更多的信息。即使现在,利用更多功能systemd提供了进一步改进的空间。例如,我们可以设置Restart=restart-always 总是告诉systemd在它停止时自动重启这个服务。或者,我们可以使用OOMScoreAdjust=-500来请求内核在OOM杀手发生严重破坏时请留下这个过程。或者,我们可以使用CPUSchedulingPolicy=idle`来确保abrtd进程仅在后台崩溃转储,始终允许内核优先考虑可能正在运行的任何其他操作并需要CPU时间。

当然,并非所有的SysV脚本都像这一个一样容易转换。但事实证明绝大多数实际上是。

关闭的三个级别

在systemd中,有三个关闭服务的级别。让我们来看看这些是:

  1. 你可以 停止 一个服务. 这只是终止服务的运行实例,并没有别的。如果由于某种形式的激活(例如手动激活,套接字激活,总线激活,通过系统启动激活或通过硬件插头激活),则在服务被再次请求时将被启动。因此停止服务是一项非常简单,暂时和肤浅的操作。以下是如何为NTP服务执行此操作的示例:
1
$ systemctl stop ntpd.service

这大致等同于大多数SysV灵感系统可用的以下传统命令:

1
$ service ntpd stop

如果你执行后一个命令,它将被透明地转换为前者。

  1. 您可以禁用服务。这从它的激活触发器中解除了一项服务。这意味着,取决于您的服务,它将不再在启动时通过套接字或总线激活或通过硬件插件(或任何其他适用于它的触发器)来激活。但是,如果您愿意,您仍然可以手动启动它。如果已经有一个已启动的实例,禁用一个服务将不会产生停止它的效果。以下是如何禁用服务的示例:

    1
    $ systemctl disable ntpd.service

    这大致等同于以下命令:

    1
    $ chkconfig ntpd off

    如果有必要,后者的命令也会透明地转换为前者。

    通常,您希望合并停止和禁用服务,以摆脱当前实例并确保它不会再次启动(除非手动触发):

    1
    2
    $ systemctl disable ntpd.service 
    $ systemctl stop ntpd.service

    这样的命令例如在Fedora上卸载systemd服务的过程中使用。

    禁用服务是永久性的变化; 直到你撤销它,即使在重新启动时,它也会被保留。

  2. 你可以mask一项服务。这就像禁用服务,类似disable。它不仅确保服务不再自动启动,甚至可以确保服务甚至无法手动启动。这在systemd中是一个隐藏的功能,因为它通常不是很有用,可能会让用户感到困惑。但这是你如何做到的:

    1
    2
    $ ln -s /dev/null /etc/systemd/system/ntpd.service
    $ systemctl daemon-reload

    通过将服务文件符号链接到 /dev/null 告诉 systemd永远不会启动相关服务并完全阻止其执行. 存储再/etc/systemd/system 中的单元将覆盖 /lib/systemd/system 具有相同名称的单元文件. 前一个目录是管理员区域,后者是您的软件包管理器的后者。通过在/etc/systemd/system/ntpd.service 安装符号链接, 您可以确保systemd永远不会读取上游提供的服务文件/lib/systemd/system/ntpd.service.

    systemd会识别符号链接到 /dev/null 并将它们显示为masked.如果你尝试手动启动这样的服务(例如通过 systemctl start),这将失败并出现错误。.

    SysV系统上的类似技巧并没有(正式)存在。但是,还有一些非官方的黑客攻击,例如编辑init脚本并在顶部放置一个 exit 0 者移除它的执行位。但是,这些解决方案有各种缺点,例如它们会干扰包管理器。

    屏蔽服务是永久的变化,就像禁用服务一样。

现在我们已经学会了如何关闭三个层面的服务,我们如何再次打开服务?systemctl start来撤销 stop,使用systemctl enable来撤销systemctl disable ,使用 rm 来撤销ln

下一集介绍chroot sysconfig 等