黑客技巧和 / - 高效管理多台服务器

作者:Kyle Rankin

多年来,我不得不管理各种不同的服务器。在一家公司,我从只有几台服务器开始,扩展到大约十台,而在另一家公司,我管理了数百台服务器。在这两种情况下,我都发现当您一次登录一台机器时,您根本无法高效地完成所有需要做的事情。多年来,我发现了一些工具和技术,它们确实使事情变得更容易。现在,即使这些技术也只能扩展到一定程度。如果您有一个非常大的环境,您可能最好使用一些集中式管理工具,如 Puppet、cfengine 或您可以从供应商处购买的其他工具。即便如此,对于那些在工作场所(或在家中)拥有中小型环境的人来说,这里有一些技巧可以帮助您更好地管理这些机器。

SSH 循环

当您的环境中有多台服务器时,您通常需要在一个以上的机器上运行相同的命令。当我第一次遇到这个问题时,我想出了一个非常简单的 shell 脚本

$ HOSTS="machine1 machine2 machine3 machine4"; 
 ↪for i in $HOSTS; do ssh $i uname -a; done;

这个单行命令遍历我在 HOSTS 环境变量中列出的每台机器,并运行 uname -a。当然,您可以将 uname -a 替换为您想要在主机上运行的任何命令行命令。例如,我需要做的一件事是保持我所有 Debian 服务器的更新。我在每个 Debian 主机上创建了一个名为 /usr/local/bin/apt-automate 的小型 shell 脚本

#!/bin/sh

apt-get update && apt-get -u upgrade

然后,我编辑了我的 /etc/sudoers 文件,以便我的普通用户可以以 root 身份执行该脚本,而无需密码

username ALL=(root) NOPASSWD: /usr/local/bin/apt-automate

(将 username 替换为您在该主机上的本地用户名。)一旦我安装了脚本并配置了 sudo,我就设置了 SSH 密钥,以便我的用户可以轻松登录到每台机器。然后,我可以用一个简单的单行命令更新四台主机

HOSTS="machine1 machine2 machine3 machine4"; 
 ↪for i in $HOSTS; do ssh $i sudo apt-automate; done;

最终,我发现我执行这个单行命令的次数太多了,以至于它值得拥有自己的脚本,我称之为 update-all

#!/bin/sh

hosts="machine1 machine2 machine3 machine4"

# Run the command on each remote host
for i in $hosts;
do
  echo $i;
  ssh $i sudo apt-automate;
done;

# Also run the command on the local machine
sudo apt-automate

现在,这个系统在当时对我很有效,但它还有很大的改进空间。首先,我可以为不同的主机组设置一组环境变量。然后,我可以引用其中一个组,而不是每次运行单行命令时都定义 HOSTS。

ClusterSSH

当我只有几台主机要管理时,SSH 循环方法对我来说效果很好。但是,当我需要在不同的数据中心管理数百台机器时,这个计划就无法很好地扩展了。首先,我并不总是只需要在一组机器上运行一个命令。有时,我想对每台主机上的同一个文件进行相同的更改。虽然我可以玩 Perl,或者使用 awk 和 sed 脚本来内联编辑文件,但这很容易出错。幸运的是,我找到了一个非常宝贵的工具,用于管理中小型服务器环境,名为 ClusterSSH (clusterssh.sourceforge.net)。

ClusterSSH 为您要管理的每台机器打开一个终端。除了这些终端,ClusterSSH 还打开一个小型的 Tk 控制窗口。您在任何一个单独的终端中键入的任何内容都只在该服务器上执行,但是您在 Tk 窗口中键入或粘贴的任何内容都会输入到每个终端中。控制窗口还允许您切换输入是否进入特定终端,并允许您添加额外的主机。

许多发行版都打包了 ClusterSSH。如果您的发行版没有它,您也可以从项目页面下载并构建源代码。一旦安装了软件包,执行就很简单

$ cssh host1 host2 host3 host4

ClusterSSH 的一个不错的功能是它会自动平铺所有窗口,以便您在每个窗口上获得最大量的可见屏幕空间(图 1)。当您同时操作大量服务器时,这尤其有用。如果您碰巧重新排列窗口或从 ClusterSSH 添加或删除主机,您可以按 Alt-R 或单击 Hosts→Refile Hosts 来重新排列所有窗口。

Hack and / - Manage Multiple Servers Efficiently

图 1. ClusterSSH 平铺的十个终端窗口。

现在您可能会说,“这一切看起来都不错,但您仍然必须每次都在命令行上指定所有服务器。如果我有一个 30 台服务器的集群要管理怎么办?” 好吧,ClusterSSH 通过其配置文件涵盖了这一点。在 ~/.csshrc 文件中,您不仅可以定义 ClusterSSH 的默认设置,例如终端设置,还可以定义服务器组。如果您想更改所有用户的设置,您可以在 /etc/clusters 文件中定义集群,并在 /etc/csshrc 中设置 ClusterSSH 参数。否则,~/.csshrc 作为存储用户所有设置的位置就足够了。这是一个示例 ~/.csshrc,其中突出显示了一些有用的选项

terminal_args = -fg green
terminal_font = 7x14
clusters = web dbtest dbprod dns
web = web1 web2 web3 web4 web5 web6 web7 web8 web9 web10
dbtest = testdba@db1.test.example.net testdba@db2.test.example.net
dbprod = proddba@db1.prod.example.net proddba@db2.prod.example.net
dns = root@ns1 root@ns2 root@10.1.1.1

此文件中的前两个选项配置终端设置。首先,我将 xterm 的前景色设置为绿色(因为黑色上的绿色是唯一的真正终端颜色),然后我设置了终端字体。第三行设置 clusters 选项,并为您将在下面定义的所有集群定义别名。请注意,如果您在此文件中定义了一个集群,但不记得将其添加到 cluster 选项中,您将无法访问它。在 clusters 选项下方,我定义了许多不同的集群。语法基本上是 clustername = serverlist,每个主机名用空格分隔。正如您在示例中看到的那样,您可以严格按主机名(在这种情况下,您的 DNS 搜索路径将尝试解析完全限定域名)、按主机的完全限定域名或按 IP 指定服务器。如果您想以不同的用户名登录,您也可以在逐个主机的基础上指定。

一旦您的配置文件到位,您就可以在命令行上连接任何或所有集群别名。因此,如果我想在所有 Web 服务器上运行命令,我会键入

$ cssh web

如果我想访问 dbtest 和 dbprod 服务器,我会键入

$ cssh dbtest dbprod

当您指定多个主机组时,一个缺点是,如果您没有设置 SSH 密钥,您可能需要为每个主机键入不同的密码。在这种情况下,您需要单独突出显示每个终端窗口,然后登录。之后,您可以返回到 Tk 控制窗口并在所有主机上执行命令。

总而言之,我发现 ClusterSSH 是管理中小型服务器组的宝贵工具。界面非常简单明了,并且能够将 20 行配置粘贴到 30 台主机的 vim 会话中,或者快速对所有 Web 服务器日志运行 tail 命令,这非常酷。我发现我最常使用它来将软件包部署到服务器组。我可以挑选一台服务器来确保软件包工作正常,然后关闭该服务器并将其应用于其余服务器。

Kyle Rankin 是旧金山湾区的高级系统管理员,也是多本书的作者,包括 O'Reilly Media 出版的 Knoppix HacksUbuntu Hacks。他目前是 North Bay Linux Users' Group 的总裁。

加载 Disqus 评论