红联Linux门户
Linux帮助

Linux Cluster环境下批量分发执行补丁

发布时间:2016-08-04 14:59:05来源:linux网站作者:李子无为
这两天做了一个需求,因为上一个版本的/tmp空间默认只分配了5G,而升级程序上传解压路径也是/tmp,且解压过程要占用5G左右的空间,这样就导致/tmp空间占满,解压失败,升级无法进行。后来想了一个办法,就是从/var建了一个软链接到/tmp,这样实际上升级文件上传解压到/var路径下了,解决了/tmp路径空间不足的问题。但是因为客户那里是一个cluster环境,由6个node组成,最好能够在一个机器上执行一次补丁,所有node都生效。
经过几次尝试,写了两个shell脚本,一个run.sh负责调度和分发补丁,另外一个doFix.sh,真正给系统打补丁的脚本。这里只介绍调度分发的部分。
基本思路就是从主node上将doFix.sh脚本分发到其他各个node上,然后再从主node上ssh到各node执行补丁脚本。
Linux Cluster环境下批量分发执行补丁
 
调度脚本run.sh:
#!/bin/bash
#check version  
cat /etc/issue | grep "V3.5"  
if [ $? -ne 0 ]; then  
echo "This is not V3.5, exit!"  
exit  
fi
ISFABRIC=0  
ADMPW=""
echo
read -rsn1 -p "Is this a fabric with same admin password? [y/n]"  
echo  
if [ "$REPLY" = "y" -o "$REPLY" = "Y" ]; then  
ISFABRIC=1  
read -esp "Please input the password: " ADMPW  
else  
echo "Please run the script doFix.sh manually"  
exit  
fi  
echo  
echo
echo "Patch current node..."  
sh ./doFix.sh
NODEIP=$(ifconfig eth0 | grep 'inet addr' | cut -d':' -f2 | awk '{print $1}')
echo "Begin to patch other nodes..."  
echo
egrep "MAGICNODE-" /etc/hosts | awk '{print $1}' | sort | uniq | while read LINE  
do  
if [ "$NODEIP" = "$LINE" ]; then  
continue  
fi
echo "Patching node $LINE"  
# scp doFix.sh to remote node  
./scpExpect $ADMPW./doFix.sh admin@$LINE:/tmp/  
if [ $? -ne 0 ]; then  
echo "SCP script to node $LINE failed! skip"  
continue  
fi
# execute patch script  
./sshExpectSudo admin $ADMPW $LINE "sudo bash /tmp/doFix.sh"  
if [ $? -ne 0 ]; then  
echo "Remote patch node $LINE failed! skip"  
continue  
fi  
echo  
echo  
done
echo "Patch finished."  
 
从/etc/hosts文件中获取cluster环境的所有node IP,然后将doFix.sh脚本通过scp送过去,再执行ssh打补丁。
这里两个关键点是scpExpect和sshExpect,何为Expect文件?网上有很多Expect的介绍文章,归结一句话就是一种实现自动化交互的脚本语言,从TCL扩展出来。
 
上代码:
scpExpect
#!/usr/bin/expect -f  
# usage: scpExpect user password ip file target
system "rm -rf  ~/.ssh/known_hosts"  
set password [lindex $argv 0]  
set from  [lindex $argv 1]  
set to  [lindex $argv 2]  
set timeout 120
# now connect to remote UNIX box (ipaddr) with given script to execute  
spawn scp -r -o StrictHostKeyChecking=no $from $to  
match_max 100000  
expect {  
"*assword:*" {  
send -- "$password\r"  
set timeout -1  
expect {  
"*assword:*" {  
exit  
}  
}  
} "yes/no)?" {  
send "yes\r"  
set timeout -1  
} -re . {  
exp_continue  
} timeout {  
exit  
} eof {  
exit  
}  
}  
 
sshExpect
#!/usr/bin/expect -f  
# usage:  ssh user password ipaddre command target  
# set Variables  
set user [lrange $argv 0 0]  
set password [lrange $argv 1 1]  
set ipaddr [lrange $argv 2 2]  
set command  [lrange $argv 3 3]  
set target  [lrange $argv 4 4]  
set timeout -1
# now connect to remote UNIX box (ipaddr) with given script to execute  
spawn ssh -o StrictHostKeyChecking=no $user@$ipaddr $command $target  
match_max 100000  
# Look for passwod prompt  
expect "*?assword:*"  
# Send password aka $password  
send -- "$password\r"  
# send blank line (\r) to make sure we get back to gui  
send -- "\r"  
expect eof  
 
感概一下:学习脚本切忌眼高手低,看着挺简单的东西,但是真正要自己写的时候发现步履维艰啊。shell脚本里面细节一不注意就容易犯错误,比如说if语句中方括号要注意两边的空格,还有"="两边的空格。另外一些细节的处理,shell很周到地为你考虑到了,比如输入密码时要防止回显,一个-s参数就搞定,所以有时候得多看看男人(man)。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/22989.html