理解和管理systemd

学习systemd init系统的基本原理:如何配置它并使用它来管理系统。

理解systemd


Systemd是Linux的系统和服务管理器,兼容SysV和LSB初始化脚本。Systemd提供:

  • 先进的并行处理能力
  • 用socket和D-Bus激活来启动服务
  • 提供按需启动守护进程,使用Linux cgroups跟踪进程
  • 支持对系统状态进行快照和恢复
  • 维护挂载和自动挂载点
  • 实现一个复杂的基于事务依赖关系的服务控制逻辑。

systemctl 命令是管理systemd 的主要工具。它将SysVinit的服务和chkconfig命令的功能组合成一个工具,您可以使用它来永久启用和禁用服务,或者只针对当前会话来启用和禁用服务。

Systemd管理的服务称为units,它们是系统资源和服务的表示。下面的列表显示了systemd可以管理的单元类型:

service

        系统上的服务,包括了启动,重启和停止服务的相关说明

socket

        与服务相关联的网络套接字。

device

        一种由systemd专门管理的设备。

mount

        用systemd管理的挂载点。

automount

        在引导时自动挂载的挂载点。

swap

        系统上的交换空间。

target

        其他单元的同步点,通常用于在系统启动时启动开启了开机启动的服务

path

        用于基于路径激活的路径。例如,您可以根据某个路径的状态启动服务,例如该路径是否存在。

timer

        调度激活其他单元的定时器

snapshot

        当前systemd状态的快照。通常用于对systemd进行临时更改后的回滚。

slice

        通过Linux控制组节点(cgroups)限制资源。

scope

        来自systemd总线接口的信息。通常用于管理外部系统进程。

启动、停止和查询systemd服务


        你可以使用systemctl命令执行各种管理任务来控制systemd服务。下面是一组命令示例,演示如何使用systemctl管理systemd服务。

下面的命令控制一个foo服务:

  • 立即激活服务:
systemctl start foo
  • 立即停用服务:
systemctl stop foo
  • 重启服务
 systemctl restart foo
  • 显示服务的状态,是否服务在运行:
systemctl status foo
  • 启用服务的开机启动
systemctl enable foo
  • 禁用服务的开机启动
systemctl disable foo
  • 阻止服务自动启动甚至手动启动,除非解除
systemctl mask foo
  • 检查服务是否启用开机自启
systemctl is-enabled foo

详细信息请运行man systemctl。

修改已有systemd服务


这个例子展示了如何修改现有的服务。服务修改存储在/etc/systemd/system目录中的单个文件中或以服务命名的子目录中。例如,修改mysqld服务。

1. 可以使用systemctl edit修改系统服务

systemctl edit httpd.service

这将创建一个覆盖文件/etc/systemd/system/httpd.service.d/override.conf 并且在文本编辑器中打开它。你在该文件中写的任何内容都将附加到已经存在的服务文件

2. 添加一个自定义配置,例如:

[Service]
Restart=always
RestartSec=30

要替换一个可以被多次设值得选项,你必须首先清空它,否则这个覆盖文件将再次附加这个选项

[Service]
ExecStart=
ExecStart=<new command>

3. 保存文件。Systemd自动加载新的服务配置

4. 重启这个mysqld服务

systemctl restart httpd

要完全的替换(而不是仅仅的添加或者修改)一个已经存在的服务文件,使用systemctl edit --full命令.例如systemctl edit --full mysqld.service。这将创建/etc/systemctl/system/mysqld.service,它将取代现有的服务文件。

创建新的systemd服务


这个例子展示了如何为自定义服务创建单元文件。自定义单元文件位于/etc/systemd/system/中,扩展名为.service。例如,自定义foo服务使用/etc/systemd/system/foo.service单元文件。

1. 创建和编辑新配置文件

nano /etc/systemd/system/foo.service

2. 接下来的几个步骤描述了要添加到文件中的每个部分的参数:

        a. [Unit]部分提供了关于该服务的基本信息。foo服务使用以下参数:

            Description

                描述单元的字符串。Systemd将此描述显示在用户界面的单元名称旁边。

            After

                定义与第二个单元的关系。如果你激活这个单元,systemd只会在第二个单元之后激活它。例如,foo服务可能需要网络连接,这意味着foo服务指定了                        network.target作为After=条件。

                生成的[Unit]部分如下所示:      

[Unit]
Description=My custom service
After=network.target

        b. [Service]部分提供如何控制服务的说明。foo服务使用以下参数:

            Type

                定义systemd服务的类型。在这个例子中,foo服务是一个simple 的服务,它在启动服务时没有任何特殊的考虑。

            ExecStart

                启动服务的命令。这包括命令的完整路径和修改服务的参数。

                得到的[Service]部分是这样的:

[Service]
Type=simple
ExecStart=/usr/bin/sleep infinity

        c. [Install]部分提供了systemd如何安装服务的说明。foo服务使用以下参数:

            WantedBy

                如果该服务使用systemctl enable启用开机自启,该选项定义哪一个服务触发这个自定义服务。这主要用于在引导时启动这个自定义服务。在该例中,foo.service使用multi-user.target, 这标示着当systemd加载multi-user.target时启动foo.service

3. 完整的foo.service文件包含下面的内容:

[Unit]
Description=My custom service
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/sleep infinity

[Install]
WantedBy=multi-user.target

4. 使systemd发现新的服务,重载服务文件:

systemctl daemon-reload

5. 启动自定义foo服务:

systemctl start foo.service

6. 检查该服务的状态确保这个服务是运行中:

$ systemctl status foo.service
● foo.service - My custom service
   Loaded: loaded (/etc/systemd/system/foo.service; disabled; vendor preset: disabled)
   Active: active (running) since 一 2021-10-11 09:39:26 CST; 5s ago
 Main PID: 2183 (sleep)
   CGroup: /system.slice/foo.service
           └─2183 /usr/bin/sleep infinity

10月 11 09:39:26 localhost.localdomain systemd[1]: Started My custom service.

将SysVinit服务转换为systemd服务


旧版本的系统使用SysVinit脚本管理服务,本节提供了一些关于如何将SysVinit脚本转换为systemd等价脚本的指南。

1. 在你的SysVinit脚本中确定服务运行级别。这通常定义在脚本的开头注释部分的chkconfig指令。例如,下面这行标识着该服务使用runlevels 2,3和5:

# chkconfig: 235 20 80

systemd使用targets替代runlevels. 使用这个表Table 1. Runlevel to target mapping去转换运行级别到targets。在该例中,运行级别2,3和5都是multi-user runlevels.所以这个systemd服务可以使用下面的配置:

[Install]
WantedBy=multi-user.target

如果你启用这个自定义服务为开机自启(systemctl enable foo.service),当系统启动并加载multi-user.target时systemd将加载这个服务

2. 确定依赖的services和targets。例如,如果该自定义服务需要网络连接,指定network.target作为依赖:

[Unit]
Description=My custom service
After=network.target

3. 在SysVinit脚本中确定启动该服务的命令并将其转换为systemd等效的配置。例如,init脚本可能包含一个start函数使用下面的格式:

start() {
  echo "Starting My Custom Service..."
  /usr/bin/myservice -D
}

在这个例子中,/usr/bin/myservice命令是一个自定义服务命令并且带有一个-D选项。设置ExecStart参数以使用此命令:

[Service]
ExecStart=/usr/bin/myservice -D

4. 检查SysVinit脚本,看看服务是否使用特殊命令重新启动服务。例如,脚本可能包含一个重新加载服务的reboot函数:

reboot() {
  echo "Reloading My Custom Service..."
  /usr/bin/myservice reload
}

在本例中,/usr/bin/myservice命令是自定义服务命令,并使用reload子命令重新加载服务。设置ExecReload参数以使用此命令:

[Service]
ExecReload=/usr/bin/myservice reload

或者,您可以省略ExecReload并使用默认行为,这将kill掉该服务并重新启动它。

5. 检查SysVinit脚本,看看服务是否使用特殊命令停止服务。例如,脚本可能包含一个stop函数来重新加载服务:

reboot() {
  echo "Stopping My Custom Service..."
  /usr/bin/myservice shutdown
}

在本例中,/usr/bin/myservice命令是自定义服务命令,并使用shutdown子命令优雅地停止服务。设置ExecStop参数以使用此命令:

[Service]
ExecStop=/usr/bin/myservice shutdown

或者,您可以省略ExecStop并使用默认行为,这将kill掉该服务。

6. 检查SysVinit脚本并识别任何附加参数或函数。使用systemd参数复制可能与您的服务相关的任何标识的SysVinit函数。

公共服务参数


Unit Parameters

此部分包含可以在服务的[Unit]部分中使用的参数。这些参数对其他systemd单位是通用的。

Description

一个自由格式的描述字符串

Documentation

该服务相关的文档或者配置URI.仅仅接受这几种类型:http://https://file:info:, man:.

Requires

配置对其他服务的依赖。如果这个服务被激活,这里列出的单元也会被激活。如果一个依赖的服务无法激活,systemd将不会启动该服务。此选项可以指定多次,也可以指定多个空格分隔的单元。

Wants

类似于Requires,除了失败的单元对该服务没有任何影响。

BindsTo

类似于Requires,除了停止依赖的单元也会停止该服务。

PartOf

类似于Requires,除了停止和重新启动依赖的单元,也要停止和重新启动该服务。

Conflicts

由空格分隔的单元名称列表,如果运行该列表的服务,将导致该服务不运行。

Before, After

用空格分隔的单元名称列表,用于配置服务之间依赖关系的排序。

OnFailure

以空格分隔的单元名称列表,当此服务进入失败状态时激活。
 

Install Parameters

本节包含可在服务的[Install]部分中使用的参数。这些参数对其他systemd单元是通用的。

Alias

在此服务下安装的附加名称以空格分隔的列表。这里列出的名称必须具有与服务文件名相同的后缀(即类型)。

RequiredBy, WantedBy

将服务定义为依赖于另一个服务。这通常定义target来触发已启用的服务运行。这些选项类似于[Unit]一节中的Requires 和Wants 。

Also

安装或卸载此服务时要安装或卸载的附加单元。

Service Parameters

此部分包含可在服务单元的[Service]部分中使用的参数。这些参数仅适用于systemd service单元。

Type

配置该服务的进程启动类型:

  • simple - The service starts as the main process. This is the default.

  • forking - The service calls forked processes and run as part of the main daemon.

  • oneshot - Similar to simple, except the process must exit before systemd starts follow-up services.

  • dbus - Similar to simple, except the daemon acquires a name of the D-Bus bus.

  • notify - Similar to simple, except the daemon sends a notification message using sd_notify or an equivalent call after starting up.

  • idle - Similar to simple, except the execution of the service is delayed until all active jobs are dispatched.

RemainAfterExit

一个布尔值,指定即使服务的所有进程都退出了,该服务是否仍被认为是活动的。默认为no。

GuessMainPID

一个布尔值,指定如果无法可靠地确定服务的主PID, systemd是否应该猜测它。这个选项将被忽略,除非设置了Type=forking并且没有设置PIDFile。默认值为yes。

PIDFile

指向这个守护进程的PID文件的绝对文件名。对于Type=fork的服务,建议使用此选项。Systemd在服务启动后读取守护进程主进程的PID。Systemd不会写入此处配置的文件,尽管它会在服务关闭后删除该文件。

BusName

到达此服务的D-Bus总线名称。对于Type=dbus的服务,此选项是必须的。

ExecStart

服务启动时执行的命令和参数。

ExecStartPre, ExecStartPost

在ExecStart命令之前或之后执行的附加命令。

ExecReload

服务重新加载时要执行的命令和参数。

ExecStop

服务停止时要执行的命令和参数。

ExecStopPost

在服务停止后执行的附加命令。

RestartSec

重启服务前休眠的时间(以秒为单位)。

TimeoutStartSec

等待服务启动的时间,以秒为单位。

TimeoutStopSec

等待服务停止的时间,以秒为单位。

TimeoutSec

同时配置TimeoutStartSecTimeoutStopSec的简写。

RuntimeMaxSec

服务运行的最大时间,以秒为单位。传递infinity (默认值)以配置无运行时限制。

Restart

配置服务进程退出、终止或超时时是否重新启动服务:

  • no - The service will not be restarted. This is the default.

  • on-success - Restart only when the service process exits cleanly (exit code 0).

  • on-failure - Restart only when the service process does not exit cleanly (node-zero exit code).

  • on-abnormal - Restart if the process terminates with a signal or when a timeout occurs.

  • on-abort - Restart if the process exits due to an uncaught signal not specified as a clean exit status.

  • always - Always restart.

将runlevels对应到targets


systemd targets提供一个与SysVinit runlevels相似的目的,但是表现得又有点不同。每个target都有一个名称而不是数字,每个target都有特定的用途。Systemd通过继承另一个target的所有服务并向其添加额外的服务来实现一些target。 一些systemd target模拟常见的sysvinit运行级别,这意味着您可以使用熟悉的telinit RUNLEVEL命令切换targets,在之前系统中安装的特定runlevels(0、1、3、5和6)与特定的systemd target有1:1的映射。

然而,用户自定义的运行级别2和4并不是如此的。要使用这些运行级别,创建一个新的命名systemd target,例如/etc/systemd/system/$YOURTARGET,该目标以一个现有的运行级别为基础,创建一个目录/etc/systemd/system/$YOURTARGET.wants,然后将要启用的附加服务符号链接到该目录中。

下面是SysVinit运行级别到systemd目标的映射。

Table 1. Runlevel to target mapping
Sysvinit Runlevelsystemd TargetNotes

0

runlevel0.target, poweroff.target

Halt the system.

1, s, single

runlevel1.target, rescue.target

Single user mode.

2, 4

runlevel2.target, runlevel4.target, multi-user.target

User-defined/Site-specific runlevels. By default, identical to 3.

3

runlevel3.target, multi-user.target

Multi-user, non-graphical. Users can usually login via multiple consoles or via the network.

5

runlevel5.target, graphical.target

Multi-user, graphical. Usually has all the services of runlevel 3 plus a graphical login.

6

runlevel6.target, reboot.target

Reboot

emergency

emergency.target

Emergency shell

对应service命令

下表演示了SysVinit命令的systemd等效命令。

所有最新版本,如果不使用服务名后缀,systemctl的都使用.service后缀。例如,systemctl启动frobozz.service与systemctl start frobozz相同。

Sysvinit Commandsystemd CommandNotes

service frobozz start

systemctl start frobozz

Used to start a service (not reboot persistent)

service frobozz stop

systemctl stop frobozz

Used to stop a service (not reboot persistent)

service frobozz restart

systemctl restart frobozz

Used to stop and then start a service

service frobozz reload

systemctl reload frobozz

When supported, reloads the config file without interrupting pending operations.

service frobozz condrestart

systemctl condrestart frobozz

Restarts if the service is already running.

service frobozz status

systemctl status frobozz

Tells whether a service is currently running.

ls /etc/rc.d/init.d/

systemctl or systemctl list-unit-files --type=service or
ls /lib/systemd/system/*.service /etc/systemd/system/*.service

Used to list the services that can be started or stopped
Used to list all the services and other units

chkconfig frobozz on

systemctl enable frobozz

Turn the service on, for start at next boot, or other trigger.

chkconfig frobozz off

systemctl disable frobozz

Turn the service off for the next reboot, or any other trigger.

chkconfig frobozz

systemctl is-enabled frobozz

Used to check whether a service is configured to start or not in the current environment.

chkconfig --list

systemctl list-unit-files --type=service or ls /etc/systemd/system/*.wants/

Print a table of services that lists which runlevels each is configured on or off

chkconfig --list | grep 5:on

systemctl list-dependencies graphical.target

Print a table of services that will be started when booting into graphical mode

chkconfig frobozz --list

ls /etc/systemd/system/*.wants/frobozz.service

Used to list what levels this service is configured on or off

chkconfig frobozz --add

systemctl daemon-reload

Used when you create a new service file or modify any configuration

 表中列出的所有/sbin/service和/sbin/chkconfig命令在基于systemd的系统上仍然可以继续工作。除了一个例外: chkconfig --list

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
systemd 是一种用于启动、管理和监控 Linux 系统的初始化系统。它的源代码包含了各个模块和组件的实现,以及整个系统的核心功能。 systemd 的源码主要分为以下几个部分: 1. `core`:这是 systemd 的核心部分,包含了启动和管理服务的功能。它实现了 systemd 运行时的基本逻辑,包括服务启动、停止、重启等操作的处理流程,还有各种配置项的解析和加载。 2. `units`:这个目录下存放了所有 systemd 服务的配置文件。每个服务都有一个对应的单元文件,用来描述该服务的各种属性和依赖关系。这些单元文件中定义了服务的启动类型、运行级别、依赖关系等信息。 3. `sd-boot`:这个目录包含了 systemd 的引导加载器的相关源码。它负责在系统启动时加载内核和 initramfs,并启动 systemd 作为系统的第一个进程。 4. `journal`:这个目录存放了 systemd 用于存储系统日志的相关代码。systemd-journald 负责收集、存储和管理系统日志,以便用户和管理员能够方便地检索和分析日志信息。 5. `network`:这个目录下包含了 systemd 的网络管理相关代码。systemd-networkd 负责网络接口的配置和管理,包括 IP 地址、路由表、网络桥接等。 6. `udev`:这个目录中存放了 systemd-udev 的源码,它负责设备和驱动程序的管理。udev 可以在设备被插入或移除时执行特定操作,如加载或卸载驱动程序、运行用户定义的脚本等。 总体而言,systemd 的源码实现了一个功能强大且高度集成的初始化系统,通过模块化的设计,提供了管理和监控 Linux 系统的各个方面的功能。通过深入研究和理解 systemd 的源码,开发者可以了解其内部实现细节,并对其进行定制和扩展,以满足特定需求或解决特定问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值