systemd 的使用
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 还引入了 localectl
、timedatectl
、hostnamectl
等新命令,使得系统配置更方便。本篇以 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
字段,表示在哪些服务之前启动;After
和Before
只涉及启动顺序,不涉及依赖关系;有时会有
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.service
或rescue.target
正在运行,multi-user.target
就不能运行,反之亦然。
After
:表示multi-user.target
在basic.target
、rescue.service
、rescue.target
之后启动,如果它们有启动的话。
AllowIsolate
:允许使用systemctl isolate
命令切换到multi-user.target
。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK