For the complete documentation index, see llms.txt. This page is also available as Markdown.

rdist

什么是 rdist?

引用手册的话说,“rdist is a program to maintain identical copies of files over multiple hosts(rdist 是一款在多个主机上维护相同文件副本的程序)”rdist 是一款可用于多种用途的通用工具,比如通过网络实现文件的同步——类似于 rsync 和 unison;亦可作为分布式配置管理工具:如 cfengine、ansible、puppet、salt 等其他配置管理工具。

为什么要使用 rdist?

要理解为什么要使用 rdist,了解一点历史能更好地理解它因何产生。

Ralph Campbell 在加州大学伯克利分校(1983-1984 年间)编写了 rdist。rdist 首次出现在 4.3BSD(1986 年),是最早解决分布式软件管理问题的软件之一。从 20 世纪 80 年代末到 90 年代,它几乎随所有商业 UNIX 一同分发。当时它成为了远程平台管理的标准。

rdist 是同类软件中最早出现的(也早于 rsync)。rsync 是一款备份工具,用于备份和克隆目录树,而 rdist 通常用作网络文件的分发工具。它们都针对各自设计目的定制。

有这么多可选,为什么还要用 rdist 呢?

  • rdist 比后续出现的配置分发应用程序(如 ansible 等)更轻量。

  • rdist 容易集成到 shell 脚本和 Makefile 中。

  • rsync 无法像 rdist 一样并行分发到多个主机。rsync 也不能使用配置文件来同步文件。但这些 rdist 都可以做到。rsync 和 rdist 被设计用于不同的目的,rsync 用于备份和文件克隆,而 rdist 更适合用作配置管理工具。

另一方面,为什么会有人想用别的工具呢?与诸如 cfengine 和 ansible 之类的工具相比,rdist 更轻量化——其配置远程节点的能力仅限于分发文件和执行简单的分发后任务。而较重的工具可以用来执行分发前的任务:这个问题通过简单的 shell 脚本或 Makefile 就能解决。以我自己为例,我使用了一款名为 ipfmeta 的配置工具来管理我的 ipfilter 防火墙规则,该工具使用 Makefile 从规则文件和对象文件中生成防火墙配置文件。而 Makefile 使用 rdist 把生成的文件分发到 rdist 的 Distfile 中定义的远程防火墙中。Distfile 之于 rdist,类似于 Makefile 之于 make。与 rsync 不同,rdist 根据其 Distfile 中的规则来分发文件。

rdist 是如何工作的?

如同 make(1) 通过解析其 Makefile 来构建程序一样,rdist 解析其 Distfile——描述要分发的文件和目录以及要在分发后执行哪些任务。最初,rdist 使用不安全的 rcmd(3) 接口进行网络通信。rcmd() 会连接到远程 rshd(8)。当连接建立时,它会生成 rdistd(8) 远程文件分发服务器,在远程服务器上执行分发功能。这类似于 ssh 的 sftp-server:sftp-server 为 sftp 提供了远程功能。

伯克利的“r”命令(如 rsh)是不安全的。如今的 rdist 传输可基于 ssh 实现,而不用 rsh。通过 ssh 可以使用 ssh 密钥或 GSSAPI(kerberos)进行身份验证。与 ansible 不同,在 ansible 中的连接是使用你自己的账户进行的,并通过“become”进行提权;而 rdist 必须直接登录到目标服务器的 root。为了便于实现这一点,可将 sshd_config 中的 PermitRootLogin 设置为 prohibit-password,从而强制使用 ssh 密钥或 Kerberos 凭据。

rdist 本身不进行身份验证。它依赖于传输机制进行身份验证。与 ansible 一样,它也依赖于 ssh 传输机制进行身份验证,并依赖于 su(1)sudo(1)ksu(1) 进行提权。

rdist 可用于管理服务账户中的应用程序文件,如 mysql、oracle 或其他应用程序账户。用所需的账户名替换 root 即可。

rdistd(8) 必须位于目标服务器上用户的搜索路径 ($PATH)。

rdist 协商协议版本:sysutils/rdist6(软件包、Port)使用 RDIST 第六版本协议,而 sysutils/rdist7(alpha 版本)使用 RDIST 第七版本协议。

安装 rdist

安装 rdist,只需:

若使用 Ports,以 rdist7 为例,

使用 rdist

如上所述,rdist 使用配置文件,类似主机 make 使用其配置文件。必须编写自己的 Distfile。

Distfile 中包含三种语句类型。

Distfile

和 make 一样,rdist 会寻找名为 Distfile 或 distfile 的文件。就像可以覆盖 make 所使用的 Makefile 的名称一样,也可以覆盖 rdist Distfile 的名字。

Distfiles 包含一系列条目,指定要分发(复制)的文件,要将这些文件复制到哪些节点,以及在分发文件后要执行的后续操作。

变量

可以使用以下格式将一个或多个项目分配给变量。

例如,

以上将字符串 matisse 和 root@arpa 赋值给变量 HOSTS。

以下示例将三个目录名分配给了变量 FILES。

将文件分发到其他主机

第二种语句类型告诉 rdist 将文件分发到其他主机。其格式为:

<source list> 是文件名或变量名。<destination list> 是文件将被复制到的主机列表。而 <command list> 是要应用于复制操作的 rdist 指令列表。

可选的标签用于在命令行引用时识别语句以进行部分更新。

例如,我的防火墙 Distfile:

这将要求 rdistipf.conf 安装到 HOSTS 变量中列出的节点。install 命令告诉 rdist 文件的安装位置是 /etc/ipf.conf。

special 命令要求 rdist 在复制操作之后运行 chownchmod

标签 install-ipf 可以在 rdist 命令行中引用,将操作限制在此标签对应的操作,即 rdist install-ipf

命令列表包含的关键字有 installexceptspecialcmdspecial

关键字
说明

install

指定目标文件的安装位置。

notify

列出复制操作完成后要通知的电子邮件地址。

except

无需复制的文件,即例外模式。

except_pat

except 相同,但使用正则表达式模式。

special

每个文件复制后要执行的 shell 命令。

cmdspecial

所有文件复制后要执行的 shell 命令。

下面是个简单的例子。它将我这篇文章的工作副本复制到 FreeBSD 工作目录树中的某个目录。

这里将文件 /t/tmp/rdist.odt 复制到我的笔记本电脑上的 /home/cy/freebsd/rdist/rdist.odt。当然,简单的 cp(1) 命令就可以完成,但这个简单的例子初步展示了如何复制单个文件。还请注意,目标是同名文件。如目标是个目录,如 /home/cy/freebsd/rdist,它将删除目标目录中的所有文件和子目录,并用单个 rdist.odt 文件进行替换。指定目标文件或目录时要小心。类似于:

意料之外的结果可能造成糟糕的一天。

rdist(1) 手册页提供了一个更好的例子:

在上述示例中,列在变量 FILES 中的文件将从本地主机复制到变量 HOSTS 中列出的机器上。除了变量 EXLIB 中列出的文件、/usr/games/lib 和一个模式之外。每个文件复制后,将运行带选项 -bzsendmail

special 一般用于运行 shell 命令。但在上述例子中,special 执行了 /usr/lib/sendmail(就如同 shell 一样),将引号内的参数传给 sendmail

/usr/local 中的三个文件将被复制到目标系统上的 /usr/local/lib,复制完成后会发送电子邮件通知 ralph

作业完成时会触发时间戳文件,发送邮件给 root@cory。时间戳文件用于避免不必要的复制。例如,如果列出的文件比时间戳文件更新,就会复制该文件(而 ansible 使用校验和)。

注意事项

如上所述,一不小心,就会发生意外。如同 rsyncrdist 也不会验证源文件与目标文件是否为同一类型的对象(文件还是目录)。很容易用一个目录替换目标文件或者用一个文件替换目标目录。就像 rsync 一样,它可能会破坏系统。请小心,并在沙盒或 jail 中进行测试。

总结

rdist 是一款优秀的工具,当与脚本、makefile、其他工具结合使用时,尤其是在单个工具不能完成全部任务的情况下,可与其他工具联合使用。正如我管理 ipfilter 防火墙、ipfmeta、make Makefile、rdist Distfile 和 git 管理 rdist 的方式一样,rdist 可以很好地集成以创建轻量级应用程序。在与 ansible 或 cfengine 这类不能与脚本和 makefile 集成的重量级工具集成时,rdist 填补了这一独特的空白。rdist 遵循最初的 UNIX 哲学——即单一工具用于单一目的,可以与其他工具集成以创建新工具和应用程序。

参考文献


Cy Schubert 是 FreeBSD src 和 Ports 的提交者。他的职业生涯始于五十多年前,编写和维护着用 Fortran 写就的电气工程应用程序。他的经验包括 IBM MVS(大型机)系统编程,编写 MVS 内核和作业输入子系统 2(JES/2)的扩展。在三十五年前,他的职业生涯转向 UNIX 之路,开始涉足 SunOS、Solaris、Tru64、NCR AT&T、DG/UX、HP-UX、SGI、Linux 和 FreeBSD 系统管理。

Cy 的 FreeBSD 之旅亦始于三十五年前。在尝试了某个 Linux 内核 0.95 的 Linux 发行版后,发现它不支持 UNIX 域套接字(UDS);他又试了试某个实验性的 Linux 内核。在恢复被实验性内核破坏的 EXTFS 文件系统的那个悲惨月份之后,Cy 在 FreeBSD 和 NetBSD 的 USENET 新闻组上提出了一个问题。唯一回复 Cy 问题的人是 FreeBSD 项目的 Jordan Hubbard。由于 Jordan 是第一个也是唯一回复的人,Cy 决定先试试 FreeBSD。自那时起,他就一直在使用 FreeBSD(从 2.0.5 开始)。他在 2001 年成为了 Ports 提交者,于十一年前成为了源代码提交者。目前,他受雇于一家大型托管服务提供商的加拿大子公司。

最后更新于