前言
《Ubuntu系統(tǒng)批量自動安裝》一文中,配置好了PXE服務(wù)器,也通過它安裝了幾臺機器。每個機器都重新配置好了IP,已經(jīng)可以遠程訪問了?,F(xiàn)在新的問題來了,每個機器的主機名都相同,需要修改;每個機器的sources.list都有問題,需要替換。以后,肯定也有很多其他需要批量操作的問題,比如批量安裝ganglia,總不能上百臺機器一個個手動操作吧!
本文,就研究下linux批量操作的相關(guān)方法和工具,重點研究下pssh。
批量操作思路
首先定義兩個概念:管理機和客戶機,本文中的管理機是指管理其他服務(wù)器的服務(wù)器,客戶機是指普通服務(wù)器。
管理機IP為192.168.56.101,客戶機IP為192.168.56.102-104,用戶名都是test。
思路一
說到批量操作,最容易想到的,肯定是在管理機寫一個腳本,里面有個循環(huán)語句,挨個連接客戶機進行操作。
而循環(huán)語句里面,主要是ssh,然后執(zhí)行交互命令。參考 shell實現(xiàn)SSH自動登陸 、 關(guān)于SSH 遠程執(zhí)行命令你要知道的二三事 和 shell腳本實現(xiàn)同時多臺遠程主機執(zhí)行命令的代碼分享。
但是,這種方式很難并行處理,比較浪費時間。
思路二
另一個簡單的思路,是在管理機寫一個在客戶機執(zhí)行的腳本,然后推送給客戶機,再在客戶機里執(zhí)行腳本。主要參考SSH 遠程執(zhí)行任務(wù)。
這種方式同樣很難并行處理,比較浪費時間。如果非要并行處理,那么就只能犧牲反饋信息。
思路三
最后一種思路就是借助工具,比如mussh、pdsh、pssh等等。
pssh
pssh簡介
pssh是一個python編寫可以在多臺服務(wù)器上執(zhí)行命令的工具,同時支持拷貝文件,是同類工具中很出色的。類似pdsh,但是相對pdsh更為簡便,使用前必須在各個服務(wù)器上配置好密鑰認證訪問。參考pssh命令和pssh HOWTO。
安裝
1、ubuntu安裝pssh,sudo apt-get install pssh
2、ubuntu安裝完pssh后,輸入pssh,也許會提示:No command 'pssh' found, did you mean:...
解決辦法參考Why pssh command is not working?,一條命令解決:
echo "alias pssh=parallel-ssh" >> ~/.bashrc && . ~/.bashrc,其中&& . ~/.bashrc代表立即生效。
3、設(shè)置相關(guān)命令
安裝完pssh后,實際上還安裝了pscp、prsync、pnuke和pslurp。和pssh命令無效的問題相同,它們默認也只能使用全名,不能只用簡稱。需要執(zhí)行如下命令:
echo "alias pscp=parallel-scp" >> ~/.bashrc && . ~/.bashrc
echo "alias prsync=parallel-rsync" >> ~/.bashrc && . ~/.bashrc
echo "alias pnuke=parallel-nuke" >> ~/.bashrc && . ~/.bashrc
echo "alias pslurp=parallel-slurp" >> ~/.bashrc && . ~/.bashrc
其中,pscp把文件并行地復(fù)制到多個客戶機;prsync使用rsync協(xié)議從管理機同步到客戶機;pslurp將文件從客戶機復(fù)制到管理機;pnuke并行地在客戶機殺進程。
命令格式
命令格式:pssh [OPTIONS] command [...]
選項:
--version:查看版本
--help:查看幫助,即此信息
-h:主機文件列表,內(nèi)容格式"[user@]host[:port]"
-H:主機字符串,內(nèi)容格式"[user@]host[:port]"
-l:登錄使用的用戶名
-p:并發(fā)的線程數(shù)【可選】
-o:輸出的文件目錄【可選】
-e:錯誤輸入文件【可選】
-t:TIMEOUT 超時時間設(shè)置,0無限制【可選】
-O:SSH的選項
-v:詳細模式
-A:手動輸入密碼模式
-x:額外的命令行參數(shù)使用空白符號,引號,反斜線處理
-X:額外的命令行參數(shù),單個參數(shù)模式,同-x
-i:每個服務(wù)器內(nèi)部處理信息輸出
-P:打印出服務(wù)器返回信息
實踐篇
添加密鑰認證訪問
參考Linux之SSH密鑰認證和ssh使用密鑰進行認證,在管理機上制作密鑰對,將公鑰添加給客戶機,然后通過ssh免密登錄。
1、確認管理機和客戶機都安裝了ssh。
ps aux | grep ssh
2、在管理機上創(chuàng)建密鑰對
ssh-keygen
所有的提示按enter鍵即可,完成后在home目錄執(zhí)行ll .ssh,即可看到創(chuàng)建好的id_rsa和id_rsa.pub文件。
3、把公鑰拷貝到所有客戶機中
ssh-copy-id -i .ssh/id_rsa.pub -p 22 test@192.168.56.102
4、測試登錄
上一步拷貝完成后,會提示使用ssh -p '22' 'test@192.168.56.102'測試登錄。
在管理機中,使用ssh test@192.168.56.102測試登錄,我們發(fā)現(xiàn)已經(jīng)不需要輸入密碼了。
5、查看公鑰
登錄102客戶機,ll .ssh,我們發(fā)現(xiàn)有一個authorized_keys文件,文件的內(nèi)容和管理機的id_rsa.pub相同。
5、測試命令
ssh test@192.168.56.102 '/sbin/ifconfig'
返回了102客戶機的ifconfig執(zhí)行結(jié)果,測試成功。
6、設(shè)置sudo命令免密碼
ssh test@192.168.56.102 'sudo iptables --list'
報錯:sudo: no tty present and no askpass program specified
這個問題,需要在每個客戶機下進行sudo免密設(shè)置。
進入客戶機之后,sudo vim /etc/sudoers,添加:
test ALL = NOPASSWD: ALL
再次執(zhí)行ssh test@192.168.56.102 'sudo iptables --list',成功。
獲取每臺機器的uptime
1、在管理機上新建hosts.txt,內(nèi)容為:
test@192.168.56.102
test@192.168.56.103
test@192.168.56.104
2、執(zhí)行uptime
pssh -h hosts.txt -i uptime
3、保存執(zhí)行結(jié)果
pssh -h hosts.txt -i -o /tmp/pssh/ uptime
ll /tmp/pssh
cat /tmp/pssh
批量修改hostname
參考Linux批量修改多臺服務(wù)器的主機名(hostname),我們把客戶機的主機名改為vk102、vk103和vk104。
1、新建hosts文件,內(nèi)容為:
192.168.56.102 vk102
192.168.56.103 vk103
192.168.56.104 vk104
2、新建hostname.sh文件,內(nèi)容為:
#!/bin/bash
ip=`ifconfig eth0 | grep 'inet' | awk '{print $2}' | tr -d 'addr:'`
hostname=`cat /home/test/hosts | grep $ip | awk '{print $2}'`
echo $ip
echo $hostname
hostnamectl set-hostname --static $hostname
hostname $hostname
3、發(fā)送到hosts和hostname.sh到客戶機/home/test目錄下
pscp -h hosts.txt ./hosts /home/test
pscp -h hosts.txt ./hostname.sh /home/test
4、批量授予hostname.sh可執(zhí)行權(quán)限
pssh -h hosts.txt -i 'chmod +x /home/test/hostname.sh'
5、批量執(zhí)行hostname.sh
pssh -h hosts.txt -i 'sudo sh /home/test/hostname.sh'
報錯:Stderr: hostname: you must be root to change the host name
命令修改為:pssh -h hosts.txt -i 'sudo sh /home/test/hostname.sh'
執(zhí)行成功。
批量替換sources.list
1、新建sources.list,內(nèi)容為:
deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
2、客戶機備份原sources.list
pssh -h hosts.txt -i 'sudo mv /etc/apt/sources.list /etc/apt/sources.list.bak'
3、復(fù)制新的sources.list到客戶機
pscp -h hosts.txt sources.list /home/test/
pssh -h hosts.txt 'sudo mv /home/test/sources.list /etc/apt/'
4、更新安裝源
pssh -h hosts.txt -i 'sudo apt-get update'
批量安裝ganglia
參考Ubuntu14.04安裝配置Ganglia,假設(shè)我們已經(jīng)配置好了ganglia主節(jié)點。
1、把ganglia主節(jié)點的/etc/ganglia/gmond.conf文件拷貝到管理機當前目錄。
2、編寫ganglia安裝腳本install-gmond.sh(不要照抄,下面有修改版)
#!/bin/bash
sudo apt-get -y install ganglia-monitor rrdtool && \
sudo mv /etc/ganglia/gmond.conf /etc/ganglia/gmond.conf.bak && \
sudo mv /home/test/gmond.conf /etc/ganglia/ && \
sudo /etc/init.d/ganglia-monitor restart && \
sudo rm -rf /home/test/install-gmond.sh
3、拷貝gmond.conf和install-gmond.sh到客戶機
pscp -h hosts.txt gmond.conf /home/test/
pscp -h hosts.txt install-gmond.sh /home/test/
4、添加執(zhí)行權(quán)限
pssh -h hosts.txt -i 'chmod +x /home/test/install-gmond.sh'
5、執(zhí)行安裝
pssh -h hosts.txt -i 'sudo apt-get update'
pssh -h hosts.txt -i 'sudo sh /home/test/install-gmond.sh'
腳本雖然順利執(zhí)行了,但是報錯:Stderr: debconf: unable to initialize frontend: Dialog
解決辦法是修改腳本為:
#!/bin/bash
export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true && \
sudo apt-get -y -q install ganglia-monitor rrdtool && \
sudo mv /etc/ganglia/gmond.conf /etc/ganglia/gmond.conf.bak && \
sudo mv /home/test/gmond.conf /etc/ganglia/ && \
sudo /etc/init.d/ganglia-monitor restart && \
sudo rm -rf /home/test/install-gmond.sh
6、查看運行狀態(tài)
pssh -h hosts.txt -i -o /tmp/pssh/ 'ps aux | grep ganglia'
批量修改密碼
參考shell實現(xiàn)SSH自動登陸 和 6個Expect腳本示例,使用expect命令。
1、管理機上新建chpasswd.sh腳本,內(nèi)容如下:
#!/usr/bin/expect
set timeout 3
set user test
set password 123456
spawn sudo passwd $user
expect "Enter new UNIX password:"
send "${password}\r"
expect "Retype new UNIX password:"
send "${password}\r"
expect eof
2、在客戶機上安裝expect(可以用whereis expect查看是否安裝)
pssh -h hosts.txt -i 'sudo apt-get install expect -y'
3、拷貝chpasswd.sh腳本到客戶機
pscp -h hosts.txt chpasswd.sh /home/test
5、添加執(zhí)行權(quán)限
pssh -h hosts.txt -i 'sudo chmod a+x /home/test/chpasswd.sh'
5、執(zhí)行修改密碼
pssh -h hosts.txt -i 'sudo /home/test/chpasswd.sh'
6、刪除chpasswd.sh腳本
pssh -h hosts.txt -i 'sudo rm -rf /home/test/chpasswd.sh'
批量殺進程
假設(shè)需要殺死的進程為gmond。
方法一:
pnuke -h hosts.txt gmond
pssh -h hosts.txt -i 'ps -ef | grep gmond'
這種方法雖然顯示success,但是查看進程依然存在,看來存在不確定性。猜測對于sudo啟動的進程難以殺死。
方法二:
pssh -h hosts.txt -i 'sudo pkill -9 gmond'
這種方法殺的很徹底,是個好方法。
方法三:
pssh -h hosts.txt 'sudo ps -ef | grep gmond | awk '{print $2}' | xargs kill -9'
這種方法也顯示success,但是查看進程依然存在,還是有問題。猜測因為sudo作用在了ps上,所以對于sudo啟動的進程難以殺死。
方法四:
pssh -h hosts.txt -i 'sudo kill -s 9 `pgrep gmond`'
這種方法殺的很徹底,是個好方法。
PS:啟動gmond命令pssh -h hosts.txt -i 'sudo /etc/init.d/ganglia-monitor start
后記
以上實踐,已經(jīng)包含了pssh的最常見用法。更高級的用法,就在需要時再去學(xué)習(xí)吧!