@Vany
2016-03-26T15:48:47.000000Z
字数 6146
阅读 1537
Hadoop
Shell
Bash
CentOS
Linux
这一部分主要介绍的是思想以及原理,如果要具体操作步骤,可以直接跳过看下一部分(三).
抽象看来,集群的部署操作基本只有两种类型操作:
根据基本思想小节中提到的两种操作,我用两个脚本来抽象这两种操作,一个是applyall.sh,一个是remoterunall.sh。
在正式介绍applyall和remoterunall之前,我先介绍一个基本功能,tf,即传送文件的功能。传送文件在部署过程中是非常常见的一个需求,因此我们将其抽象出来作为一个单独的“命令”。
因为传送文件的前提是目标目录存在,因此每次传送文件前需要先mkdir xxx
一下以确保文件夹存在,再传送文件。
但在传送过程中很有可能需要密码或者输入yes
以保存对方的fingerprint,因此这里采用了expect程序来做交互式处理,如果没有的话需要安装一下:yum install expect
。
具体实现的代码如下:
#!/usr/bin/expect
set source [lindex $argv 0]
set dest [lindex $argv 1]
set destfile [lindex $argv 2]
set serverip [lindex $argv 3]
set pwd [lindex $argv 4]
spawn ssh root@$serverip "mkdir $dest"
expect {
"*continue connecting*" { send "yes\r"; exp_continue }
"*password*" { send "$pwd\r"; exp_continue }
"#" { send "\r" }
}
spawn scp -r $source root@$serverip:$dest$destfile
expect {
"*continue connecting*" { send "yes\r"; exp_continue }
"*password*" { send "$pwd\r"; exp_continue }
"#" { send "\r" }
}
先来说说applyall.sh. 调用脚本,传入hostlist(格式同hosts文件),以及要执行的bashfile,就会帮你依次执行,例如我想将本地的hosts文件传送到各个其他机器,则用法如下:
./applyall.sh hostlist deployhosts.sh mypassword
其中hostlist是预先定好的hosts列表(见上一个文章文末),deployhosts.sh内容如下(该脚本必须按照ip,name,pwd的顺序来取对应的参数):
#!/usr/bin/bash
hostip=$1
hostname=$2
pwd=$3
echo -e "\n===Sending hosts to client $1, $2..."
./tf hosts /etc/ hosts $hostip $pwd
这里的tf即上文提到的传送文件的tf。
applyall.sh的脚本如下所示,如果参数中没有传送pwd参数,那么会询问用户手动输入。
#!/usr/bin/bash
if [ $# -lt 2 ]; then
echo "Error call format"
echo "Format: ./applyall.sh hostlist bashfile [pwd]"
exit
fi
hostlist=$1
bashfile=$2
if [ $# -lt 3 ]; then
read -p "Enter the client password:" -s pwd
else
pwd=$3
fi
echo
echo ===Enter Apply-All hostlist: $hostlist, bashfile: $bashfile
cat $hostlist | while read hostInfo
do
hostip=`echo $hostInfo | cut -d " " -f1`
hostname=`echo $hostInfo | cut -d " " -f2`
echo -e "\n===Applying Client $hostip $hostname..."
bash $bashfile $hostip $hostname $pwd
done
echo -e "\n===Leave Apply-All."
remoterunall.sh,顾名思义,就是远程执行脚本的意思。假设我想每台机器更新python,那么我只要写一个小脚本updatepython2.sh在同一个目录下:
yum update python -y
然后运行remoterunall.sh hostlist updatepython2.sh
即可。
remoterunall.sh的实现如下:
#!/usr/bin/bash
if [ $# -lt 2 ]; then
echo "Error call format"
echo "Format: ./remoterunall.sh hostlist bashfile"
exit
fi
hostlist=$1
bashfile=$2
echo
echo ===Enter Remote-RunAll hostlist: $hostlist, bashfile: $bashfile
cat $hostlist | while read hostInfo
do
hostip=`echo $hostInfo | cut -d " " -f1`
hostname=`echo $hostInfo | cut -d " " -f2`
echo -e "\n===Run script in client $hostip $hostname..."
ssh root@$hostip 'bash -s' < $bashfile
done
echo -e "\n===Leave Remote-RunAll."
这里假设执行remoterunall.sh的时候,所有机器之间的ssh-key已经配置好了,可以无密码访问,因此这里并没有需要密码。
接下来的脚本基本是建立在上面的“基本脚本”的基础上的,这里只介绍三个主要脚本:
1. init.sh 负责初始化一个集群
2. configmaster.sh 负责配置master节点 (主要是配置Ambari相关)
3. addnewhost.sh 负责当集群汇总新加入一个节点时,配置新机器以及重新分发hosts等文件
使用方法: ./init.sh hostlist
其中hostlist是一个以hosts格式存着主机名和ip的文件
#!/usr/bin/bash
if [ $# -lt 1 ]; then
echo "Error: parameter is not enough..."
echo "Format: ./init.sh hostlist"
exit
fi
hostlist=$1
read -p "Enter the client password(all should be same):" -s pwd
# generate sever ssh-key
filepath=~/.ssh/id_rsa
if [ -f $filepath ]; then
echo
echo "ssh-key already exists. it won't be generated again."
echo "if you want to generate new key, please remove the key file first."
else
echo
echo "===ssh key generating..."
ssh-keygen -f ~/.ssh/id_rsa -P ""
fi
echo
echo "===Clearing public key gathering folder..."
rm -f ~/.ssh/pub/*
echo
echo "===Copy this public key to that folder..."
cp ~/.ssh/id_rsa.pub ~/.ssh/pub/id_rsa.pub
echo
echo "===Generating hosts file...."
cat ./others/hosts_template $hostlist > hosts
# Deploying Clients...
./applyall.sh $hostlist others/deployclient.sh $pwd
echo
echo "===Gathering pub keys..."
cat ~/.ssh/pub/*.pub > authorized_keys
echo "===Deploying pub keys..."
./applyall.sh $hostlist others/deploypubkeys.sh $pwd
echo
echo "===Cleaning..."
rm -f hosts
rm -f authorized_keys
echo "===Clean finished."
echo
echo "===Reboot all the machine..."
cat $hostlist | while read hostinfo
do
hostip=`echo $hostinfo|cut -d " " -f1`
hostname=`echo $hostinfo|cut -d " " -f2`
ssh root@$hostip 'reboot' < /dev/null
done
echo "===reboot finished."
这里调用configmaster.sh,然后输入主机ip及其密码,即可自动配置ambari的repo地址,并且安装ambari,拷贝现有的jdk到master节点上(Amabri配置时使用)。
read -p "Enter your master ip:" masterip
read -p "Enter your password:" -s pwd
echo $masterip, $pwd
./tf others/ambari.repo /etc/yum.repos.d/ ambari.repo $masterip $pwd
ssh root@$masterip 'bash -s' < others/installmaster.sh
./tf ../jdk/jdk-8u60-linux-x64.tar.gz /var/lib/ambari-server/resources/ jdk-8u60-linux-x64.tar.gz $masterip $jdk
./tf ../jdk/jce_policy-8.zip /var/lib/ambari-server/resources/ jce_policy-8.zip $masterip $jdk
这调用了installmaster.sh,其实就是执行了三句话(即安装ambari):
yum clean all
yum repolist
yum install ambari-server -y
注意调用完该脚本仅仅是安装好了Ambari,接下来还需要到master节点上运行以下命令以配置、启动Amabri:
ambari-server setup
ambari-server start
这个用法和init.sh类似,但是要注意传入一个新的hostlist,一个旧的hostlist。注意:程序并不会自动合并两个hostlist(为了避免任务失败,还需要重新建立hostist)。
#!/usr/bin/bash
newhostlist=$1
orighostlist=$2
if [ $# -lt 2 ]; then
echo "Error: parameter is not enough..."
echo "Format: ./addnew.sh newhostlist orignhostlist"
exit
fi
echo
echo "Enter addnew scirpt: $newhostlist $orighostlist"
read -p "Enter the client password(all should be same):" -s pwd
echo
echo "===Generating new hosts file...."
updatedhostlist="updatedhostlist"
cat $orighostlist > $updatedhostlist
cat $newhostlist >> $updatedhostlist
cat ./others/hosts_template $updatedhostlist > hosts
# Deploying new clients...
./applyall.sh $newhostlist others/deployclient.sh $pwd
echo
echo "===reDeploying hosts file..."
./applyall.sh $updatedhostlist others/deployhosts.sh $pwd
echo -e "\n===gathering pub keys..."
cat ~/.ssh/pub/*.pub > authorized_keys
echo -e "\n===reDeploying pub keys for all clients..."
./applyall.sh $updatedhostlist others/deploypubkeys.sh $pwd
echo
echo "===Cleaning..."
rm -f hosts
rm -f $updatedhostlist
rm -f authorized_keys
echo "===Clean finished."
echo
echo "===reboot all the new machine..."
cat $newhostlist | while read hostinfo
do
hostip=`echo $hostinfo|cut -d " " -f1`
hostname=`echo $hostinfo|cut -d " " -f2`
ssh root@$hostip 'reboot' < /dev/null
done
echo "===reboot finished."
echo
echo "Leave addnew scirpt."
其他的一些脚本这里就不一一放上来了,整个脚本目录如下:
[root@yumsource script]# tree
.
├── addnewhost.sh
├── applyall.sh
├── configmaster.sh
├── hostlist
│ ├── hostlist_new
├── init.sh
├── others
│ ├── ambari.repo
│ ├── configclient_template.sh
│ ├── deployclient.sh
│ ├── deploypubkeys.sh
│ ├── deploypythons.sh
│ ├── disSELinuxCfg
│ ├── hosts_template
│ ├── installmaster.sh
│ ├── installpython34.sh
│ └── updatepython2.sh
├── remoterunall.sh
└── tf