rdist
作者:CY SCHUBERT
什么是 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:ssh 为 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 协商协议版本:systuils/rdist6(软件包、Port)使用 RDIST 第六版本协议,而 sysutils/rdist7(alpha 版本)使用 RDIST 第七版本协议。
安装 rdist
安装 rdist,只需,
或
若使用 ports,以 rdist7 为例,
使用 rdist
如上所述,类似于主机 make 使用其配置文件,rdist 使用类似于其配置文件的配置文件。我们必须编写我们自己的 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:
这将要求 rdist
把 ipf.conf
安装到 HOSTS 变量中列出的节点中。命令行 install 告诉 rdist 文件,安装位置是 /etc/ipf.conf。
命令行 special 要求 rdist
在复制操作之后运行 chown
和 chmod
。
标签 install-ipf
可以在 rdist
命令行中被引用,限制此行为仅用于该操作,即 rdist install-ipf
。
命令列表涉及的关键字有 install
、except
、special
和 cmdspecial
。
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
和一个模式之外。每个文件复制后,将运行带 -bz
参数的 sendmail
。
special
一般用于运行 shell 命令。但在上述例子中,special
执行了 /usr/lib/sendmail
(就如同 shell 一样),将调用的参数传给 sendmail
。
/usr/local
中的三个文件将被复制到目标系统上的 /usr/local/lib
,复制完成后会发送电子邮件通知 ralph
。
作业完成时会触发时间戳文件,发送邮件给 root@cory
。时间戳文件用于避免不必要的复制。例如,如果有列出的文件比时间戳文件更新(而 ansible 使用校验和),才会复制该文件。
注意事项
如上所述,一不小心,就会发生意外。如同 rsync
,rdist
也不会验证源文件与目标文件是否为同一类型的对象(文件还是目录)。很容易就会用一个目录替换目标文件或者用一个文件替换目标目录。就像 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 年成为了 Port 提交者,于十一年前成为了源代码提交者。目前,他受雇于一家大型托管服务提供商的加拿大子公司。
最后更新于