天天看點

同時在 linux 多台伺服器 執行相同的指令

1. 使用工具 multixterm

2. 腳本

#test.sh

#!/bin/bash

dir=/home/test

while read line

do

host=`echo $line| awk '{print $1}'`

passwd=`echo $line | awk '{print $2}'`

$dir/expect_ssh.sh $host $passwd &

done < $dir/host.txt

#expect_ssh.sh

#!/usr/bin/env expect

set HOST [lindex $argv 0]

set PASSWD [lindex $argv 1]

spawn ssh root@$HOST

expect  "(yes/no)?" { send "yes\n" }

expect "*password:" { send "$PASSWD\n" }

expect "*#" { send "useradd -u 0 -g 0 username\n" } #執行相關操作,比如adduser

expect eof

#host.txt格式,可從資料庫中導出

IP           passwd

更多請參考 高效管理之大量并行運作指令

雲在根本上是由硬體和軟體組成的,這些元件需要經常細心地維護。出現故障的硬體需要修理或更換;軟體需要應用更新檔、更新和更新;必須根據需求和潛在的安全威脅提前配置系統。應用程式開發人員可能覺得計算雲很友善、很靈活,但是雲管理者要應對艱巨的任務。

不隻是雲的管理有這些問題。LAN(小型伺服器群)和計算叢集也有同樣的系統管理難題。在管理大量計算機時,Secure Shell (ssh)、scp 和 sftp 等常用工具用起來非常麻煩。本期 對話 UNIX 讨論從指令行有效地管理大量計算機的技術,先從少量系統開始,然後擴大規模。

強力方式

在一組計算機上運作指令的簡單方法是,把共用的 ssh 指令包裝在腳本中。假設您已經把公共密鑰分發到希望通路的每個遠端系統上(避免每次都需要輸入密碼),腳本 mssh.sh 在指定的每台計算機上運作一個指令,最後輸出收集的結果(見 清單 1)。

清單 1. mssh.sh

# 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

     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/software/downloads/libdshconfig-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/software/downloads/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:

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 相似,但是還可以管理系統映像。

繼續閱讀