systemd服务和systemd相关命令

1 篇文章 0 订阅
1 篇文章 0 订阅

systemd介绍

systemd即为system daemon,是linux下的一种init软件。它在Centos7系统中是PID为1的进程。

在CentOS5和CentOS6的启动是采取SystemV init来管理的

先说一下SystemV它其实就是利用一系列脚本来启动服务的,依赖一个特定的启动顺序每次只能启动执行一个启动任务。

这些都是通过一个核心配置文件tab(/etc/init)和一组启动脚本以及符号链接集执行的,本质上为系统提供了合理的启动顺序,
支持不同的运行级别。

他的好处是依赖关系简单,任务之间泾渭分明的一个一个启动,即使某个基础服务出了错也便于排查。但也正因为如此,他的启动性能很不好。服务无法并行启动不说,而且只能按照预先规定的顺序启动服务。如果你安装了新的硬件或者新服务,他不提供及时支持的标准方法。最重要的是如果其中有一步没有执行成功可能造成系统无法启动,如常见的开机挂载磁盘,如果磁盘找不到可能造成系统无法启动的问题。
在这里插入图片描述
这是一个网上的图片,从中可以看到用户空间init的服务分别有JobA、JobB等,它必须一个接一个的启动,因此启动时间是他们的执行时间总和。
在这里插入图片描述

它的改进版Upstart在此基础上改成了互不相关的服务可以并行启动,这样启动总时间就等于时间消耗最大的一组服务,而不是所有服务之和。systemd在并行启动上采取了比Upstart更加激进的方案

如果服务之间有依赖关系,如A依赖于B的启动,那么A在启动完毕B还没有启动完毕时,A先发请求给B,B会将A的请求缓存,当B启动完毕后在进行处理。
当然这样做也有不好的地方,它增加的出现问题时的排查难度,你不能很快的知道哪些服务起来了哪些没起来
它违反"keep simple, keep stupid"的Unix 哲学,使systemd与其他服务成了强耦合

systemd架构图

在这里插入图片描述

Systemd 是通过unit 及其配置文件来管理控制系统服务、监听的socket、快照及其他与init相关的信息的。

systemd启动步骤

  • systemd加载配置信息,在上一文的启动过程中有具体说明
  • 判断启动级别,即default.target所指向的级别
  • 判断启动目标的依赖关系
  • 激活依赖服务,启动目标
  • 响应系统消息,激活其他组件

systemd中的单元

systemd除了负责处理进程和服务,还能挂载文件系统、监控网络套接字、快照和管理环境变量等等。systemd中所有服务和功能都被抽象成一个个单元(Unit),根据功能不同,单元类型也不同。systemd正是通过配置这些单元来开关、管理服务的。
单元的后缀多数为.service

Unit单元类型
以下单元类型支持自定义

systemd单元类型
单元类型扩展名说明
Service.service描述一个系统服务
Socket.socket描述一个进程间通信的套接字
Device.device描述一个内核识别的设备文件(硬件)
Mount.mount描述一个文件系统的挂载点
Automount.automount描述一个文件系统的自动挂载点
Swap.swap描述一个内存交换设备或交换文件
Path.path描述一个文件系统中文件或目录
Timer.timer描述一个定时器(用于实现类似cron的调度任务)
Snapshot.snapshot用于保存一个systemd的状态
Scope.scope用systemd的总线接口以编程的方式创建外部进程(即不是systemd管理的外部进程)
Slice.slice描述居于Cgroup的一组通过层次组织的管理系统进程(进程组)
Target.target描述组systemd的 单元

Unit配置文件

每一个 Unit 都有一个配置文件,告诉 Systemd 怎么启动这个 Unit

unit文件通常被放置于/usr/lib/systemd/system/etc/systemd/system/run/systemd/system

Systemd默认从目录/etc/systemd/system/读取配置文件。但是,里面存放的大部分文件都是符号链接,指向目录/usr/lib/systemd/system/,真正的配置文件存放在这个目录。

默认的配置文件后缀名是.service,即不指定后缀为其他的后缀如.socket、.mount等,那么系统认为它的后缀就是.service.
systemd文件一般由:[Unit] 、[Service] 、 [Install]三部分组成
官方定义为[Unit] 、 [unit type] 、 [Install]

下面举一个例子如sshd服务,

注意:容都是以键值对的形式存在且大小写敏感,以及等式两侧不可以有空格

cat /usr/lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service
Wants=sshd-keygen.service
[Service]
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target

[Unit]区块

keyvalue
Description简短描述
Documentation文档地址
Requires当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败
Wants与当前 Unit 配合的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败
BindsTo与Requires类似,它指定的 Unit 如果退出,会导致当前 Unit 停止运行
Before如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动
After如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之前启动
Conflicts这里指定的 Unit 不能与当前 Unit 同时运行
Condition…当前 Unit 运行必须满足的条件,否则不会运行
Assert…当前 Unit 运行必须满足的条件,否则会报启动失败

[Unit type]区块
这里以service为例,其他的不是很常用

keyvalue
Type定义启动时的进程行为。它有simple、forking、oneshot、dbus、notify、idle几种值。
User设置服务运行的用户
Group设置服务运行的用户组
PIDFile存放PID的文件路径,读取服务启动后守护程序主进程的PID。服务关闭会删除该文件(如果文件还存在)
ExecStart启动当前服务的命令
ExecStartPre启动当前服务之前执行的命令
ExecStartPost启动当前服务之后执行的命令
ExecReload重启当前服务时执行的命令
ExecStop停止当前服务时执行的命令
ExecStopPost停止当其服务之后执行的命令
RestartSec自动重启当前服务间隔的秒数,默认值0.1(s)
StartLimitInterval无限次重启,默认是10秒内如果重启超过5次则不再重启,设置为0表示不限次数重启
Restart定义何种情况 Systemd 会自动重启当前服务,可能的值包括always(总是重启)、on-success、on-failure、on-abnormal、on-abort、on-watchdog
RestartPreventExitStatus符合某些退出状态时不进行重启
TimeoutStartSec等待启动的时间。 守护进程服务没有在配置时间内发送启动完成的信号,认为该服务失败服务退出。

以秒为单位, “0”来禁用。 默认使用DefaultTimeoutStartSec,若使用Type=oneshot,则该模式默认情况下超时是禁用的
TimeoutStopSec等待关闭的超时时间
TimeoutSec快速配置TimeoutStartSec和TimeoutStopSec时间
Environment指定环境变量
KillModecontrol-group、mixed、none
PrivateTmp=True表示给服务分配独立的临时空间
注意:[Service]部分的启动、重启、停止命令必须使用绝对路径,使用相对路径则会报错
KillSignal服务的所有进程根据 KillSignal的设置被立即全杀死

type几种类型的解释
simple:默认值,执行ExecStart指定的命令,启动主进程
forking:以fork方式从父进程创建子进程,创建后父进程立即退出
oneshot:一次性进程,Systemd会等当前服务退出,再继续执行
dbus:当前服务通过D-Bus启动
notify:当前服务启动完毕,会通知Systemd,再继续往下执行
idle:若有其他任务执行完毕,当前服务才会运行
Restart的几种类型解释
no(默认值):退出后不会重启
on-success:只有正常退出时(退出状态码为0),才会重启
on-abnormal:只有被信号终止和超时,才会重启
on-abort:只有在收到没有捕捉到的信号终止时,才会重启
on-watchdog:超时退出,才会重启
always:不管是什么退出原因,总是重启
KillMode的几种类型解释
control-group(默认值):当前控制组里面的所有子进程,都会被杀掉
process:只杀主进程
mixed:主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号
none:没有进程会被杀掉,只是执行服务的 stop 命令。

下面举一个不是service类型的Unit type

cat /usr/lib/systemd/system/tmp.mount
[Unit]
Description=Temporary Directory
Documentation=man:hier(7)
Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
ConditionPathIsSymbolicLink=!/tmp
DefaultDependencies=no
Conflicts=umount.target
Before=local-fs.target umount.target

[Mount]
What=tmpfs
Where=/tmp
Type=tmpfs
Options=mode=1777,strictatime

# Make 'systemctl enable tmp.mount' work:
[Install]
WantedBy=local-fs.target

[Install]区块

keyvalue
WantedBy依赖该服务的服务列表
RequiredBy表示该服务所在的Target
Alias当前 Unit 可用于启动的别名
Also当前 Unit 激活(enable)时,会被同时激活的其他 Unit

编写一个自己的.service文件

cat /usr/lib/systemd/system/myshell.service
[Unit]
Description=my test service
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=simple
PIDFile=/tmp/my.pid
ExecStartPre=/usr/bin/rm -f /tmp/my.pid
ExecStart= /usr/sbin/test.sh
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
#[Install]
#WantedBy=multi-user.target

cat test.sh
#!/bin/bash
while true
do
   echo `date`,"ok" >>/tmp/result.log
done

#!/bin/bash是必须的,否则会提示203错误异常

简单的自启动示例

[Unit]
Description=mytest
[Service]
Type=simple
ExecStart=/root/mytest.sh
Restart=always
RestartSec=5
StartLimitInterval=0
[Install]
WantedBy=multi-user.target

当业务因受到OOM而退出时,不希望重新启动,其他情况下自动启动

[Unit]
Description=mytest
[Service]
Type=simple
ExecStart=/root/mem
Restart=always
RestartSec=5
StartLimitInterval=0
RestartPreventExitStatus=SIGKILL
[Install]
WantedBy=multi-user.target


#/root/mem.c(不断消耗内存直到OOM)
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
  int main ()
  {
      char *c = NULL;
      int count = 1;
      while(1){
          c = (char *)malloc(1024*2048*50);
          if(!c){
              printf("malloc error!n");
              return -1;
          }
          memset(c, 0, 1024*2048*50);
          printf("malloc %dM memoryn", 100*count++);
          usleep(500000);
      }
   }
gcc -o /root/mem /root/mem.c
systemctl daemon-reload
systemctl start mytest

测试结果

[root@fzxiaomange ~]# systemctl status mytest
● mytest.service - mytest
   Loaded: loaded (/usr/lib/systemd/system/mytest.service; disabled; vendor preset: disabled)
   Active: failed (Result: signal) since Sat 2018-10-20 23:32:24 CST; 45s ago
   Process: 10555 ExecStart=/root/mem (code=killed, signal=KILL)
 Main PID: 10555 (code=killed, signal=KILL)
     
Oct 20 23:31:55 fzxiaomange.com systemd[1]: Started mytest.
Oct 20 23:31:55 fzxiaomange.com systemd[1]: Starting mytest...
Oct 20 23:32:24 fzxiaomange.com systemd[1]: mytest.service: main process exited, code=killed, status=9/KILL
Oct 20 23:32:24 fzxiaomange.com systemd[1]: Unit mytest.service entered failed state.
Oct 20 23:32:24 fzxiaomange.com systemd[1]: mytest.service failed.

重点看上面第6行 MainPID:10555(code=killed,signal=KILL),这行表示主进程的状态,常见有2种情况

code=exited, status=143:表示systemd认为主进程自行退出的,exit code为143

code=killed, signal=KILL:表示systemd认为主进程是被kill的,接收到的信号是SIGKILL

等待5秒后,并没有自动重启,符合预期

此时将RestartPreventExitStatus=SIGKILL改为RestartPreventExitStatus=SIGTERM

执行systemctl restart mytest,再进行一次观察,等待5秒后,服务自动重启,符合预期

服务状态列表

状态描述
loaded系统服务已经初始化完成,加载过配置
actvie(running)正常运行
actvie(exited)正常结束的服务,
active(waitting)正在执行当中, 等待其他的事件才继续处理
inactive服务关闭
enabled服务开机启动
disabled服务开机不自启
static服务开机启动项不可被管理
falied系统配置错误

systemd中的系统管理

Systemd并不是一个命令,而是一组命令,涉及许多系统管理

systemctl

systemctl功能特别多,有系统管理、服务管理等
系统管理

# 检查系统是否完全运行
#	running 系统完全可控;
#	degraded 系统可控,但存在单元失败;
#	maintenance 营救模式启动;
#	stopping 管理器停止
systemctl is-system-running

# 设置一个或多个环境变量
systemctl set-environment NAME=VALUE

# 取消设置一个或多个环境变量
systemctl unset-environment NAME

# 重启系统
systemctl reboot

# 关闭系统,切断电源
systemctl poweroff

# CPU停止工作
systemctl halt

# 暂停系统
systemctl suspend

# 让系统进入冬眠状态
systemctl hibernate

# 让系统进入交互式休眠状态
systemctl hybrid-sleep

# 启动进入救援状态(单用户状态)
sudo systemctl rescue

# 进入紧急模式
systemctl emergency

服务管理

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

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

# 立即启动一个服务
systemctl start httpd.service

# 立即停止一个服务
systemctl stop httpd.service

# 重启一个服务
systemctl restart httpd.service

# 尝试重启某个服务
systemctl try-restart httpd

# 杀死一个服务的所有子进程
systemctl kill httpd.service

# 重新加载一个服务的配置文件
systemctl reload httpd.service

# 设置一个服务开机启动
systemctl enable httpd.service

# 设置一个服务开机不启动
systemctl disable httpd.service

# 屏蔽某个服务(屏蔽后start无法启动)
systemctl mask httpd

# 显示某个服务(可以启动)
systemctl unmask httpd

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

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

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

#查看一个服务的依赖关系(如果依赖target需要展开加--all)
systemctl list-dependencies nginx.service

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

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

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

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

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

# 显示系统状态
systemctl status

配置文件管理

# 列出所有配置服务, -t 指定类型
systemctl list-unit-files
systemctl list-unit-files -t socket
sysemctl list-unit-files --type=service
systemctl list-unit-files -t mount

#查看一个服务的unit配置文件
systemctl cat httpd.service

# 显示某个 Unit 的所有配置参数细节
systemctl show httpd.service

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

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

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

运行级别管理


# 查看启动时的默认 Target
systemctl get-default

# 设置启动时的默认 Target
systemctl set-default multi-user.target

# 关闭前一个 Target 里面所有不属于后一个 Target 的进程
# 临时切换运行级别
systemctl isolate multi-user.target

journalctl

日志管理
Systemd Journal用二进制格式保存所有日志信息,用户使用journalctl命令来查看日志信息。相较于syslog无需再进行字符串分析处理。

# 查看所有日志(默认情况下 ,只保存本次启动的日志)
journalctl

# 查看内核日志(不显示应用日志)
journalctl -k

# 查看系统本次启动的日志
journalctl -b
journalctl -b -0

# 查看上一次启动的日志(需更改设置)
journalctl -b -1

# 查看指定时间的日志
journalctl --since="2020-08-20 12:00:00"
journalctl --since "20 min ago"
journalctl --since yesterday
journalctl --since "2020-08-23" --until "2020-08-24 12:00"
journalctl --since 09:00 --until "1 hour ago"

# 显示尾部的最新10行日志
journalctl -n

# 显示尾部指定行数的日志
journalctl -n 20

# 实时滚动显示最新日志
journalctl -f

# 查看指定服务的日志
journalctl /usr/lib/systemd/systemd

# 查看指定进程的日志
journalctl _PID=1

# 查看某个路径的脚本的日志
journalctl /usr/bin/bash
journalctl /usr/sbin/crond
journalctl /usr/bin/passwd

# 查看指定用户的日志
journalctl _UID=1 --since today

# 查看某个 Unit 的日志
journalctl -u httpd.service
journalctl -u httpd.service --since today

# 实时滚动显示某个 Unit 的最新日志
journalctl -u httpd.service -f

# 合并显示多个 Unit 的日志
journalctl -u httpd.service -u mysqld.service --since today

# 查看指定优先级(及其以上级别)的日志,共有8级
# 0: emerg
# 1: alert
# 2: crit
# 3: err
# 4: warning
# 5: notice
# 6: info
# 7: debug
journalctl -p err -b

# 日志默认分页输出,--no-pager 改为正常的标准输出
journalctl --no-pager

# 以 JSON 格式(单行)输出
journalctl -b -u httpd.service -o json

# 以 JSON 格式(多行)输出,可读性更好
journalctl -b -u httpd.service -o json-pretty

# 显示日志占据的硬盘空间
journalctl --disk-usage

# 指定日志文件占据的最大空间
journalctl --vacuum-size=1G

# 指定日志文件保存多久
journalctl --vacuum-time=1years

systemd-analyze

启动相关的耗时

# 查看启动耗时
systemd-analyze                                                                                       

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

# 显示瀑布状的启动过程流
systemd-analyze critical-chain

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

hostnamectl

主机的一些信息设置

# 显示当前主机的信息
hostnamectl

# 设置主机名。
hostnamectl set-hostname wzp

# 设置平台类型
hostnamectl set-chassis vm

# 设置主机icon名
hostnamectl set-icon-name computer-vm

localectl

用于控制系统的本地化与键盘布局

# 查看本地化设置
localectl

# 列出所有可用的 locale
localectl list-locales

# 设置字符集
localectl set-locale LANG=en_GB.utf8

# 列出所有可用的列出所有可用的控制台键盘映射
localectl list-keymaps

# 设置控制台的键盘映射(中国人应设为 "us")
localectl set-keymap us

# 列出所有可用的X11键盘的 Layout
localectl list-x11-keymap-models

# 设置默认的X11键盘布局(中国人应设为 "us")
localectl set-x11-keymap us

timedatectl

时间相关设置

# 显示系统的当前时间和日期
timedatectl  status   
RTC time是硬件时钟的时间。

# 查看所有可用的时区:
timedatectl list-timezones

# 根据地理位置找到本地的时区:
timedatectl list-timezones | grep  "Asia/S.*"

# 在Linux中设置本地时区,使用set-timezone开关:
timedatectl set-timezone “Asia/Shagnhai”

# 可以使用timedatectl命令设置系统的日期和时间:
timedatectl set-time 15:58:30
#只设置时间的话可以使用set-time开关以及HH:MM:SS(小时,分,秒)的时间格式。

# 只设置日期的话可以使用set-time开关以及YY:MM:DD(年,月,日)的日期格式。
timedatectl set-time 20200824

# 设置日期和时间:
timedatectl set-time '16:10:40 2020-08-24'

# 设置硬件时钟为UTC可以使用 set-local-rtc boolean-value选:
timedatectl | grep local #首先确定硬件时钟是否设置为本地时区:
timedatectl set-local-rtc 1   #将硬件时钟设置为本地时区:
timedatectl set-local-rtc 0   #将硬件时钟设置为UTC:

loginctl

查看当前登录的用户

# 列出当前session
loginctl list-sessions

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

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

参考文献:http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值