云在根本上是由硬件和软件组成的,这些组件需要经常细心地维护。出现故障的硬件需要修理或更换;软件需要应用补丁、更新和升级;必须根据需求和潜在的安全威胁提前配置系统。应用程序开发人员可能觉得计算云很方便、很灵活,但是云管理员要应对艰巨的任务。
不只是云的管理有这些问题。LAN(小型服务器群)和计算集群也有同样的系统管理难题。在管理大量计算机时,Secure Shell (ssh)、scp 和 sftp 等常用工具用起来非常麻烦。本期 对话 UNIX 讨论从命令行有效地管理大量计算机的技术,先从少量系统开始,然后扩大规模。
强力方式
在一组计算机上运行命令的简单方法是,把共用的 ssh 命令包装在脚本中。假设您已经把公共密钥分发到希望访问的每个远程系统上(避免每次都需要输入密码),脚本 mssh.sh 在指定的每台计算机上运行一个命令,最后输出收集的结果(见 清单 1)。
清单 1. mssh.sh
#!/bin/bash
# Usage: mssh.sh "machine1 [machine2...]" "command"
OUTPUT_LOG=/tmp/output-$$.log
ERROR_LOG=/tmp/error-$$.log
MACHINES=$1; shift
COMMAND=$2; shift
for machine in $MACHINES
do
ssh $machine $COMMAND >>$OUTPUT_LOG.$machine 2>>$ERROR_LOG.$machine &
done
wait
cat $OUTPUT_LOG.*
cat $ERROR_LOG.* >&2
rm -f $OUTPUT_LOG.* $ERROR_LOG.*
例如,命令 mssh.sh "example.com [email protected]" "uptime -a"> 在两台主机(example.com 和 sample.com)上运行 uptime -a。计算机名列表放在引号中以组成一个参数,由于同样的原因,命令也放在引号中。每个计算机名必须符合 ssh 要求的模式 — 如果远程用户名与本地用户名相同,那么使用 hostname;如果远程用户名与本地用户名不同,那么使用 username@hostname。运行 mssh.sh "example.com [email protected]" "uptime -a"> 会产生这样的结果:
$ mssh.sh "example.com [email protected]" "uptime"
example.com
08:34:35 up 66 days, 17:29, 0 users, load average: 0.40, 0.19, 0.07
[email protected]
08:34:28 up 104 days, 10:18, 0 users, load average: 0.15, 0.10, 0.10
这个脚本很原始,但是可以通过扩展它包含其他特性,比如用可调的超时设置防止在主机停机时出现长时间延迟(ssh -o 选项),用指定的目录捕捉输出。实际上,有许多按这种方式构建的软件包,可以简化分布式系统管理。其中之一是 Distributed Shell (dsh)。
回页首
更好的工具
dsh 是专为在远程系统上运行 shell 命令设计的,可以简化对大量计算机的操作。可以获取这个 shell 的二进制代码和源代码。对于二进制代码,检查您的 Linux® 或 UNIX® 发行版是否有 libdshconfig 和 dsh 包。例如,Ubuntu 和 Debian 用户可以通过 apt-get 方便地安装 dsh:
$ sudo apt-get install libdshconfig1 libdshconfig1-dev dsh
如果找不到针对您的系统预构建的包,从源代码构建 dsh 也很容易。找到库和实用程序的最新版本,下载并解压两个压缩文件,用通常的 ./configure; make; sudo make install 命令构建和安装它们(见 清单 2)。
清单 2. 从源代码构建 dsh
$ # Build and install the library first
$ wget http://www.netfort.gr.jp/~dancer ... nfig-0.20.13.tar.gz
$ tar xzvf libdshconfig-0.20.13.tar.gz
$ cd libshconfig-0.20.13
$ ./configure
$ make
$ sudo make install
$ # Then build and install the utility
$ wget http://www.netfort.gr.jp/~dancer ... s/dsh-0.25.9.tar.gz
$ tar xzvf dsh-0.25.9.tar.gz
$ cd dsh-0.25.9
$ ./configure
$ make
$ sudo make install
这个 shell 是相当小的应用程序;dsh 和 dsh.conf 手册页提供掌握它所需的所有信息。例如,要想在一组主机上运行 uptime,只需输入:
$ dsh --show-machine-names -m example.com -m [email protected] -- uptime
example.com: 11:34:57 up 66 days, 20:29, 0 users, load average: 0.04, 0.06, 0.01
[email protected]: 11:35 up 2 days, 14:59, 8 users, load averages: 0.46 0.35 0.31
用 -m 指定主机,主机名的规则与 ssh 相同。命令行中的双连字符把 dsh 命令本身的选项与要运行的命令分隔开。按指定主机的次序显示输出。--show-machine-names 选项在远程命令发出的输出前面加上主机名。
如果经常操作同一组计算机,可以定义一个或多个集合并指定要操作的集合。可以创建一个全局集合和任意数量的组。$HOME/.dsh/machines.list 文件是全局集合。如果指定 dsh -a,就会在 machines.list 中列出的所有计算机上运行指定的命令。因此,如果 machines.list 包含:
example.com
[email protected]
那么命令:
dsh -a --show-machine-names -- uptime
会产生与前一个命令相同的输出:
$ dsh -a --show-machine-names -- uptime
example.com: 11:57:03 up 66 days, 20:51, 0 users, load average: 0.29, 0.18, 0.07
[email protected]: 11:57 up 2 days, 15:21, 8 users, load averages: 0.52 0.31 0.26
可以在 $HOME/.dsh/group/groupname 文件中创建更小或专门的计算机集合,其中的 groupname 是您指定的有意义的名称。例如,如果创建名为 $HOME/.dsh/group/servers 的文件,那么命令 dsh -g servers -- uptime 会在 servers 文件中列出的所有计算机上运行 uptime。
可以结合使用 -m 与 -a 和 -g,分别扩展全局列表和组。另外,可以使用 --file filename 把 filename 中列出的所有计算机添加到主机列表中。在默认情况下,dsh 并行地运行命令。但是,如果希望顺序地运行命令,那么指定 --wait-shell。
尽管很方便,但是 dsh 有一个重大的缺陷:它无法复制文件。如果希望把数据部署到多台计算机上,就必须编写一个新脚本,利用发行版的基础设施(比如 rsync),或者考虑使用更健壮的工具(比如 Parallel SSH (pssh))。
回页首
与 ssh 相似,但采用并行方式
与 dsh 一样,pssh 的目标也是简化大量计算机的管理。除了具备 dsh 的所有功能之外,pssh 还可以把文件从一组系统复制到中心服务器或反向复制,以及杀死一组系统上的进程。这个 shell 和它的底层库是用 Python 编写的,如果系统上已经安装了 Python 解释器和核心库,就很容易安装它(见 清单 3)。
清单 3. 安装 pssh
$ # For systems with apt-get (apt-get installs Python if necessary)
$ sudo apt-get install pssh
$ # For all others, install Python and then continue
$ wget http://peak.telecommunity.com/dist/ez_setup.py
$ sudo python ez_setup.py
$ wget http://parallel-ssh.googlecode.com/files/pssh-2.1.1.tar.gz
$ tar xzvf pssh-2.1.1.tar.gz
$ cd pssh-2.1.1
$ sudo python setup.py install
pssh 包安装 5 个实用程序:parallel-ssh、parallel-scp、parallel-slurp、parallel-nuke 和 parallel-rsync。每个实用程序都并行地操作多个主机。
parallel-ssh 在多个主机上并行地运行命令。
parallel-scp 把文件并行地复制到多个主机上。
parallel-rsync 通过 rsync 协议把文件高效地并行复制到多个主机上。
parallel-slurp 把文件并行地从多个远程主机复制到中心主机上。
parallel-nuke 并行地在多个远程主机上杀死进程。
与 dsh 不同,pssh 总是通过清单 文件指定主机,其中的每行采用 host[:port] [user] 形式。下面的示例用 parallel-ssh 在一组主机上运行 uptime:
$ parallel-ssh -h servers.txt uptime
[1] 16:15:14 [SUCCESS] example.com 22
16:15 up 2 days, 19:39, 9 users, load averages: 0.09 0.10 0.12
[2] 16:15:28 [SUCCESS] sample.com 22
16:15:28 up 67 days, 1:09, 0 users, load average: 0.09, 0.07, 0.01
servers.txt 文件有两行:
example.com
sample.com joe
在默认情况下,每个命令实例的输出出现在 stdout 中。输出划分为每个主机一段。但是,可以指定一个目录来捕捉每个实例的输出。例如,如果运行前面的命令并添加 --outdir /tmp/uptime,那么会把每个主机的命令输出捕捉到 /tmp/uptime 中单独的文件中,见 清单 4。
清单 4. 把输出捕捉到单独的文件中
$ parallel-ssh -h servers.txt uptime
[1] 16:15:14 [SUCCESS] example.com 22
[2] 16:15:28 [SUCCESS] sample.com 22
$ ls -1 /tmp/uptime
example.com
sample.com
$ cat /tmp/uptime/*
16:22 up 2 days, 19:46, 9 users, load averages: 0.47 0.28 0.19
16:22:32 up 67 days, 1:17, 0 users, load average: 0.06, 0.04, 0.00
parallel-ssh 实用程序可以生成最多 32 个进程,并行地连接各个节点。如果远程命令在 60 秒内没有完成,连接会终止。如果命令需要更多处理时间,可以使用 -t 设置更长的到期时间。(parallel-scp 和 parallel-rsync 没有默认的到期时间,但是可以用 -t 指定到期时间。)
可以使用 parallel-scp 并行地把一个或多个文件或目录复制到许多计算机。如果您精通传统的 scp,应该熟悉这个命令。
$ parallel-scp -h servers.txt /etc/hosts /tmp/hosts
[1] 16:49:38 [SUCCESS] example.com 22
[2] 16:49:55 [SUCCESS] sample.com 22
前面的命令把本地文件 /etc/hosts 复制到 servers.txt 中列出的每台计算机上的 /tmp/hosts。parallel-rsync 的工作方式相似,它通过运行 rsync 并行地在本地主机和清单中列出的远程主机之间管理文件。parallel-slurp 的作用与 parallel-scp 相反,但是有一点不同:它从每台远程计算机收集指定的文件,但是并不覆盖文件的本地版本。parallel-slurp 为每台远程计算机创建一个子目录并把指定的文件复制到此位置。
假设希望把 /etc/hosts 文件从每台远程计算机复制到本地计算机。为实现这个目标,执行 parallel-slurp -h servers.txt /etc/hosts,见 清单 5。
清单 5. 把 /etc/hosts 文件从远程计算机复制到本地计算机
$ parallel-slurp -h servers.txt -L /tmp/hosts /etc/hosts hosts_file
1] 17:03:32 [SUCCESS] example.com 22
[2] 17:03:50 [SUCCESS] dcauto.gotdns.com 22
$ ls -R /tmp/hosts
/tmp/hosts/example.com:
hosts_file
/tmp/hosts/sample.com:
hosts_file
parallel-slurp 把指定的远程文件复制到本地计算机,把文件的每个拷贝存储在按远程主机命名的子目录中。在这里,远程文件是 /etc/hosts;每个本地拷贝名为 hosts_file。-L 选项指定创建子目录的位置。在这里,目标是 /tmp/hosts,这会生成子目录 /tmp/hosts/example.com 和 /tmp/hosts/sample.com。
最后,parallel-nuke 相当于运行 ssh host killall。parallel-nuke 的参数是一个模式。在远程计算机上运行的名称符合这个模式的所有进程都被杀死。可以用此命令方便地在一组服务器上停止同一守护进程。
要想使用 pssh 工具,必须在要管理的每台远程服务器上配置公共密钥访问。如果 pssh 实用程序产生 [FAILURE],就用一般的 ssh 建立连接以检查配置。如果系统提示输入密码,那么在远程主机上安装公共密钥并再次尝试连接。(具体步骤见 ssh 和 ssh-keygen 手册页。)
回页首
操作大量计算机的其他工具
对于 5 台、10 台或更多计算机,这里介绍的工具很可能足够了,尤其是对于不经常执行的非重复性管理任务。但是,如果计算机数量很大,或者经常重复执行相同的任务,那么应该谨慎地考虑采用为自动维护大量计算机而设计的其他工具和子系统。另一方面,为大型网络设计的一些软件也可以应用于少量计算机。找到适当的工具以及手工干预与自动化之间的平衡点是一个难题,而且需要经常重新审查和调整。
下面是可以考虑采用的一些工具:
rsync:这个出色的工具用于从中心服务器分发文件以及保持分布式文件系统同步。前面的一期对话 UNIX 详细讨论了 rsync。
Puppet。Puppet 是一个越来越流行的 UNIX 和 Linux® 子系统,它可以自动地维护配置。根据它的网站所说,“[Puppet] 提供一个强大的框架,可以简化 [系统管理员] 需要执行的大多数技术任务。可以用 Puppet 的定制语言编写各种任务,可以像其他代码一样共享这些任务代码。” Puppet 可以描述组件之间的依赖关系、定义文件的正确状态、查询系统的状态等等。如果要多次执行某一任务,最好以 Puppet 任务的形式捕捉它。
Capistrano。Capistrano 是另一个流行的远程系统管理工具。它的主页上说:“简单地说,Capistrano 用于在一个或多个远程服务器上自动地执行任务。它在所有目标计算机上并行地执行命令,还提供在多台计算机上回退修改的机制。它非常适合任何人执行任何系统管理任务,包括专业的系统管理员和偶尔执行系统管理的人员。” 与 Puppet 相同,Capistrano 采用脚本编程。脚本基于 Ruby 编程语言和 Capistrano 的域相关语言。下面是一个示例:
task :search_libs, :hosts => "www.capify.org" do
run "ls -x1 /usr/lib | grep -i xml"
end
此任务名为 search_libs。它连接 www.capify.org 并运行命令 ls -x1 /usr/lib | grep -i xml。Capistrano 通过角色 支持计算机组,还提供许多其他特性。通过 cap 命令启动任务,比如 cap search_libs。Ruby 和 Rails 开发人员广泛采用 Capistrano 把代码部署到服务器,但是对于自动执行大多数分布式系统管理任务,它也是非常好的工具。一些教程解释了如何结合使用 Capistrano 与 Java™ 语言、Perl、Python 和其他编程语言,以及如何结合使用 Capistrano 与 Drupal and Expression Engine 等应用程序引擎。如果与源代码控制系统结合使用,Capistrano 的效果最好,但这不是必需的。可以通过 put 操作分发二进制代码。
Nagios。维护很重要,但是监视也很重要。停机和错误会在网络上造成严重破坏,尤其是在许多系统采用相同配置的情况下。Nagios 是一个开放源码监视程序,它可以监视服务器、服务、资源等。它的安装和部署很容易,可以通过任何 web 浏览器使用它。
还可以研究 Oak Ridge National Laboratory (ORNL) 的 Cluster Command and Control (C3) 和 pdsh 等计算集群工具。C3 操作 ORNL 的大规模计算集群,它提供大量命令行工具,可以减少操作和管理集群所需的时间和精力,提高系统管理员的生产力。pdsh shell 在许多方面与 pssh 相似,但是还可以管理系统映像。
回页首
用很少的时间管理大量计算机
使用 dsh 和 pssh 等工具能够节省时间并减少错误。可以在大量系统上运行相同的命令,几乎马上会看到组合的结果。通过清单把相似的计算机集中在一起可以降低遗漏的风险。Puppet 和 Capistrano 可以把经常重复执行的任务捕捉到脚本中。如果管理的计算机比较多,自动化就是关键。总之,如果采用适当的工具,计算云的管理也不难。