14.4.管理 FreeBSD 中的服务
==========================

FreeBSD 在系统初始化和管理服务时使用 `rc(8) <https://www.freebsd.org/cgi/man.cgi?query=rc&sektion=8&format=html>`__ 系统的启动脚本。在 **/etc/rc.d** 中列出的脚本提供了基本的服务,可以用 `service(8) <https://www.freebsd.org/cgi/man.cgi?query=service&sektion=8&format=html>`__ 的 ``start`` 、\ ``stop`` 和 ``restart`` 选项来控制。例如,可以用下面的命令重启 `sshd(8) <https://www.freebsd.org/cgi/man.cgi?query=sshd&sektion=8&format=html>`__:

.. raw:: latex

   \diilbookstyleinputcell

.. code:: shell-session

   # service sshd restart

这个程序可以用来在一个正在运行中的系统上启动服务。服务将在系统启动时按照 `rc.conf(5) <https://www.freebsd.org/cgi/man.cgi?query=rc.conf&sektion=5&format=html>`__ 中的指定的那样自动启动。例如,要在系统启动时启用 `natd(8) <https://www.freebsd.org/cgi/man.cgi?query=natd&sektion=8&format=html>`__\ ,请在 **/etc/rc.conf** 中添加以下一行:

.. raw:: latex

   \diilbookstyleinputcell

.. code:: shell-session

   natd_enable="YES"

如果 ``natd_enable="NO"`` 一行已经存在,请把 ``NO`` 改为 ``YES``\ 。\ `rc(8) <https://www.freebsd.org/cgi/man.cgi?query=rc&sektion=8&format=html>`__ 脚本会在下一次启动时自动加载其依赖的服务,如下所述。

由于 `rc(8) <https://www.freebsd.org/cgi/man.cgi?query=rc&sektion=8&format=html>`__ 系统的主要目的是在系统启动和关闭时启动和停止服务,\ ``start`` 、\ ``stop`` 和 ``restart`` 选项只有在 **/etc/rc.conf** 中的变量设置适当时才会执行它们的操作。例如,只有在 **/etc/rc.conf** 中把 ``sshd_enable`` 设置为 ``YES`` 时,\ ``sshd restart`` 才会生效。要 ``start`` 、\ ``stop`` 和 ``restart`` 一个服务,而无需考虑 **/etc/rc.conf** 中的设置,需要在这些命令的前面添加前缀“one”。例如,要重启 `sshd(8) <https://www.freebsd.org/cgi/man.cgi?query=sshd&sektion=8&format=html>`__ 而不考虑当前 **/etc/rc.conf** 的设置,执行以下命令:

.. raw:: latex

   \diilbookstyleinputcell

.. code:: shell-session

   # service sshd onerestart

为检查某个服务是否在 **/etc/rc.conf** 中被启用,请用 ``rcvar`` 运行相应的 `rc(8) <https://www.freebsd.org/cgi/man.cgi?query=rc&sektion=8&format=html>`__ 脚本。这个例子将检查 `sshd(8) <https://www.freebsd.org/cgi/man.cgi?query=sshd&sektion=8&format=html>`__ 是否在 **/etc/rc.conf** 中被启用:

.. raw:: latex

   \diilbookstyleinputcell

.. code:: shell-session

   # service sshd rcvar
   # sshd
   #
   sshd_enable="YES"
   #   (default: "")

..

   **提示**

   ``# sshd`` 这一行是上面那个命令的输出,不是以 ``root`` 身份执行的命令。

要确定一个服务是否在运行,使用 ``status``\ 。例如,要验证 `sshd(8) <https://www.freebsd.org/cgi/man.cgi?query=sshd&sektion=8&format=html>`__ 是否正在运行:

.. raw:: latex

   \diilbookstyleinputcell

.. code:: shell-session

   # service sshd status
   sshd is running as pid 433.

在某些情况下,也可以 ``reload`` 一个服务。该操作试图向一个单独的服务发送信号,迫使服务重新加载其配置文件。在大多数情况下,这意味着向该服务发送一个 ``SIGHUP`` 信号。并非每个服务都支持这个功能。

`rc(8) <https://www.freebsd.org/cgi/man.cgi?query=rc&sektion=8&format=html>`__ 系统用于网络服务,它也为大部分的系统初始化做出了贡献。例如,当 **/etc/rc.d/bgfsck** 脚本被执行时,它会打印出以下信息:

.. raw:: latex

   \diilbookstyleinputcell

.. code:: shell-session

   Starting background file system checks in 60 seconds.

这个脚本被用来在系统初始化的时候在后台进行文件系统检测。

许多系统服务依赖于其他服务才能正常运行。例如,\ `yp(8) <https://www.freebsd.org/cgi/man.cgi?query=yp&sektion=8&format=html>`__ 和其它基于 RPC 的服务可能会在 `rpcbind(8) <https://www.freebsd.org/cgi/man.cgi?query=rpcbind&sektion=8&format=html>`__ 服务启动后才会启动。为了解决这个问题,关于依赖关系和其他元数据的信息被包含在每个启动脚本顶部的注释中。\ `rcorder(8) <https://www.freebsd.org/cgi/man.cgi?query=rcorder&sektion=8&format=html>`__ 程序被用来在系统初始化过程中解析这些注释,以确定系统服务应该被调用的顺序,以满足依赖关系:

所有的启动脚本都必须包含以下关键词,因为 `rc.subr(8) <https://www.freebsd.org/cgi/man.cgi?query=rc.subr&sektion=8&format=html>`__ 需要它来“enable”启动脚本:

-  ``PROVIDE``\ :指定这个文件提供的服务.

下列关键词可以放在每个启动脚本的顶部,他们并不是严格需要的,但是作为对 `rcorder(8) <https://www.freebsd.org/cgi/man.cgi?query=rcorder&sektion=8&format=html>`__ 的提示来说是很有用的:

-  ``REQUIRE``\ :列出此服务所需的服务,包含这个关键词的脚本将在指定的服务之 *后* 运行。
-  ``BEFORE``\ :列出依赖这个的服务,包含这个关键词的脚本将在指定服务之 *前* 运行。

通过为每个启动脚本仔细设置这些关键字,管理员可以对脚本的启动顺序进行精细的控制,而不需要某些 UNIX® 操作系统所使用的“运行级别”(runlevels)。

其他信息可以在 `rc(8) <https://www.freebsd.org/cgi/man.cgi?query=rc&sektion=8&format=html>`__ 和 `rc.subr(8) <https://www.freebsd.org/cgi/man.cgi?query=rc.subr&sektion=8&format=html>`__ 的用户手册中中找到。关于创建自定义 `rc(8) <https://www.freebsd.org/cgi/man.cgi?query=rc&sektion=8&format=html>`__ 脚本的说明,请参考\ `这篇文章 <https://docs.freebsd.org/en/articles/rc-scripting/>`__\ 。

14.4.1.管理特定的系统配置
-------------------------

系统配置信息的主要位置是 **/etc/rc.conf**\ 。该文件包含广泛的配置信息,在系统启动时被读取以配置系统,它提供了 **rc**\ \* 文件的配置信息。

**/etc/rc.conf** 中的条目会覆盖 **/etc/defaults/rc.conf** 中的默认设置。包含默认设置的文件不应该被编辑。相反,所有针对系统所做的修改都应该在 **/etc/rc.conf** 中进行。

在集群应用中可以采用一些策略,将整个站点的配置与系统特定的配置分开,以减少管理开销。推荐的方法是将系统特定的配置放入 **/etc/rc.conf.local**\ 。例如,\ **/etc/rc.conf** 中的这些条目适用于所有系统:

.. raw:: latex

   \diilbookstyleinputcell

.. code:: shell-session

   sshd_enable="YES"
   keyrate="fast"
   defaultrouter="10.1.1.254"

而 **/etc/rc.conf.local** 中的这些条目只适用于这个系统:

.. raw:: latex

   \diilbookstyleinputcell

.. code:: shell-session

   hostname="node1.example.org"
   ifconfig_fxp0="inet 10.1.1.1/8"

使用 ``rsync`` 或 ``puppet`` 等应用程序将 **/etc/rc.conf** 分发到每个系统,而保留各自的 **/etc/rc.conf.local**\ 。

升级系统不会覆盖 **/etc/rc.conf**\ ,所以系统配置信息不会丢失。

   **提示**

   **/etc/rc.conf** 和 **/etc/rc.conf.local** 都是由 `sh(1) <https://www.freebsd.org/cgi/man.cgi?query=sh&sektion=1&format=html>`__ 解析的,这使得系统操作者可以创建复杂的配置方案。参考 `rc.conf(5) <https://www.freebsd.org/cgi/man.cgi?query=rc.conf&sektion=5&format=html>`__ 的命令手册以了解更多有关信息。