Linux: systemctl daemon-reload

LinuxBeginner
立即练习

简介

本教程将指导你使用 systemctl daemon-reload 命令在 Linux 系统上管理系统守护进程和服务。Systemd 是大多数现代 Linux 发行版的默认服务管理器,了解如何正确更新服务配置是 Linux 用户和管理员的一项基本技能。

在这个实验中,你将学习何时以及为何使用 systemctl daemon-reload 命令,创建和修改服务文件,并在不影响系统运行的情况下应用配置更改。在本教程结束时,你将能够轻松地处理 systemd 服务并有效地应用配置更改。

本实验需要联网学习,因此只有 Pro 用户可以启动虚拟机。将你的账户升级为 Pro

了解 systemd 和 systemctl 基础

Systemd 是大多数现代 Linux 发行版(包括我们在本实验中使用的 Ubuntu 22.04)的服务和系统管理器。它负责启动和管理系统服务,而 systemctl 是用于与 systemd 进行交互的主要命令行工具。

什么是系统守护进程?

守护进程是在你的 Linux 系统上持续运行的后台进程。这些进程执行各种任务,如提供网页服务(Apache、Nginx)、管理数据库(MySQL、PostgreSQL)或处理系统事件。Systemd 通过称为“单元文件”的标准化配置文件来管理这些守护进程。

基本的 systemctl 命令

让我们先探索一些基本的 systemctl 命令,以了解系统的当前状态:

  1. 通过点击“终端”图标打开一个终端。

  2. 使用以下命令列出所有活动的系统服务:

systemctl list-units --type=service

systemctl list-units --type=service

此命令会显示系统上所有当前活动的服务。你应该会看到类似以下的输出:

UNIT                                      LOAD   ACTIVE SUB     DESCRIPTION
accounts-daemon.service                   loaded active running Accounts Service
apparmor.service                          loaded active exited  AppArmor initialization
avahi-daemon.service                      loaded active running Avahi mDNS/DNS-SD Stack
...

Ctrl+CQ 退出命令。

  1. 检查特定服务的状态,例如 SSH 服务:
systemctl status ssh

systemctl status ssh

你应该会看到有关 SSH 服务的详细信息,包括它是否处于活动状态、其进程 ID 和最近的日志条目:

● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2023-06-13 12:34:56 UTC; 3h 25min ago
       Docs: man:sshd(8)
             man:sshd_config(5)
    Process: 1234 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
   Main PID: 1235 (sshd)
      Tasks: 1 (limit: 4915)
     Memory: 5.6M
        CPU: 236ms
     CGroup: /system.slice/ssh.service
             └─1235 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"
  1. 让我们看看 systemd 服务文件存储在哪里。这些是我们将在下一步中处理的文件:
ls -l /etc/systemd/system/

此目录包含定义 systemd 如何管理服务的服务单元文件。你应该会看到几个 .service 文件和符号链接。

  1. 系统提供的单元文件位于不同的目录中。让我们来查看一下:
ls -l /lib/systemd/system/

此目录包含系统自带的默认服务单元文件。

既然你已经了解了 systemd 的基础知识以及如何检查服务状态,那么下一步你就可以准备好创建和修改服务文件了。

创建一个简单的 systemd 服务文件

在这一步中,你将创建一个简单的 systemd 服务文件,该文件将运行一个自定义脚本。这将帮助你了解服务文件的工作原理以及如何对其进行修改。

创建一个简单的脚本

首先,让我们创建一个服务将运行的简单脚本:

  1. 为你的脚本创建一个目录:
mkdir -p ~/project/scripts
  1. 使用 nano 文本编辑器创建一个简单的脚本:
nano ~/project/scripts/hello-service.sh
  1. 将以下内容添加到脚本中:
#!/bin/bash

while true; do
  echo "Hello from custom service: $(date)" >> /tmp/hello-service.log
  sleep 10
done

Ctrl+X 退出编辑器,然后按 Y 保存文件,再按 Enter 确认文件名。

此脚本只是每隔 10 秒将一条包含当前日期的消息写入一个日志文件。

  1. 使脚本可执行:
chmod +x ~/project/scripts/hello-service.sh

创建一个 systemd 服务单元文件

现在,让我们创建一个将运行此脚本的 systemd 服务文件:

  1. 使用 sudo 权限创建一个新的服务文件:
sudo nano /etc/systemd/system/hello-service.service
  1. 将以下内容添加到服务文件中:
[Unit]
Description=Hello Service Demo
After=network.target

[Service]
Type=simple
ExecStart=/home/labex/project/scripts/hello-service.sh
Restart=on-failure
User=labex

[Install]
WantedBy=multi-user.target

让我们来了解一下这个文件的每个部分:

  • **[Unit]**:包含元数据和依赖项

    • Description:服务的人类可读描述
    • After:指定此服务应在网络就绪后启动
  • **[Service]**:定义服务应如何运行

    • Type=simple:服务立即启动
    • ExecStart:要运行的命令(我们的脚本)
    • Restart:如果服务失败则自动重启服务
    • User:以其身份运行服务的用户账户
  • **[Install]**:定义服务应在何时以及如何启用

    • WantedBy:指定服务应在何时启动(multi-user.target 表示正常系统操作)
  1. 保存文件并退出编辑器(在 nano 中按 Ctrl+X,然后按 Y,再按 Enter)。

  2. 让我们查看一下新创建的服务文件:

cat /etc/systemd/system/hello-service.service

你应该会看到你刚刚添加到文件中的内容。

cat /etc/systemd/system/hello-service.service

在下一部分中,你将学习如何使用 systemctl daemon-reload 命令加载并启动此服务。

使用 systemctl daemon-reload 来应用更改

既然你已经创建了一个 systemd 服务文件,你需要告知 systemd 有关这个新服务的信息。这就是 systemctl daemon-reload 命令发挥作用的地方。

什么是 systemctl daemon-reload?

systemctl daemon-reload 命令指示 systemd 重新加载所有服务文件并更新其内部配置。每当你:

  • 创建一个新的服务文件
  • 修改现有的服务文件
  • 删除一个服务文件

时,都有必要运行此命令。如果不运行此命令,systemd 将无法识别你的更改。

重新加载 systemd 配置

  1. 运行以下命令来重新加载 systemd 配置:
sudo systemctl daemon-reload

此命令成功时不会产生任何输出,但它会更新 systemd 的内部配置。

  1. 现在让我们检查一下 systemd 是否识别我们的新服务:
systemctl status hello-service

你应该会看到输出显示该服务已加载但未激活:

● hello-service.service - Hello Service Demo
     Loaded: loaded (/etc/systemd/system/hello-service.service; disabled; vendor preset: enabled)
     Active: inactive (dead)

启动服务

  1. 让我们启动我们的服务:
sudo systemctl start hello-service
  1. 再次检查状态以查看它是否正在运行:
systemctl status hello-service

systemctl status hello-service

你现在应该会看到该服务已激活并正在运行:

● hello-service.service - Hello Service Demo
     Loaded: loaded (/etc/systemd/system/hello-service.service; disabled; vendor preset: enabled)
     Active: active (running) since [timestamp]; [time] ago
   Main PID: [pid number] (hello-service.sh)
      Tasks: 2 (limit: 4915)
     Memory: 592.0K
        CPU: 5ms
     CGroup: /system.slice/hello-service.service
             └─[pid number] /bin/bash /home/labex/project/scripts/hello-service.sh
  1. 通过检查它创建的日志文件来验证我们的服务是否真的在工作:
cat /tmp/hello-service.log

你应该会看到几行类似于以下的输出:

Hello from custom service: Wed Jun 14 15:30:45 UTC 2023
Hello from custom service: Wed Jun 14 15:30:55 UTC 2023
Hello from custom service: Wed Jun 14 15:31:05 UTC 2023

日志条目将显示当前日期和时间,确认我们的服务正在运行并按预期执行脚本。

  1. 启用该服务以便在系统启动时自动启动:
sudo systemctl enable hello-service

你应该会看到类似于以下的输出:

Created symlink /etc/systemd/system/multi-user.target.wants/hello-service.service → /etc/systemd/system/hello-service.service.

这意味着该服务现在已启用,并且在系统启动时将自动启动。

现在你已经成功创建了一个服务,使用 systemctl daemon-reload 告知了 systemd 有关它的信息,并启动了该服务。在下一部分中,你将修改该服务并应用更改。

修改服务配置

在这一步中,你将修改服务配置,并使用 systemctl daemon-reload 应用这些更改。这将展示在更新服务配置时此命令的重要性。

修改服务文件

让我们修改服务,以更改其记录消息的频率:

  1. 编辑服务文件:
sudo nano /etc/systemd/system/hello-service.service
  1. [Service] 部分添加一个新的环境变量,以控制睡眠间隔。在 User=labex 行之后添加此行:
Environment="SLEEP_INTERVAL=5"
  1. 保存并退出文件(在 nano 中按 Ctrl+X,然后按 Y,再按 Enter)。

  2. 现在,编辑脚本以使用此环境变量:

nano ~/project/scripts/hello-service.sh
  1. 修改脚本以使用环境变量(用以下内容替换整个内容):
#!/bin/bash

## 如果未设置环境变量,则默认为10秒
INTERVAL=${SLEEP_INTERVAL:-10}

while true; do
  echo "Hello from custom service: $(date) - Interval: ${INTERVAL}s" >> /tmp/hello-service.log
  sleep $INTERVAL
done
  1. 保存并退出编辑器(在 nano 中按 Ctrl+X,然后按 Y,再按 Enter)。

应用更改

既然你已经对服务文件和脚本都进行了更改,就需要应用这些更改:

  1. 首先,重新加载 systemd 配置:
sudo systemctl daemon-reload
  1. 然后,重启服务以应用更改:
sudo systemctl restart hello-service
  1. 检查服务的状态:
systemctl status hello-service

你应该会看到服务正在使用更新后的配置运行。

  1. 通过检查日志文件来验证更改是否生效:
sleep 15 ## 等待收集一些日志条目
cat /tmp/hello-service.log | tail -5

现在你应该会看到服务每隔 5 秒记录一次消息,而不是 10 秒,并且日志条目应包含新的间隔信息:

Hello from custom service: Wed Jun 14 15:45:10 UTC 2023 - Interval: 5s
Hello from custom service: Wed Jun 14 15:45:15 UTC 2023 - Interval: 5s
Hello from custom service: Wed Jun 14 15:45:20 UTC 2023 - Interval: 5s

cat /tmp/hello-service.log | tail -5

了解发生了什么

让我们来了解一下刚才发生了什么:

  1. 你修改了服务文件以添加一个环境变量。
  2. 你更新了脚本来使用此环境变量。
  3. 你运行 systemctl daemon-reload 来告知 systemd 服务文件的更改。
  4. 你重启了服务以应用这些更改。

如果没有 systemctl daemon-reload 命令,systemd 将无法识别服务文件的更改,并且在重启服务时环境变量也不会传递给脚本。

这说明了为什么每当你修改服务文件时,systemctl daemon-reload 都是必不可少的——它确保在你尝试通过启动或重启服务来应用更改之前,systemd 能够了解你的更改。

故障排除与最佳实践

在这最后一步中,你将了解在使用 systemd 服务时可能出现的常见问题以及如何对其进行故障排除。你还将学习一些使用 systemctl daemon-reload 的最佳实践。

常见问题故障排除

1. 服务无法启动

如果你的服务无法启动,第一步是检查其状态:

systemctl status hello-service

这通常会提供详细的错误信息。让我们故意制造一个错误来看看如何进行故障排除:

  1. 编辑服务文件:
sudo nano /etc/systemd/system/hello-service.service
  1. ExecStart 行更改为指向一个不存在的脚本:
ExecStart=/home/labex/project/scripts/non-existent.sh
  1. 保存并退出编辑器。

  2. 重新加载 systemd 配置并尝试重启服务:

sudo systemctl daemon-reload
sudo systemctl restart hello-service
  1. 检查状态以查看错误:
systemctl status hello-service

你应该会看到表明脚本不存在的错误消息:

● hello-service.service - Hello Service Demo
     Loaded: loaded (/etc/systemd/system/hello-service.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since [timestamp]; [time] ago
    Process: [pid] ExecStart=/home/labex/project/scripts/non-existent.sh (code=exited, status=203/EXEC)
   Main PID: [pid] (code=exited, status=203/EXEC)
        CPU: 5ms

[timestamp] systemd[1]: Started Hello Service Demo.
[timestamp] systemd[pid]: hello-service.service: Failed to execute command: No such file or directory
[timestamp] systemd[pid]: hello-service.service: Failed at step EXEC spawning /home/labex/project/scripts/non-existent.sh: No such file or directory
[timestamp] systemd[1]: hello-service.service: Main process exited, code=exited, status=203/EXEC
[timestamp] systemd[1]: hello-service.service: Failed with result 'exit-code'.
  1. 将服务文件修复为指向正确的脚本:
sudo nano /etc/systemd/system/hello-service.service
  1. ExecStart 行改回:
ExecStart=/home/labex/project/scripts/hello-service.sh
  1. 保存并退出,然后重新加载并重启:
sudo systemctl daemon-reload
sudo systemctl restart hello-service
  1. 验证服务是否再次运行:
systemctl status hello-service

2. 读取日志以获取更多信息

在进行故障排除时,你可以使用 journalctl 来查看详细日志:

sudo journalctl -u hello-service

这将显示 hello-service 单元的所有日志,这对于诊断问题非常有价值。

要仅查看最近的日志:

sudo journalctl -u hello-service -n 20

要实时跟踪日志(类似于 tail -f):

sudo journalctl -u hello-service -f

Ctrl+C 退出日志跟踪模式。

使用 systemctl daemon-reload 的最佳实践

在使用 systemd 和 daemon-reload 命令时,以下是一些最佳实践:

  1. 更改后始终重新加载:在修改、添加或删除任何 systemd 单元文件后,始终运行 systemctl daemon-reload

  2. 应用前检查语法:在重新加载之前,你可以使用以下命令检查服务文件中的语法错误:

sudo systemd-analyze verify /etc/systemd/system/hello-service.service

如果没有错误,此命令不会产生任何输出。任何语法错误都会被报告。

  1. 使用服务模板:对于需要多个实例的服务,使用服务模板(文件名类似于 service@.service)以避免重复。

  2. 检查服务依赖项:确保你的服务具有正确的 After=Requires= 指令,以确保它们按正确的顺序启动。

  3. 正确清理:在删除服务时,确保在删除服务文件之前停止并禁用它:

sudo systemctl stop hello-service
sudo systemctl disable hello-service
sudo rm /etc/systemd/system/hello-service.service
sudo systemctl daemon-reload

现在让我们清理我们的示例服务:

sudo systemctl stop hello-service
sudo systemctl disable hello-service

你应该会看到表明符号链接已删除的输出:

Removed /etc/systemd/system/multi-user.target.wants/hello-service.service.

我们暂时不会删除服务文件,因为我们仍然需要它进行验证。

现在你了解了如何创建、修改和排除 systemd 服务的故障,以及 systemctl daemon-reload 命令在管理这些服务中的重要性。

总结

在本实验中,你已经学习了如何使用 systemctl daemon-reload 命令来管理 Linux 系统上的系统守护进程和服务。你已经:

  • 了解了 systemd 和 systemctl 的基础知识
  • 创建了一个自定义的 systemd 服务文件
  • 使用 systemctl daemon-reload 将更改应用于服务配置
  • 修改了服务文件并应用了这些更改
  • 学习了如何对常见问题进行故障排除以及遵循最佳实践

systemctl daemon-reload 命令在使用 systemd 服务时至关重要,因为它可确保 systemd 管理器了解你对服务配置所做的任何更改。如果没有此命令,直到下次重启,系统才会识别你对服务文件所做的更改。

随着你继续使用 Linux 系统,这些知识将非常有用,使你能够有效地管理服务并确保你的配置更改得到正确应用。