优秀的编程知识分享平台

网站首页 > 技术文章 正文

Linux服务管理之Systemd配置详解,呕心沥血,匠心之作

nanyue 2024-11-04 13:09:03 技术文章 9 ℃

导读

本文内容主要分为Service服务配置文件详解Target配置文件详解Target和Service文件的关系和区别三个部分,其中介绍Service部分由于其涉及知识较多,因此篇幅较其他部分长一些,请耐心观看。

由于文章以markdown格式编写,可能会出现显示样式部分与头条格式有些不兼容的情况。

一、Service服务配置文件详解

1.1 服务配置文件路径

对于那些支持Systemd的应用,安装的时候,会自动在/usr/lib/systemd/system目录中添加一个以.service后缀结尾的配置文件,这种情况常见于使用apt、yum软件仓库安装,或者通过软件官方提供的deb、rpm包安装的应用

如果是通过源码或或二进制方式安装的应用,需要用户自行在/usr/lib/systemd/system目录中添加一个以.service后缀结尾的配置文件,配置文件内容需要遵循一定的格式和定义

如果想要实现应用服务开机自动启动,需要执行systemctl enable server_name,此时Linux会在/etc/systemd/system目录下新增一个链接符号文件,目标路径指向/usr/lib/systemd/systemd中的service文件

1.2 Systemd管理服务的常用命令

  • 当新增/修改服务配置文件后,需载入配置信息,使其注册生效
systemctl daemon-reload
  • 启动服务
systemctl start service_name
  • 停止服务
systemctl stop service_name
  • kill服务
# 有时候服务停止没有响应,服务停不下来,这时候就需要将进程kill掉了
systemctl kill service_name
  • 重启服务
systemctl restart service_name
  • 设置服务开机自启动
systemctl enable service_name
# 设置开机自启动,并启动服务
systemctl enable service_name
  • 取消服务开机自启动
systemctl disable service_name
  • 查看服务的配置文件
systemctl cat service_name
  • 获取默认target
systemctl get-default
  • 设置默认target
systemctl set-default <target>

1.3 服务配置文件的组成

以sshd的服务配置文件为例,其服务配置文件位于/usr/lib/systemd/system/sshd.service

[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.target
Wants=sshd-keygen.target

[Service]
Type=notify
EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config
EnvironmentFile=-/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target

可以看出,配置文件主要由3部分组成,分别是[Unit]、[Service]、[Install]

  • [Unit]区块:启动顺序与依赖关系
  • [Service]区块:启动行为
  • [Install]区块:定义如何安装这个配置文件,即怎样做到开机启动

1.3.1 Unit区块

Unit区块主要包括Description、Documentation、After、Wants等控制参数

(1)Description

当前服务的简单描述信息

(2)Documentation

指定服务相关说明文档存放路径

(3)启动顺序(After、Before)

After和Before 参数定义的启动顺序主要是在系统启动(开机)时服务初始化的顺序>。它确保某些服务在其他服务启动完成后或启动完成前启动,从而保证系统的稳定性和依赖关系的正确处理

  • After
    表示如果network.target或sshd-keygen.target需要启动,那么sshd.service应该在它们之后启动
  • Before
    Before和After相反,表示应该在哪些服务之前启动

注意,After和Before字段只涉及启动顺序,不涉及依赖关系。

举例,某Web应用需要MySQL数据库储存数据。在配置文件中,它只定义要在MySQL之后启动,而没有定义依赖MySQL。上线后,由于某种原因,MySQL需要重新启动,在停止服务期间,该Web应用就会无法建立数据库

(4)设置依赖关系(Wants、Requires)

  • Wants
    表示sshd.service和sshd-keygen.service之间存在“弱依赖”关系,即如果sshd-keygen.service启动失败或停止运行,不影响sshd.service继续执行。Wants表示一种弱依赖关系。它表示当前单元希望另一个单元也被启动,但如果另一个单元未能启动,当前单元仍然可以启动。常用于非关键性依赖关系。
  • Requires
    表示“强依赖”关系,即如果sshd-keygen.service服务启动失败或异常退出,那么sshd.service也会启动失败或停止启动。Requires表示一种强依赖关系。它表示当前单元依赖于另一个单元,如果另一个单元未能启动或失败,当前单元也会失败并停止启动。常用于关键性依赖关系。

注意,Wants和Requires字段只涉及依赖关系,与启动顺序无关,默认情况下是同时启动的

  • 结合使用
    有时需要同时使用Wants或Requires与After来确保启动顺序和依赖关系。
    示例:
[Unit]
Description=My Service
Requires=network.service
After=network.service

[Service]
ExecStart=/usr/bin/my-service

[Install]
WantedBy=multi-user.target

在这个示例中:

  • Requires=network.service确保network.service必须成功启动,否则my-service.service不会启动。
  • After=network.service确保my-service.service在network.service启动完成后再启动。

总结:

  • Wants: 弱依赖关系,表示希望另一个单元启动,但不强制要求。
  • Requires: 强依赖关系,表示必须依赖另一个单元,如果另一个单元未能启动,当前单元也不会启动。通过合理使用Wants和Requires,可以精细控制systemd单元的启动顺序和依赖关系,确保系统服务按预期运行。

1.3.2 Service区块

Service区块定义了如何启动当前服务,常用的字段有Type、EnvironmentFile、ExecStart、ExecStop、ExecReload等

(1)服务类型

  • Type
    Type字段定义了服务启动类型,它可以设置的值如下:
    • simple(默认值):服务启动时,进程为主进程
      适用于不会自行后台运行的长时间运行的服务。这是最简单的配置,通常用于不需要复杂启动过程的应用程序
    • forking:服务采用fork()方式启动,此时父进程将会退出,子进程将成为主进程
      适用于那些自行生成子进程并退出父进程的服务(即守护进程)。例如,传统的 Apache HTTP 服务器就是一个典型的forking类型服务
      示例:
[Unit]
Description=Legacy Apache HTTP Server

[Service]
Type=forking
ExecStart=/usr/sbin/httpd -k start
ExecStop=/usr/sbin/httpd -k stop

[Install]
WantedBy=multi-user.target
    • oneshot:类似simple,但只执行一次,执行完后服务退出
      此类型用于一次性任务和脚本,服务启动后执行一次然后退出。适用于需要执行一次性任务(如初始化任务)的场景。通常与RemainAfterExit=yes结合使用,使服务在任务完成后仍被视为活动
      例如:笔记本电脑启动时,要把触摸板关掉,这种服务只需运行一次即可,不需要长期运行。配置可以这么写:
[Unit]
Description=Switch-off Touchpad

[Service]
Type=oneshot
ExecStart=/usr/bin/touchpad-off

[Install]
WantedBy=multi-user.target

上面的配置文件,启动类型设为oneshot,表示这个服务只需要运行一次就可以,不需要长期运行
如果想要达到服务关闭后,将来某个时候还想重新打开,配置文件修改如下:

[Unit]
Description=Switch-off Touchpad

[Service]
Type=oneshot
ExecStart=/usr/bin/touchpad-off start
ExecStop=/usr/bin/touchpad-off stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

RemainAfterExit字段设置为yes,表示进程退出以后,服务仍然保持执行。这样的做法是,一旦使用systemctl stop命令停止服务,ExecStop指定的命令就会执行,从而重新开启触摸板

    • dbus:类似simple,但会等待D-Bus信号后才启动
      服务启动后,systemd等待 D-Bus 服务在 D-Bus 总线上注册自己,然后认为服务已激活。适用于提供 D-Bus 服务的应用程序,如 GNOME 的各种组件。
      常见的采用dbus方式启动的服务有NetworkManager、Avahi Daemon、Bluetooth service (bluetoothd)、ModemManager
      以下是NetworkManger的服务配置文件:
[Unit]
Description=Network Manager
Documentation=man:NetworkManager(8)
Wants=network.target
After=network-pre.target dbus.service
Before=network.target network.service

[Service]
Type=dbus
BusName=org.freedesktop.NetworkManager
ExecReload=/usr/bin/busctl call org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager Reload u 0
ExecStart=/usr/sbin/NetworkManager --no-daemon
Restart=on-failure
KillMode=process
CapabilityBoundingSet=CAP_NET_ADMIN CAP_DAC_OVERRIDE CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_MODULE CAP_AUDIT_WRITE CAP_KILL CAP_SYS_CHROOT
ProtectSystem=true
ProtectHome=read-only
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
Also=NetworkManager-dispatcher.service
Also=NetworkManager-wait-online.service
    • notify:类似simple,启动结束后会发出通知信号,然后Systemd再启动其他服务
      适用于需要精确控制启动过程,且能够发送通知的现代服务。这允许服务在完全初始化并准备好接受请求之前,不会被认为是活动的
      常见使用notify方式启动的服务有docker、journald(Systemd的日志服务)、postsql等
      以docker为例,其Systemd配置文件内容如下:
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target docker.socket firewalld.service containerd.service time-set.target
Wants=network-online.target containerd.service
Requires=docker.socket

[Service]
Type=notify
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process
OOMScoreAdjust=-500

[Install]
WantedBy=multi-user.target
    • idle:类似simple,但是要等他其他任务都执行完,才会启动该服务。
      主要使用场景是为该服务的输出,不与其他服务的输出相混合。适用于在系统空闲时运行的低优先级任务,这可以减少系统启动时的负载
      一个典型的使用idle类型的服务是updatedb,它是用于更新locate命令数据库的服务。这个服务可以配置为在系统空闲时运行,以减少对系统性能的影响。
      以下是一个updatedb服务的systemd配置文件示例:
[Unit]
Description=Update locate database
Documentation=man:updatedb(8)
ConditionACPower=true

[Service]
Type=idle
ExecStart=/usr/bin/updatedb

(2)启动用户和组

Systemd支持指定服务由哪个用户或组来运行,这样做的好处是进一步实现对权限的管理,增加系统的安全性。

如果在 systemd 服务配置文件中不设置 User 和 Group 参数,服务将默认以 root 用户的身份运行。这意味着服务进程将拥有系统的最高权限,可以访问和修改系统中的所有文件和资源。

推荐做法,为了提高系统的安全性,建议为每个服务设置专门的用户和组,限制其权限。当然,这需要根据实际情况灵活安排,因为有些服务由于涉及底层资源的调用,需要管理员权限才能正常启动。对于那些确认能以普通用户身份运行的服务,还是以普通用户运行

  • User
    指定以哪个用户运行服务。通过设置User,可以限制服务进程的权限,确保它智能访问该用户有权限访问的文件和资源。
    例如,如果你设置User=www,那么,服务进程将以www用户的身份运行
  • Group
    指定以哪个用户组运行服务。通过设置Group,可以进一步限制服务进程的权限,确保它只能访问该组有权限访问的文件和资源。
    例如,如果你设置Group=www,服务进程将以www组的身份运行

(3)环境变量

  • Environment
    在配置文件中定义内部变量,这样就可以在执行ExecStart等操作的时候直接引用
Environment="ENV_VAR=value"
  • EnvironmentFile
    有些软件启动时需要读取自己的环境变量,EnvironmentFile字段指定当前服务的环境参数文件。该环境参数文件内部的变量,可以用$key的形式,在当前配置文件中引用。在上述配置文件中,sshd的环境参数文件是/etc/sysconfig/sshd
    有些时候,我们可以看到EnvironmentFile后面的文件前面会加上一个横杠“-”,这是一个连词号,表示“抑制错误”,即发生错误的时候,不影响其他命令的执行。
  • 例如:EnvironmentFile=-/etc/sysconfig/sshd,表示即使/etc/sysconfig/sshd文件不存在,也不会抛出错误

(4)服务启动与停止

  • ExecStart
    定义启动进程时执行的命令。上面的例子中,启动sshd,执行的启动命令是/usr/sbin/sshd -D $OPTIONS,其中的变量$OPTIONS就来自EnvironmentFile字段指定的环境参数文件
  • ExecStop
    停止服务
  • ExecRload
    重启服务
  • ExecStartPre
    启动当前服务之前需要执行的命令
  • ExecStartPost
    启动当前服务之后需要执行的命令
  • ExecStopPre
    停止当前服务前需要执行的命令
  • ExecStopPost
    停止当前服务后需要执行的命令

(5)重启行为

Service区块中定义了一些字段,服务在各种原因停止时,Systemd所执行的操作

  • KillMode
    用于定义Systemd如何停止sshd服务
    上面的例子将KillMode设置为process,表示只停止主进程,不停止任何sshd子进程,即子进程打开的ssh session仍然保持连接的状态。这个设置不太常见,但对sshd很重要,否则当停止sshd服务时,会将自己打开的ssh session一起杀掉
    • control-group(默认值):当前控制组里面的所有子进程,都会被杀掉
    • process:只杀掉主进程,子进程保留
    • mixed:主进程将收到SIGTERM信号,子进程收到SIGKILL信号
    • none:没有进程会被杀掉,只是执行服务的stop命令
  • Restart
    定义了服务退出后,Systemd的重启方式。它允许系统管理员精细控制服务在遇到不同退出情况时是否应该重启。这是确保关键服务可靠性的重要机制,尤其是在生产环境中,服务的持续运行对业务至关重要。
    上面的例子中,Restart设置为on-failure,表示非正常情况服务异常停止或退出(例如内存溢出导致的程序崩溃),Systemd将会重启sshd。若是系统计划性的维护正常停止服务,或是开发人员出于调试程序目的停止服务,那么sshd服务将不会重启。
    Restart字段可以设置的值如下:
    • no(默认值):退出后不会重启
    • on-success:只有正常退出时(退出状态为0),才会重启
    • on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启。正常退出则不会重启
    • on-abnormal:只有被信号终止和超时,才会重启
    • on-abort:只有在收到没有捕捉到的信号终止时,才会重启
    • on-watchdog:超时退出,才会重启
    • always:服务无论是正常或非正常退出的情况,Systemd总是保持重启的行为

对于守护进程,建议设置为on-failure

  • RestartSec
    表示Systemd重启服务之前,需要等待的时间,单位是s

1.3.3 Install区块

Install区块定义如何安装这个配置文件,即怎样做到开机启动

  • WantedBy
    表示该服务所在的target。target的含义是服务组,表示一组服务。WantedBy=multi-user.target指的是当前服务所属target是multi-user.target
    这个设置非常重要,如sshd的配置文件,当执行systemctl enable sshd命令时,会在/etc/systemd/system中的multi-user.target.wants目录生成一个名字为sshd.service的符号文件,指向/usr/lib/systemd/system/sshd.service

一般来说,常用的target有两个:

  1. multi-user.target
    表示多用户命令状态
  1. graphical.target
    表示图形用户状态,它依赖于multi-user.target

二、Target配置文件详解

在 systemd 系统中,target 文件是一种特殊类型的单位(unit),用于组织和管理系统中的其他服务和单位。target 文件本身不包含要执行的进程,而是作为一种逻辑分组,用于控制和协调其他单位的启动顺序和方式。它们类似于传统 init 系统中的运行级别,但提供了更细粒度的控制和更灵活的依赖关系处理。

作用和用途

target 文件的主要作用包括:

  • 分组服务:将相关的服务和任务组织在一起,便于统一管理。
  • 管理启动顺序:通过依赖关系(如Wants,Requires),控制服务启动的顺序和条件。
  • 同步点:在系统启动或其他操作中,提供一个同步点,确保在继续执行其他任务前,一组特定的服务已经启动或达到某种状态。

常见的 target 文件

systemd 中有几个常见的 target 文件,它们在系统启动和运行中扮演重要角色:

  • multi-user.target:对应于传统的多用户运行级别,是标准的非图形用户界面多用户系统目标。
  • graphical.target:用于启动图形用户界面,通常在multi-user.target的基础上添加了图形环境。
  • network.target:网络服务启动后达到的目标,许多依赖网络的服务都会在此目标之后启动。
  • reboot.target, poweroff.target, halt.target:这些目标用于管理系统的关机、重启和停机过程。

示例:multi-user.target

以下是一个 multi-user.target 的示例配置文件:

[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

参数说明:

  • Description:Target文件的简要描述
  • Documentation:帮助指导文档路径
  • Requires:要求和basic.target一起运行
  • Conflicts:冲突字段,如果rescue.service或rescue.target正在运行,multi-user.target就不能运行,反之亦然
  • After:表示multi-user.target在basic.target、recue.service、rescue.target之后启动,如果它们有启动的话
  • AllowIsolate:允许使用systemctl isolate命令切换到multi-user.target

使用场景

管理员可以通过 systemctl 命令来管理 target,例如,切换当前目标或重新定义默认启动目标。这使得 systemd 非常灵活,能够适应各种不同的系统配置和需求。

通过理解和使用 target 文件,系统管理员可以更好地控制和优化系统的启动过程和运行状态。

三、Target和Service文件的关系和区别

target 和 service 文件是 Systemd 中的两种不同类型的单元文件,它们在系统启动和服务管理中扮演着不同的角色。

3.1 Service 文件

  • 作用: 定义和管理具体的服务(即守护进程)。
  • 内容: 包含服务的启动命令、运行时参数、依赖关系等。
  • 示例:nginx.service、mysqld.service等。

示例:

[Unit]
Description=My Example Service
After=network.target

[Service]
ExecStart=/usr/bin/my-service
User=myserviceuser
Group=myservicegroup
Restart=always

[Install]
WantedBy=multi-user.target

3.2 Target 文件

  • 作用: 组织和管理一组单元(包括service、socket、device等),类似于传统的运行级别(runlevels)。
  • 内容: 定义一组单元的集合,表示系统的某个状态或功能。
  • 示例:multi-user.target、graphical.target等。

示例

[Unit]
Description=Multi-User System
Requires=basic.target
Conflicts=rescue.target
After=basic.target rescue.target
AllowIsolate=yes

3.3 关系和区别

  1. 功能:
    • service文件用于定义和管理具体的服务。
    • target文件用于组织和管理一组单元,表示系统的某个状态或功能。
  1. 依赖关系:
    • service文件可以依赖于target文件。例如,一个服务可能需要在network.target之后启动。
    • target文件可以包含多个service文件。例如,multi-user.target包含多个服务,表示系统处于多用户模式。
  1. 启动顺序:
    • service文件通过After、Before等指令定义启动顺序。
    • target文件通过包含和依赖关系定义系统的启动顺序和状态。

示例关系

假设有一个 my-service.service 文件,它依赖于网络服务:

[Unit]
Description=My Service
After=network.target

[Service]
ExecStart=/usr/bin/my-service
User=myserviceuser
Group=myservicegroup
Restart=always

[Install]
WantedBy=multi-user.target

在这个例子中:

  • my-service.service文件定义了一个服务。
  • 该服务在network.target之后启动,确保网络服务已启动。
  • 该服务被包含在multi-user.target中,表示它是多用户模式的一部分。

通过这种方式,service 和 target 文件共同协作,确保系统服务按正确的顺序启动,并达到预期的系统状态。


Tags:

最近发表
标签列表