博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hadoop自动安装的脚本与步骤
阅读量:5843 次
发布时间:2019-06-18

本文共 8713 字,大约阅读时间需要 29 分钟。

最近要在10几台机器上安装hadoop。对于这种繁复而重复的工作,一步步的打命令行,对于程序员来说是一件不能忍的事情。所以我就琢磨着怎么写一个脚本来自动安装hadoop。

任务: 在10几台机器上中的任意一台执行脚本,即可安装好hadoop。

条件: 每台机器的用户名和密码都是一样的。每台机器都配置好了ssh,能够远程登录。

解决思路:

  1. 首先读取配置文件,读取到节点的ip和想要的机器名字,然后修改好本地hadoop的配置文件。

  2. 然后读取配置文件,复制所有文件到每个节点的安装的路径。(利用scp命令可以远程复制)

  3. 然后读取配置文件,自动ssh到每个节点做一些配置工作,包括配置hadoop和JDK 环境变量、生成ssh-key。

  4. ssh到主节点,将每个节点(包括主节点自己)生成的public key 都复制并追加到自己的authorized_keys. 然后把这个authorized_keys分发到每个节点。

 

这样就配置好了hadoop。

  题外话,介绍一下 ssh-keygen。ssh-keygen是一个ssh用于生成密钥的命令。用途是用于免密码登录。它会生成两个密钥,一个是公钥,一个是私钥。比如A 机器生成了pubKeyA,priKeyB。然后A 把pubKeyA给了机器B ,然后机器B 就可以无密码登录机器A 了。

 

在上面的步骤中,主要的难题是。

1. 对于步骤一,主要难题在于怎么用shell读取配置文件。由于我也之前没写过shell,所以Shell的循环和if 语句和字符串处理也卡了不少时间。

# 这段代码是怎么从hosts的节点配置文件中读取节点的信息 # hosts的格式如下 # 192.168.1.100 master # 192.168.1.101 slave1 # 192.168.1.102 slave2 # ... while read linedo    echo $line    ip=`echo $line | cut -d" " -f1`    name=`echo $line | cut -d" " -f2`    if [ ! -z $ip ]; then        echo $name        if [[ $name == maste* ]]; then        echo "$name" >> ../hadoop-1.2.1/conf/masters        elif [[ $name == slave* ]]; then        echo "$name" >> ../hadoop-1.2.1/conf/slaves         fi    fidone < hosts

2. 对于步骤2,由于刚开始节点直接没有实现无密码ssh,所以scp命令需要输入密码,所以怎么实现自动输入密码实在是一个棘手的问题。我搜索之后,发现一个工具叫expect。

 expect工具就像bash一样有自己的语法,然后有自己的命令。它的语法是基于TCL这种脚本语言(我也没听过),看帮助可以直接man expect。我觉得主要需要知道的expect命令是spawn,expect,exp_continue这三个。

#!/usr/bin/expect # expect 定义函数的方式如下proc usage {} {    puts stderr "usage: $::argv0 ip usrname password"    exit 1}if {$argc != 3} { usage }#利用脚本传参数set hostip [lindex $argv 0]set username [lindex $argv 1]set password [lindex $argv 2]set timeout 100000# 利用expect的spawn命令来代理执行命令spawn scp -r ../../hadoop ${username}@${hostip}:~#获取期望的输出expect {#如果输出是 要输入密码 #注意下面的大括号 不能换行写,必须用Java风格,而且与前面的“之间要有一个空格,我当时犯了这错误,程序执行的结果很奇怪却不报错。    "*assword:" {        send "$password\n"#输入密码后期待spawn代理的命令结束        expect eof    }#如果不需要输入密码,那也是一样期待命令结束    expect eof}

 

对于步骤3、4已经没什么挑战性了,很快就完成了。

下面我把所有代码贴上来

  1. setHadoopOnce.sh 这个文件是脚本执行的起点

1 #!/bin/bash 2 #修改密码 3 pw=123456 4 loginName=hadoop 5 master=master 6 slave=slave 7 slaveNum=1 8 set timeout 100000 9 > ../hadoop-1.2.1/conf/masters10 > ../hadoop-1.2.1/conf/slaves11 #update local file12 while read line13 do14     echo $line15     ip=`echo $line | cut -d" " -f1`16     name=`echo $line | cut -d" " -f2`17     if [ ! -z $ip ]; then18         echo $name19         if [[ $name == maste* ]]; then20         echo "$name" >> ../hadoop-1.2.1/conf/masters21         elif [[ $name == slave* ]]; then22         echo "$name" >> ../hadoop-1.2.1/conf/slaves23         fi24     fi25 done < hosts26 #upload file to all nodes27 while read line28 do29     ip=`echo $line | cut -d" " -f1`30     name=`echo $line | cut -d" " -f2`31     if [ ! -z $ip ]; then32         expect copyDataToAll.exp $ip $loginName $pw33         expect setForAll.exp $ip $loginName $pw34     fi35 done < hosts36 37 while read line38 do39     ip=`echo $line | cut -d" " -f1`40     name=`echo $line | cut -d" " -f2`41     if [ ! -z $ip ]; then42         if [[ $name == maste* ]]; then43             expect setForMaster.exp $ip $loginName $pw44         fi45     fi46 done < hosts

  2. copyDataToAll.exp 这个在setHadoopOnce.sh中的32行被调用,以复制文件到所有节点。

1 #!/usr/bin/expect 2 proc usage {} { 3     puts stderr "usage: $::argv0 ip usrname password" 4     exit 1 5 } 6 if {$argc != 3} { usage } 7 set hostip [lindex $argv 0] 8 set username [lindex $argv 1] 9 set password [lindex $argv 2]10 set timeout 10000011 spawn scp -r ../../hadoop ${username}@${hostip}:~12 expect {13     "*assword:" {14         send "$password\n"15         expect eof16     }17     expect eof18 }

  3. setForAll.exp 为所有节点进行一些配置工作,在setHadoopOnce.sh中的33行被调用.

#!/usr/bin/expectproc usage {} {    puts stderr "usage: $::argv0 ip usrname password"    exit 1}proc connect {
pwd} { expect { "*(yes/no)?" { send "yes\n" expect "*assword:" { send "$pwd\n" expect { "*Last login:*" { return 0 } } } } "*assword:" { send "$pwd\n" expect { "*Last login:*" { return 0 } } } "*Last login:*" { return 0 } } return 1}if {$argc != 3} { usage }set hostip [lindex $argv 0]set username [lindex $argv 1]set password [lindex $argv 2]set timeout 100000spawn ssh ${username}@${hostip}if {[connect $password]} { exit 1}#set hostsend "sudo bash ~/hadoop/setup/addHosts.sh\r"expect "*assword*"send "$password\r"expect "*ddhostsucces*"sleep 1send "ssh-agent bash ~/hadoop/setup/sshGen.sh\n"expect { "*(yes/no)?" { send "yes\n" exp_continue } "*verwrite (y/n)?" { send "n\n" exp_continue } "*nter file in which to save the key*" { send "\n" exp_continue } "*nter passphrase*" { send "\n" exp_continue } "*nter same passphrase again*" { send "\n" exp_continue } "*our public key has been saved*" { exp_continue } "*etsshGenSucces*" { sleep 1 }}send "bash ~/hadoop/setup/setEnvironment.sh\n"expect "*etEnvironmentSucces*"sleep 1send "exit\n"expect eof

  3.1  addHosts.sh 在setForAll.exp中被调用,用于设置节点的hosts文件

#!/bin/bashhadoopRoot=~/hadoophadoopPath=$hadoopRoot/hadoop-1.2.1setupPath=$hadoopRoot/setuplocalip="`ifconfig |head -n 2|tail -n1 |cut -f2 -d: |cut -f1 -d" " `"hostline="`grep "$localip$" $hadoopRoot/setup/hosts`"sed -i /$hostline/\d $hadoopRoot/setup/hosts#cp /etc/hosts /etc/hosts.hadoop.bakfor delip in `cat $hadoopRoot/setup/hosts`do    delipline="`grep -n "$delip[[:space:]]" /etc/hosts |cut -f1 -d:`"    #echo $delipline    if [ -n "$delipline" ]; then        sed -i $delipline\d /etc/hosts        sleep 1s    #else        #echo "Your List have no the ip $delip"    fidonecat $hadoopRoot/setup/hosts >> /etc/hostsrm -f "$setupPath"/sed*echo "addhostsuccess"

  3.2 sshGen.sh 在setForAll.sh中被调用,用于生成sshkey。

#!/bin/bashsshPath=~/.sshsetupPath=~/hadoop/setuprm "$sshPath"/authorized_keyssleep 1ssh-keygen -t rsacat "$sshPath"/id_rsa.pub >> "$sshPath"/authorized_keysssh-addecho "setsshGenSuccess"

  3.3 setEnvironment.sh 在setForAll.sh中被调用,用于设置环境变量

#!/bin/bashhadoopRoot=~/hadoophadoopPath=$hadoopRoot/hadoop-1.2.1setupPath=$hadoopRoot/setupJAVA_VERSION=`java -version 2>&1 | awk '/java version/ {print $3}'|sed 's/"//g'|awk '{if ($1>=1.6) print "ok"}'`if [ "$JAVA_VERSION"x != "okx" ]; then    cat "$setupPath"/jdkenv >> ~/.bashrc    sleep 1    source ~/.bashrc    sleep 1fiHadoop_Version=`hadoop version|awk '/Hadoop/ {print $2}'|awk '{if ($1>=1.0) print "ok"}'`if [ "$Hadoop_Version"x != "okx" ]; then    cat "$setupPath"/hadoopenv >> ~/.bashrc    sleep 1    source ~/.bashrc    sleep 1fiecho "setEnvironmentSuccess"

4. setForMaster.exp 远程ssh调用setForMaster.sh,以配置无密码登录的功能。

#!/usr/bin/expectproc usage {} {    puts stderr "usage: $::argv0 ip usrname password"    exit 1}proc connect {
pwd} { expect { "*(yes/no)?" { send "yes\n" expect "*assword:" { send "$pwd\n" expect { "*Last login:*" { return 0 } } } } "*assword:" { send "$pwd\n" expect { "*Last login:*" { return 0 } } } "*Last login:*" { return 0 } } return 1}if {$argc != 3} { usage }set hostip [lindex $argv 0]set username [lindex $argv 1]set password [lindex $argv 2]set timeout 100000spawn ssh ${username}@${hostip}if {[connect $password]} { exit 1}send "ssh-agent bash ~/hadoop/setup/setForMaster.sh\n"expect { "*etForMasterSucces*" { sleep 1 send "exit\n" } "*assword*" { send "$password\n" exp_continue } "*(yes/no)?" { send "yes\n" exp_continue }}

  4.1 setForMaster.sh

#!/bin/bashwhile read linedo    ip=`echo $line | cut -d" " -f1`    name=`echo $line | cut -d" " -f2`    if [ ! -z $ip ]; then        if [[ $name == slave* ]]; then            scp $ip:~/.ssh/authorized_keys ~/tmpkey            cat ~/tmpkey >> ~/.ssh/authorized_keys        fi    fidone < ~/hadoop/setup/hostssleep 1rm -f ~/tmpkeywhile read linedo    ip=`echo $line | cut -d" " -f1`    name=`echo $line | cut -d" " -f2`    if [ ! -z $ip ]; then        if [[ $name == slave* ]]; then            scp ~/.ssh/authorized_keys $ip:~/.ssh/authorized_keys        fi    fidone < ~/hadoop/setup/hostsecho "setForMasterSuccess"

 

安装包打包下载地址: http://pan.baidu.com/s/1dDj6LHJ

 

转载于:https://www.cnblogs.com/tlm1992/p/tlm_hadoop_auto.html

你可能感兴趣的文章
Mininet实验 自定义拓扑结构
查看>>
datagrid鼠标悬浮提示
查看>>
Node.js大众点评爬虫
查看>>
Html5
查看>>
微信红包惊人秘密:谁最容易抢到大红包?
查看>>
Spark 概念学习系列之从物理执行的角度透视spark Job(十七)
查看>>
连接 insance 到 vlan101 - 每天5分钟玩转 OpenStack(97)
查看>>
sqlserver两种分页方法比较
查看>>
【python】面向对象编程
查看>>
分布式系统关注点——99%的人都能看懂的「熔断」以及最佳实践
查看>>
常见的 Web 应用攻击示例
查看>>
【43】学习处理模版化基类内的名称
查看>>
Tag:meta
查看>>
纯javaScript实现div层拖动/移位效果 推荐学习
查看>>
自定义UITabBarController以及UITabBar的分析
查看>>
oracle 获取当前用户下的所有表名与字段信息
查看>>
Nginx配置文件详细说明
查看>>
[转]【基于zxing的编解码实战】精简Barcode Scanner篇
查看>>
自动化运维工具之ansible
查看>>
解密javascript模块载入器require.js
查看>>