Linux服务管理神器:SYSTEMD介绍

笔者在平常的开发和使用中,常常须要写大量的本地服务而且进行管理,例如定时执行,定时查错,异步排队以及数据库的备份归档工做。所以systemd做为一个服务管理神器就成了必备工具。今天就写一篇小工具文来介绍一下这东西的用法。shell

1、SYSTEMD基本工具

监控和控制systemd主要使用的指令是systemctl。主要是历来看系统状态、服务状态,以及管理系统和服务。 同时systemctl能够经过ssh链接远程控制其余主机,使用 systemctl -H <username>@<URL> 格式。数据库

一、分析系统状态

显示系统状态: $ systemctl status 输出激活的单元列表: $systemctl 或者 $systemctl list-units 输出运行失败的单元: $ systemctl —failed缓存

全部可用的单元都在 /etc/systemd/system/(优先度高) 和 /usr/lib/systemd/system/(优先度低)。 查看全部已安装的服务:$ systemctl list-unit-filesbash

二、使用单元

一个单元配置文件能够描述以下内容之一:系统服务(.service)、挂载点(.mount)、sockets(.sockets) 、系统设备(.device)、交换分区(.swap)、文件路径(.path)、启动目标(.target)、由 systemd 管理的计时器(.timer)。服务器

咱们一般在用systemctl调用单元的时候通常要单元文件的全名。也就是带上述后缀的那些。 若是不带扩展名的话systemctl会默认成是.service文件,因此为了避免发生意外通常仍是推荐把名字打全了。 挂载点和设备会自动转化为对应的后缀单元,好比/home就等价于home.mount, /dev/sda等价于dev-sda.device网络

systemctl在enable、disable、mask子命令里面增长了--now选项,能够激活同时启动服务,激活同时中止服务等。ssh

马上激活单元:$ systemctl start <unit> 马上中止单元:$ systemctl stop <unit> 重启单元:$ systemctl restart <unit> 从新加载配置:$ systemctl reload <unit> 输出单元运行的状态:$ systemctl status <unit> 检测单元是否为自动启动:$ systemctl is-enabled <unit> 设置为开机自动激活单元:$ systemctl enable <unit> 设置为开机自动激活单元并如今马上启动:$ systemctl enable --now <unit> 取消开机自动激活单元:$ systemctl disable <unit> 禁用一个单元:$ systemctl mask <unit> 取消禁用一个单元:$ systemctl unmask <unit> 显示单元的手册页(前提是由unit提供):$ systemctl help <unit> 从新载入整个systemd的系统配置并扫描unit文件的变更:$ systemctl daemon-reload异步

三、电源管理

注意:须要安装了polkit之后才能用普通用户身份进行电源管理。socket

重启:$ systemctl reboot 退出系统并关闭电源:$ systemctl poweroff 待机:$ systemctl suspend 休眠:$ systemctl hibernate 混合休眠模式:$ systemctl hybrid-sleep编辑器

2、编写unit文件

systemd的unit书写语法来源于XDG桌面配置文件,最初则来自于ini文件。 经过指令 $ systemctl show --property=UnitPath能够按照优先级查看unit加载目录。 /usr/lib/systemd/system/:软件包安装的单元 /etc/systemd/system/ :系统管理员安装的单元

一、处理依赖关系

主要有三类之外关系处理配置: Requires=B:启动必须依赖单元B Wants=B:启动依赖单元B(可选) After=B:本单元在B运行后再运行

注意的是Requires和Want并无包含After属性,若是不声明After则默认同时启动。

二、服务类型

Type=simple :(默认值) systemd认为该服务将当即启动。服务进程不会 fork 。 Type=forking :systemd认为当该服务进程fork,且父进程退出后服务启动成功。使用此启动类型应同时指定 PIDFile=,以便 systemd 可以跟踪服务的主进程。 Type=oneshot :这一选项适用于只执行一项任务、随后当即退出的服务。可能须要同时设置 RemainAfterExit=yes 使 systemd 在服务进程退出以后仍然认为服务处于激活状态。 Type=notify :与 Type=simple 相同,但约定服务会在就绪后向 systemd 发送一个信号。 Type=dbus :若以此方式启动,当指定的 BusName 出如今DBus系统总线上时,systemd认为服务就绪。 Type=idle :systemd会等待全部任务处理完成后,才开始执行 idle 类型的单元。其余行为与 Type=simple 相似。

三、修改现有的unit

直接修改文件并加载:$ systemctl daemon-reload 若是须要替换unit文件,则从新启用单元:$ systemctl reenable <unit> 或者运行:$ systemctl edit --full unit

附加配置片断:$ systemctl edit <unit> 这个操做会在编辑器里面打开/etc/systemd/system/<unit>.d/override.conf

重置到软件包版本:$ systemctl revert <unit>

3、目标 Target

目标是一个相似于运行界别的概念。一些目标能继承其余目标的服务而且启动新的服务,systemd默认提供了一部分相似于sysvinit运行级别的target。

获取当前的target:$ systemctl list-units --type=target 建立自定义target:咱们能够新建一个/etc/systemd/system/.target。而后再建立目录/etc/systemd/system/.want,而且在里面加入须要启动的服务器链接(指向/usr/lib/systemd/system/)

SysV Level Systemd 目标 注释
0 runlevel0.target, poweroff.target 中断系统(halt)
1, s, single runlevel1.target, rescue.target 单用户模式
2, 4 runlevel2.target, runlevel4.target, multi-user.target 用户自定义运行级别,一般识别为级别3。
3 runlevel3.target, multi-user.target 多用户,无图形界面。用户能够经过终端或网络登陆。
5 runlevel5.target, graphical.target 多用户,图形界面。继承级别3的服务,并启动图形界面服务。
6 runlevel6.target, reboot.target 重启
emergency emergency.target 急救模式(Emergency shell)

切换当前运行目标:$ systemctl isolate <target>.target 这个指令仅仅改变当前运行的target,不会对启动有影响

更改开机默认启动target: 检查当前的启动target:$ systemctl get-default 用systemctl修改default.target来变动开机启动target:$ systemctl set-default multi-user.target

4、临时文件

/usr/lib/tmpfiles.d//etc/tmpfiles.d/ 中的文件描述了 systemd-tmpfiles 如何建立、清理、删除临时文件和目录,这些文件和目录一般存放在 /run/tmp 中。配置文件名称为 /etc/tmpfiles.d/<program>.conf。此处的配置能覆盖 /usr/lib/tmpfiles.d/ 目录中的同名配置。

临时文件通常和服务文件同时提供,来生成守护进程须要的文件和目录。也能够在开机的时候往特定的文件写入一些内容。

5、定时器

一、服务单元

定时器是一个以.timer为结尾的unit配置文件,包含了systemd控制和监督的信息。不少时候能够替代crontab而且有更强的功能。 每个.timer文件在同一个目录都有一个对应的.service文件。.timer用来激活并控制.service文件。.service文件不须要有[Install],这部分由.timer单元管理。

二、管理

使用.timer的方法也和其余unit同样,enable或者start便可。 查看已有的定时器使用:$ systemctl list-timers 查看全部的定时器(包括非活动的):$ systemctl list-timers --all

三、示例

下面是两个timer单元的例子。

单调定时器:

/etc/systemd/system/example.timer
----------------------------------
[Unit]
Description=Run example weekly and on boot        ## 文件描述
[Timer]
OnBootSec=15min                                   ## 开机后多久启动
OnUnitActiveSec=1w                                ## 执行间隔t
[Install]
WantedBy=timers.target                            ## 目标service单元
复制代码

实时定时器: 定义一个定时执行,且上次未执行就马上执行的timer

/etc/systemd/system/foo.timer
-----------------------------------
[Unit]
Description=Run foo weekly

[Timer]
OnCalendar=weekly
Persistent=true     
 
[Install]
WantedBy=timers.target
复制代码
四、替代crontab探讨

优点主要在于,每一个任务都有本身的systemd服务。从而:

  • 任务能够独立于定时器,便于测试。
  • 任务能够运行在特殊状况下。
  • 任务可使用cgroups的特性。
  • 任务能够依赖于其余systemd unit。
  • 任务记录在systemd日志里,便于调试排查。

同时也能够和crontab同样在unit失效的时候发送一个email。不过如今通常都用其余开源监控工具,更好用。

6、挂载

由于systemd也负责按 /etc/fstab 挂在目录,因此在系统重启或者从新加载系统管理器的时候,systemd-fstab-generator会把/etc/fstab里面的配置转化为systemd unit。这些设置具体来讲由 x-systemd组件来配置。

7、日志

systemd提供了本身的日至系统。 读取日志:$ journalctl

默认状况下(当 Storage= 在文件 /etc/systemd/journald.conf 中被设置为 auto),日志记录将被写入 /var/log/journal/。该目录是 systemd 软件包的一部分。

一、优先级

日志系统内有日志的优先级区分,下面为对应介绍:

优先级 介绍
优先级0 Emergency(emerg)
优先级1 Alert(alert)
优先级2 Critical(crit)
优先级3 Error(err)
优先级4 Warning(warning)
优先级5 Notice(notice)
优先级6 Informational(info)
优先级7 Debug(debug)
二、功能

在日志系统中,各个日志都会用编码来指代必定的功能区域。下面为对应介绍:

编码 内容(缩写)
功能编码0 kernel-message(kern)
功能编码1 user-level-message(user)
功能编码2 mail-system(mail)
功能编码3 system-daemon(daemon)
功能编码4 authorization-messages(auth)
功能编码5 syslog(syslog)
功能编码6 line-printer-subsystem(lpr)
功能编码7 network-news-subsystem(news)
功能编码8 uucp-subsystem(uucp)
功能编码9 clock-daemon
功能编码10 authpriv(authpri)
功能编码11 ftp-daemon(ftp)
功能编码12 tp-subsyst
功能编码13 log-audit
功能编码14 log-alert
功能编码15 crontab(cron)
功能编码16-23 local0-7
三、过滤输出

Journalctl能够过滤字段输出,下面为经常使用操做。

显示本次启动后全部日志:$ journalctl -b 或者 $ journalctl -b -0 显示上次启动后的日志:$ journalctl -b -1 显示上上次启动后的日志:$ journalctl -b -2 只显示错误冲突和重要告警信息:$ journalctl -p err..alert 或者用编号表示 $ journalctl -p 3..1 显示某个时间开始的消息:$ journalctl --since="2019-01-01 00:00:00" 显示最新的消息:$ journalctl -f 显示特定程序的全部消息:$ journalctl /usr/lib/systemd/systemd 显示某进程的全部信息:$ journalctl _PID=12345 显示指定unit的全部信息:$ journalctl -u mydumper-archive.service 指定内核缓存消息:$ journalctl -k 显示auth.log当前量:$ journalctl -f -1 SYSLOG_FACILITY=10

四、日志大小限制

默认状况下,systemd日志的最大限制是所在FS容量的10%。可是咱们能够经过修改来改变最大限制:

/etc/systemd/journald.conf
--------------------------------
SystemMaxUse=50M
复制代码

同时也能够经过配置片断而非全局来进行设置:

/etc/systemd/journald.conf.d/00-journal-size.conf
-----------------------------------
[Journal]
SystemMaxUse=50M
复制代码
五、配合syslog

systemd提供了socket:/run/systemd/journal/syslog,来兼容传统日志服务。若是要让传统的日志服务工做,则要用这个socket来替代/dev/log。若是是使用rsyslog,则不用更改。

设置开机启动syslog-ng:$ systemctl enable syslog-ng

六、清理日志

全部的日志都存放在/var/log/journal,这个目录下其实rm也能够用来清理,可是不推荐。 下面的方法比较推荐。 清理日志到小于100MB:$ journalctl --vacuum-size=100M 清理最先两周前的日志:$ journalctl --vacuum-time=2weeks

8、疑难和差错

一、寻找错误

这个案例中咱们以mydumper-ro.service为例 经过systemd寻找失败的服务:$ systemctl --state=failed 或者用systemd消息:$ journalctl -fp err 找到了错误unit后查看更多信息:$ systemctl status mydumper-ro 查到这个unit的PID是12345以后:$ journalctl -b _PID=12345 发现部份内核模块的配置文件有问题:$ ls -Al /etc/mydumper-ro.d 修复错误,最后从新启动服务便可。

二、诊断启动问题

在配置中使用内核参数引导:systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M

三、诊断一个服务

在服务的配置文件中加入诊断选项。

[Service]
Environment=SYSTEMD_LOG_LEVEL=debug
复制代码
四、短运行时间进程无日志

有时候某些短期进程没有任何输出,没有日志。这个时候应该使用PID来查询。

五、禁止程序崩溃是转储内存

须要使用旧的内存转储则在对应的服务的配置文件中加入下面的设置:

/etc/sysctl.d/49-coredump.conf
-----------------------------------
kernel.core_pattern = core
kernel.core_uses_pid = 0
复制代码
相关文章
相关标签/搜索