事半功倍:使用脚本和实用程序跨所有 IBM AIX 服务器快速运行命令

系统管理员需要花更多的精力管理更多的服务器,这减少了他们投入每台服务器上的时间量。能够节省时间的实用程序对确保高效地管理这些服务器至关重要。简单的、按顺序运行的一行 SSH(Secure Shell,安全 Shell)循环代码和使用实用程序(比如 dsh 和并行 SSH)并行运行的命令显著提高了效率,尤其是在大型企业环境中。

简介

在大多数公司中,系统管理员都被要求使用更少的资源做更多的事。由于采用了虚拟化技术(比如 IBM PowerVM®),系统管理员必须管理的 IBM® AIX® 实例数量已显著增长。PowerVM 支持在单个硬件上运行数十或者甚至数百个 IBM AIX 逻辑分区 (LPAR)。多年前,系统管理员可能仅负责管理二十几个 AIX 实例,而在如今的环境中,系统管理员需要管理数百个 AIX LPAR 的情形很普遍。

如果您处在一个具有许多 LPAR 的大型 AIX 环境中,在需要更改或需要从每个服务器收集信息时,登录到每个服务器是不切实际的。在这些大型环境中,最佳的选择是谨慎地使用支持跨许多服务器快速运行命令或脚本的技术。本文将介绍跨大量服务器运行命令和脚本的多种选择。


SSH 密钥概述

本文中讨论的所有选择都需要在一个中央管理服务器与其余服务器之间设置 SSH 密钥。

第一步是挑选一个要使用的中央管理服务器。您挑选的服务器应该能够尽可能安全地访问您环境中的其他所有服务器。一个选择是为此用途创建一个新 LPAR,并尽可能多地锁定它。其他潜在的选择包括 Network Installation Manager (NIM) 服务器或系统监视服务器。

下一步是挑选一个要使用的用户帐户。您希望自动完成的许多任务可能需要根用户特权。但是,由于前缀的安全问题,不推荐直接使用根帐户。一个不错的替代方案是,创建一个正常的用户帐户,并使用实用程序(比如 sudo)为它授予根用户访问权。

在确定要将哪个服务器用作中央管理服务器并确定了一个用户帐户后,下一步是生成一个 SSH 密钥。已有许多介绍 SSH 密钥的教程,本文不再详细探讨该主题。基本上讲,您需要使用 ssh-keygen 命令在中央管理服务器上创建一个私钥和公钥。私钥仅在中央管理服务器上使用,而公钥可复制到其他所有服务器。

需要在每个服务器上建立一个新用户帐户,在用户的主目录中创建一个 “.ssh/authorized_keys” 文件并将公钥放入其中。如果计划以根用户级访问权来运行命令,还应设置 sudo 或类似实用程序,向用户授予其他访问权。如果使用 sudo,那么可以使用 “NOPASSWD” 选项,这样 sudo 就不会再提示用户输入密码。

要验证 SSH 密钥是否有效,可以尝试使用 ssh 在一个服务器上运行一个远程命令,比如 hostname。例如,如果服务器名称为 “server1”,那么您应该能够键入 ssh server1 hostname,响应应该为 server1。在使用 sudo 时,您应该能够运行 ssh server1 sudo su -c whoami 命令来验证此情况,最后应返回root


使用一个简单的 for 循环在多个服务器上运行单个命令

远程运行一个命令的一种方法是,使用一个简单的一行循环命令。要在其上运行该命令的服务器名称将从一个文件中读取。该文件的每一行有一个服务器名称。清单 1 显示了在多个服务器上运行 for 循环命令行的示例。

清单 1. 一个 ssh for 循环的示例
for server in `cat serverlist`; do printf "%-20s" $server; 
ssh -q -o "BatchMode yes" $server oslevel -s 2>&1; echo; done | grep -v ^$

我们详细分析一下这个示例:

  • for server in `cat serverlist`; do – 创建一个循环,让 serverlist 文件中的每个服务器将由该循环处理,而且服务器名称将被设置为 $server 变量。
  • printf "%-20s" $server; – 显示服务器的名称,通过填入空格来保持左对齐。这将导致服务器名称被整齐地输出。
  • ssh -q -o "BatchMode yes" $server oslevel -s 2>&1; – 使用两个选项来调用 ssh 命令。-q 选项阻止显示登录窗口。-o "BatchMode yes" 选项导致 SSH 在一个批处理模式下运行,而不提示用户输入任何信息。$server 将通过 for 循环更改为当前服务器的名称。在本示例中,oslevel -s 是我们需要在远程服务器上运行的命令。2>&1 选项用于将标准错误重定向到标准输出。没有此选项,输出可能是乱序的,因为没有缓冲区来暂存标准错误。
  • echo; – 确保无论该命令是否生成输出,光标都会移动到下一行,以便让循环中的下一个服务器名称排列在正确的位置上。为此,在每行结尾处都会使用一个回车,如果在执行命令之后没有返回输出,则设置了正确的格式。如果执行命令之后生成了输出,则会产生一个额外的空白行,但在下一步中将会删除这些行。
  • done | grep -v ^$ – 结束 for 循环,然后过滤并删除输出中的所有空白行。

图 1 显示了这个命令行和输出的一个示例。文件 serverlist 有一个服务器名称列表(每行一个),将在每个服务器上运行的命令为 oslevel -s

图 1. 一个 for 循环命令行和它的输出示例
该命令行及其输出的示例

图 2 显示了一个使用 sudofor 循环命令行和它的输出的示例。

图 2. 一个使用 sudo 来获取根用户访问权的 for 循环命令和它的输出的示例
一个使用 sudo 来获取根用户访问权的 for 循环命令和它的输出的示例

在图 2 中,在多个服务器上删除了一个用户帐户。运行 rmuser 所需的根用户级访问权由 sudo 授予。aixtest1aixtest3 上没有输出,这意味着该用户已被删除。在 aixtest2aixtest4aixtest5 上,rmuser 报告了一个错误,因为该用户不存在。

这个 for 循环命令的缺点是,每个命令一次仅在一个服务器上运行(顺序运行)。它一般只需 1/4 秒的时间就可以建立一个 SSH 连接并运行一个快速命令。如果存在网络延迟或者运行的命令花费了较长的时间,那么每个服务器可能会花费几秒钟或更长的时间。如果处理数百或数千个服务器,for 循环方法可能会花很长的时间。但是,当规模较小时,它非常简单高效。


使用一个简单的 for 循环在多个服务器上运行一段脚本

许多时候,手头的任务需要的不仅仅是跨所有服务器运行单个命令。在这些情况下,您可能需要在远程服务器上运行一段脚本。

为此,一种方式是将该脚本复制到每个服务器 [使用 Secure Copy Protocol (SCP) 或另一种文件协议],使用 SSH 远程运行该脚本,然后使用另一个 SSH 连接有选择地删除该脚本。但是,这种方式效率非常低,因为它需要与每个服务器建立多个连接,需要将脚本文件复制到每个服务器。

一种更好的方法是,在远程服务器上远程运行一个 shell 解释器或一个脚本解释器(比如 Perl),从本地服务器重定向您希望运行的脚本。使用这种方法,可在远程服务器上运行该脚本,无需将脚本文件复制到远程服务器。

清单 2 显示了中央管理服务器上存在的 info.sh 脚本的内容。这是一段简单的脚本,用于检测服务器是否为 AIX。如果服务器为 AIX,则会显示操作系统级别、CPU 模式、授权的 CPU 容量和内存量。

清单 2. 中央管理服务器上存在的 info.sh 脚本
#!/usr/bin/ksh

if [ "`uname`" = "AIX" ]; then
printf "This server is running AIX level           : "
oslevel -s
echo "CPU and Memory info: "
lparstat -i | egrep "^Mode|^Entitled Capacity  |^Online Memory"
echo "------------------------------"
else
echo "This is not an AIX server"
fi

清单 3 显示了一个与我们介绍的第一个循环类似的 for 循环。但是,在这个 for 循环中,我们运行的远程命令是 Korn shell (ksh) 解释器,我们将输入从 info.sh 文件重定向到 ksh。这会导致 info.sh 脚本在每个远程服务器上运行,而无需实际地将脚本复制到这些服务器。

清单 3. 在 servelist 文件中列出的每个服务器上运行本地 “info.sh” 脚本的 for 循环命令的示例
for server in `cat serverlist`; do printf "%-20s\n" $server; 
ssh -q -o "BatchMode yes" $server 'ksh 2>&1' < ./info.sh ; echo; done | grep -v ^$

清单 3 显示了一个在 servelist 文件中列出的每个服务器上运行本地 “info.sh” 脚本的 for 循环命令的示例,无需将脚本复制到每个服务器。

图 3 表明当运行此命令时,info.sh 脚本在 serverlist 文件中指定的每个服务器上运行。

图 3. 使用一个简单的 for 循环,使用输入重定向在远程服务器上运行脚本
使用一个简单的 for 循环,使用输入重定向在远程服务器上运行脚本

这是一种在大量服务器上运行脚本的高效方式,无需实际地将脚本复制到每个服务器。但是,脚本顺序地运行,所以如果脚本需要花较长时间才能完成,或者脚本将在大量服务器上运行,那么这可能是不切实际的。


对比脚本的顺序和并行运行

前面介绍的 for 循环在远程服务器上顺序地运行命令,也就是一个接一个地运行。也有并行运行命令的选项,表明中央管理服务器同时在多个服务器上启动命令。例如,假设您需要在 35 个服务器上运行一个命令,每个服务器需要花 1 秒来建立 SSH 连接和运行该命令。如果顺序地运行,此任务将花 35 秒完成。如果同时并行地运行 16 个服务器,它将花大约 3 秒(35 个服务器/同时运行 16 个 = 大约 3 秒)。在大量服务器上运行命令时,获得了显著的速度提升。图 4 显示了对比命令的顺序和并行运行的图表。

图 4. 脚本的顺序执行与并行执行之间的区别
脚本的顺序执行与并行执行之间的区别

使用 dsh 命令在多个服务器上运行一个命令

AIX 包含 dsh 命令,它被设计为在多个服务器上并行地运行一个命令。在默认情况下,dsh 可并行运行最多 64 个命令(这可使用 -f 标志自定义)。

要使用 dsh,首先需要确保它已安装在中央管理服务器上。这可以通过运行 which dsh; 来检查。如果向 dsh 返回一条路径,则表示它已安装在服务器上。如果没有返回任何路径,则需要安装适用于 AIX 6.1 的 csm.dsh 文件集或适用于 AIX 7.1 的 dsm.dshdsm.core 文件集。适用于 AIX 6.1 或 AIX 7.1 的适当文件集应该可以在 AIX 产品安装媒介上找到。

下一步将设置一些环境变量来告诉 dsh 如何操作。

清单 4. 为 dsh 设置的环境变量
export DSH_NODE_LIST="/home/user/serverlist"
export DSH_NODE_RSH=/usr/bin/ssh
export DSH_NODE_OPTS="-q -o BatchMode=yes"

清单 4 显示了在使用 dsh 之前必须设置的变量示例。

DSH_NODE_LIST 变量已被设置为一个文件名,这个文件指定了您需要在其上运行这些命令的服务器,每行一个服务器。

DSH_NODE_RSH 变量设置为 /usr/bin/ssh,以告诉 dsh 使用 SSH 作为连接协议。

DSH_NODE_OPTS 变量被设置为 -q -o BatchMode=yes,以告诉 SSH 客户端不显示登录窗口,并且不提示用户输入任何信息。

设置这些变量后,可运行 dsh,然后运行应在每个服务器上运行的命令行,在多个服务器上运行一个命令。图 5 显示了使用 dsh 在多个服务器上运行的 oslevel 命令。

图 5. 使用 “dsh” 在多个服务器上运行的 “oslevel” 命令
使用 dsh 在多个服务器上运行的 oslevel 命令

dsh 的另一项有用功能是 dshbak 命令。如果返回了大量输出,那么该命令可以将 dsh 的输出格式化为一种更容易使用的格式。要使用 dshbak,只需运行正常的 dsh 命令,将输出传送到 dshbak,如图 6 所示。

图 6. 使用 “dshbak” 格式化 “dsh” 的输出
使用 “dshbak” 格式化 “dsh” 的输出

使用并行 SSH 在多个服务器上运行命令和脚本

并行 SSH 是一个实用程序,它被设计用来在多个服务器上并行地运行 SSH 命令,其工作方式类似于 AIX dsh 实用程序。但是,并行 SSH 拥有多项优势,包括:能跨平台运行(同一个实用程序可在 Linux® 和其他 UNIX® 变体上运行),是开放的,而且拥有使用重定向来运行脚本的能力。

并行 SSH 包含在大多数 Linux 分发库中,可轻松地安装。

要在 AIX 上使用并行 SSH,需要先安装 Python 脚本语言的 2.4 版或其更高版本。我发现并行 SSH setup.py 安装程序可能很难在 AIX 上运行,而且也没有必要这样做。相反,您可以轻松地手动将并行 SSH 二进制文件复制到您希望运行它们的任何位置。

要使用并行 SSH 在多个服务器上运行某个命令,可以使用一个与清单 5 类似的命令。

清单 5. 使用 pssh 在多个服务器上运行某个命令的示例命令

# pssh -h serverlist -i oslevel -s

-h serverlist 命令在 serverlist 文件中指定服务器列表(每行一个服务器名称)。-i 选项指定屏幕上的输出必须是内联的。oslevel -s 是应在每个服务器上运行的命令名称。

图 7 显示了使用 pssh 在多个服务器上运行 oslevel 命令的示例输出。

图 7. 使用 “pssh” 在多个服务器上运行 “oslevel” 命令
使用 “pssh” 在多个服务器上运行 “oslevel” 命令

使用 pssh 也可以在多个服务器上快速而又轻松地运行脚本。此任务无需使用 input direction 将脚本复制到每个服务器。基本而言,这与本文的 使用一个简单的 for 循环在多个服务器上运行脚本 一节中介绍的方法相同。但在这里,它可以并行完成,因此速度要快得多。

要使用 pssh 运行 info.sh 脚本(如清单 2 所示),可使用清单 6 中所示的命令行。

清单 6. 使用 “pssh” 在多个服务器上运行一段本地脚本

# pssh -h serverlist -i -I < info.sh

-I 开关告诉 pssh 从标准输入中读取要运行的命令。< info.sh 选项将 info.sh 脚本重定向到 pssh 的标准输入,这实际上会在每个服务器上运行此脚本,无需实际地将脚本复制到每个服务器。

图 8 显示了使用 pssh 在多个服务器上运行 info.sh 脚本的输出。

图 8. 使用 “pssh” 在多个服务器上运行 info.sh 脚本
使用 pssh 在多个服务器上运行 info.sh 脚本

补充说明

AIX dsh 套件还包含一个名为 dcp 的命令,它允许在多个服务器之间并行地复制文件。这可能使得将文件推送到许多 LPAR 成为一个非常快捷的、轻松的过程。

并行 SSH 也包含类似的复制命令,它们可以并行运行。pscp 命令用于将文件复制到服务器,而 pslurp 用于从服务器复制文件。

图 9 显示了用于将 info.sh 文件复制到多个服务器上的 /tmp 目录的 pscp 命令。

图 9. 使用 “pscp” 将 info.sh 复制到多个服务器上的 /tmp 目录
使用 “pscp” 将 info.sh 复制到多个服务器上的 /tmp 目录

结束语

本文已经证明,可通过多种方法在多个服务器上运行命令或脚本。系统管理员既可以使用在每个服务器上按顺序运行命令或脚本的简单的一行循环,也可使用并行运行命令的实用程序(比如 dsh 和并行 SSH)。使用这些工具和方法,系统管理员可以提高效率,在更短的时间内完成更多的工作。

参考资料

学习

  • -->dsh 命令 操作说明
  • -->dcp命令 操作说明
  • -->并行 SSH 主页
  • AIX and UNIX 专区:developerWorks 的“AIX and UNIX 专区”提供了大量与 AIX 系统管理的所有方面相关的信息,您可以利用它们来扩展自己的 UNIX 技能。
  • AIX and UNIX 新手入门:访问“AIX and UNIX 新手入门”页面可了解更多关于 AIX 和 UNIX 的内容。
  • AIX and UNIX 专题汇总:AIX and UNIX 专区已经为您推出了很多的技术专题,为您总结了很多热门的知识点。我们在后面还会继续推出很多相关的热门专题给您,为了方便您的访问,我们在这里为您把本专区的所有专题进行汇总,让您更方便的找到您需要的内容。
  • AIX and UNIX 下载中心:在这里你可以下载到可以运行在 AIX 或者是 UNIX 系统上的 IBM 服务器软件以及工具,让您可以提前免费试用他们的强大功能。
  • IBM Systems Magazine for AIX 中文版:本杂志的内容更加关注于趋势和企业级架构应用方面的内容,同时对于新兴的技术、产品、应用方式等也有很深入的探讨。IBM Systems Magazine 的内容都是由十分资深的业内人士撰写的,包括 IBM 的合作伙伴、IBM 的主机工程师以及高级管理人员。所以,从这些内容中,您可以了解到更高层次的应用理念,让您在选择和应用 IBM 系统时有一个更好的认识。

讨论

  • 加入 developerWorks 中文社区。查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX
ArticleID=947892
ArticleTitle=事半功倍:使用脚本和实用程序跨所有 IBM AIX 服务器快速运行命令
publish-date=10102013