1

systemd 的使用

 1 year ago
source link: https://xujinzh.github.io/2022/06/17/systemd-usage/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在配置程序开机自启时,常常会用到 systemctl,其是 systemd 的主命令,用于管理系统。systemd 名字来源于 Unix 中的一个惯例:在 Unix 中常以 ‘d’ 作为系统守护进程(daemon,亦称为后台进程)的后缀标识。systemd 是 Linux 系统下的一套中央化系统及设定管理程式(init),包括守护进程、程式库以及应用软体,由 Lennart Poettering 带头开发。目前绝大多数的 Linux 发行版都已采用 systemd 代替原来的 System V,除了 systemctl,systemd 还引入了 localectltimedatectlhostnamectl 等新命令,使得系统配置更方便。本篇以 Ubuntu 为例,所有命令以普通用户运行,部分命令需要 sudo 权限。

设置开机自启

支持 systemd 的软件,在安装的时候会自动在 /lib/systemd/system 目录中添加一个配置文件。设置开机自启命令如下

sudo systemctl enable docker
# or
sudo systemctl enable docker.service

执行上面命令之后,会在 /etc/systemd/system 目录或其下的 *.target.wants 下添加一个符号链接,*docker.service 里的配置项 WantedBy 相关。开机时, systemd 只执行 /etc/systemd/system 目录里面的配置文件。当把修改后的 .service 配置文件直接放在 /etc/systemd/system 目录下会覆盖原始配置

获取 systemd 默认启动服务组(即上面的 target)方法如下:

systemctl get-default

默认安装的软件会自动设置开机自启和立即启动服务。但有时程序停止后,需要启动。常使用如下命令

sudo systemctl start docker

查看程序是否启动成功,可以使用如下命令

sudo systemctl status docker

正常结果如下:

● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2022-06-17 13:01:12 CST; 7s ago
Docs: https://docs.docker.com
Main PID: 6606 (dockerd)
Tasks: 32
CGroup: /system.slice/docker.service
└─6606 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

6月 17 13:01:12 jinzhongxu-PowerEdge-R740 systemd[1]: Started Docker Application Container Engine.
6月 17 13:01:12 jinzhongxu-PowerEdge-R740 dockerd[6606]: time="2022-06-17T13:01:12.625354075+08:00" level=info msg="API listen on /var/ru

上面输出结果含义:

  • Loaded 表示配置文件的位置,是否设为开机自启;

  • Active 表示运行状态,active 表示正在运行,inactive 表示没有运行;

  • Docs 表示文档说明信息;

  • Main PID 表示主进程;

  • Tasks 表示子进程数;

  • CGroup 表示应用的所有子进程;

  • 日志块 最下面的以日期开头的表示程序运行日志信息

查看实时日志信息,可以使用如下命令:

sudo journalctl -u docker -f

当需要停止服务时,可使用如下命令:

sudo systemctl stop docker

有时候,该命令可能没有相应,服务停不下来。这个时候可以使用 kill 向正在运行的进程发出 “杀进程” 的信号。

sudo systemctl kill docker

如果更改了 docker.service 里面的信息,那么需要重新加载,然后重启

sudo systemctl daemon-reload
# 然后重启
sudo systemctl restart docker

服务的运行启动完全有配置文件决定。一般 systemd 运行的软件的配置文件主要放在 /usr/lib/systemd/system/etc/systemd/system 目录下。找到配置文件后我们可以使用 vim 打开。或者使用如下命令查看。

systemctl cat sshd.service

结果大概是这样

# /lib/systemd/system/ssh.service
[Unit]
Description=OpenBSD Secure Shell server
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755

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

配置文件分成 Unit, Service, Install 三个块。下面分别对其进行介绍。

Unit:启动顺序与依赖关系

[Unit]
Description=OpenBSD Secure Shell server
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
  •  Description 表示当前服务的简单描述;

  • 有时还会有 Documentation 字段,给出文档位置;

  • After 表示如果 network.target, auditd.service 如果需要启动,那么 sshd 应在它们之后启动;

  • 有时会有 Before 字段,表示在哪些服务之前启动;

  • AfterBefore 只涉及启动顺序,不涉及依赖关系;

  • 有时会有 Wants 字段,表示该程序与其有”弱依赖“关系;

  • 有时会有 Requires 字段,表示该程序与其有“强依赖”关系;

Service:启动行为

[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755

Service 区块定义了如何启动当前服务。

  • EnvironmentFile 指定当前服务的环境参数文件。该文件内部是 key=value 键值对,可以用 $key 获取参数文件中的值;上面配置文件中有时会有 -,表示“抑制错误”,即发生错误时,不影响其他命令执行;

  • ExecReload字段:重启服务时执行的命令

  • ExecStop字段:停止服务时执行的命令

  • ExecStartPre字段:启动服务之前执行的命令

  • ExecStartPost字段:启动服务之后执行的命令

  • ExecStopPost字段:停止服务之后执行的命令

  • KillMode字段:定义 systemd 如何停止服务,上面的 process 表示只停止主进程,不停止任何 sshd 子进程,即子进程打开的 SSH session 仍然保持连接。这对于 SSH 很重要,不会连自己打开的 SSH session 一起杀掉;除了 process,还有 control-group (默认值),当前控制组里面的所有子进程都会被杀掉;mixed 主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号;none 没有进程会被杀掉,只是执行服务的 stop 命令;

  • Restart 字段:定义了 sshd 退出后,systemd 的重启方式,默认为 no,表示退出后不会重启;on-success 表示只有正常退出时(退出状态码为 0)才会重启;on-failure 表示非正常退出时(退出状态码非 0),包括被信号终止和超时,才会重启;on-abnormal 表示只有被信号终止和超时,才会重启;on-abort 表示只有在收到没有博捉到的信号终止时,才会重启;on-watchdog 表示超时退出,才会重启;always 表示不管是什么原因退出,总是重启;

  • Type 字段:定义启动类型。simple(默认值):ExecStart 字段启动的进程为主进程;forking:ExecStart 字段将以 fork() 方式启动,此时父进程将会退出,子进程将成为主进程;oneshot:类似于 simple,但只执行一次,systemd 会等它执行完,才启动其他服务;dbus:类似于 simple,但会等待 D-Bus 信号后启动;notify:类似于 simple,启动结束后会发出通知信号,然后 systemd 再启动其他服务;idle:类似于 simple,但是要等到其他任务都执行完,才会启动该服务。一种使用场合是为让该服务的输出,不与其他服务的输出相混合。

Install 区块

Install 区块定义如何按照这个配置文件,即怎样做到开机自启。

[Install]
WantedBy=multi-user.target
Alias=sshd.service
  • WantedBy字段:表示该服务所在的 Target,Target 的含义是服务组,表示一组服务。 WantedBy=multi-user.target 指的是, sshd 所在的 Target 是 multi-user.target 。这个设置非常重要,因为在执行 systemctl enable sshd 命令时,sshd.service 的一个符号链接,就会放在 /etc/systemd/system目录下面的 multi-user.target.wants 子目录之中。获取 systemd 默认的启动 target 命令是 systemctl get-default.

关于 target 有如下两个命令

# 查看 multi-user.target 包含的所有服务
systemctl list-dependencies multi-user.target

# 切换到另一个 target
# shutdown.target 就是关机状态
sudo systemctl isolate shutdown.target

一般来说,常用的 Target 有两个:一个是multi-user.target,表示多用户命令行状态;另一个是graphical.target,表示图形用户状态,它依赖于multi-user.target.

查看 target 的配置文件

systemctl cat multi-user.target
# /lib/systemd/system/multi-user.target
# SPDX-License-Identifier: LGPL-2.1+
#
# 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.

[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes

注意,Target 配置文件里面没有启动命令。

上面输出结果中,主要字段含义如下。

Requires字段:要求basic.target一起运行。

Conflicts字段:冲突字段。如果rescue.servicerescue.target正在运行,multi-user.target就不能运行,反之亦然。

After:表示multi-user.targetbasic.target 、 rescue.service、 rescue.target之后启动,如果它们有启动的话。

AllowIsolate:允许使用systemctl isolate命令切换到multi-user.target

  1. Systemd 入门教程:实战篇 - 阮一峰的网络日志

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK