[关闭]
@Vany 2016-03-27T22:12:26.000000Z 字数 8189 阅读 2199

Ambari自动化离线批量部署Hadoop平台总结

Ambari Hadoop


面临的问题

有了Ambari的平台,理论上来说,其实应该很方便的就可以部署Hadoop平台,但是实际上对于一个集群来说,并没有那么简单。
现在,我们是有一堆机器(手动配置非常麻烦),如何将这堆机器利用Ambari快速的搭建成Hadoop平台是我们现在面临的问题。

Client的预配置:对于每台机器,要做很多预先的配置,例如关闭防火墙,更新、安装软件等。
另外,为了实现多个机器之间的无密码访问,我们要设置ssh-key,并且将自己的pub key分发给集群中的各个机器。我们希望这些操作都可以自动化的完成。

每台机器设置hosts:在自动化配置中,机器之间相互通信是根据域名(FQDN, Fully Qualified Domain Name)的,而域名用简单的hostname name命令设置是不对的,这个设置的是hostname命令显示出来的东西,而我们要的是hostname -f命令显示出来的名字,这个需要在hosts文件中或DNS解析中得到。在不自己搭建DNS的情况下,因此我们每台机器都要配置hosts。

没有快速的互联网连接:很多时候集群面临的环境并不是一个和Internet直接相连的环境,因此,对于Ambari这种需要在线从互联网上下载的情况,或者Internet网速不佳的情况,我们就要有相应的办法应对,一个简单的办法就是实现下好离线文件,自己搭建yum source. 在我这里的环境下可以有镜像更新yum,因此我们只要考虑要安装的Ambari整个库的配置就好。


集群配置

根据上面的问题,我们提出自己搭建yum source源,并利用脚本自动化部署的方法。

一共有3类机器,一台作为yumsource,一台作为master,其余的作为slaves.

配置如下

机器 FQDN(域名) 描述
yum源 yumsource.hadoop 部署HDP、HDP-util、Ambari的源
master master.hadoop 作为hadoop的master机器,安装ambari-server
N台slave slaveX.hadoop 作为hadoop的slave机器,会自动安装ambari-agent

这里每台机器2核CPU,4G内存(这个要大一些,使用过1G结果卡死了,服务多的机器8G最好),50-100GB硬盘,系统采用CentOS7完全版


用到的技术


Goal

  1. 按照官方文档的说明,每台机器的需要配置的项如下:

    • 设置ip等网络配置,并且设置开机自动启动网络
    • 生成ssh-key,并且将public key传送给其他机器
    • 关闭SELinux(需要重启)
    • 关闭iptables(CentOS7中是firewalld),并设置开机启动
    • 安装ntp,启动ntpd,并设置开机启动
    • 更新openssl
    • 设置hosts
      注:其中有一些可以统一用脚本处理,有一些(例如ip的设置)就需要每台手动做了
  2. 配置好了基本配置后,我们还需要配置下Ambari、HDP、HDP-UTILS的服务器(yum source),使其成为一个yum-source server.

  3. 接下来就是安装Ambari了

下面会详细叙述整个过程。


Steps

安装Amabri之前我们需要做一些准备工作,主要分为:

Pre-work of each client

每台机器做简单的ip配置即可,只要实现其在集群的网络中并且可以连通,以及yum install xxx好使就可以了。

在我这里环境下,我是需要手动配置静态ip的,并且设置了DNS就可以使用yum install(如果不可以的话,那么就要自己配置centosssyum source了),另外我希望在不同网段的机器远程访问该服务器,因此我设置了两方面内容:

/etc/sysconfig/network-script/ifcfg-eth0中设置ip(eth0为对应的网卡,CentOS7中一般为enoXXXXXX)及DNS,并设置自动启动该网卡(ONBOOT=yes):

  1. BOOTPROTO=static
  2. ONBOOT=yes
  3. IPADDR=xx.xx.xxx.xxx
  4. NETMASK=255.255.255.0
  5. DNS1=xx.xx.x.xx

/etc/sysconfig/network中设置gateway(用于其他网段的机器访问该机器,可选):

  1. GATEWAY=xx.xx.xxx.x

Server端自动化脚本

这里的server是指master、slave之外的机器,我这里采用yumsource那台机器作为Server。

在Server端,主要做以下几件事情:
1. 生成server的ssh-key, 并且分发给各个client(使用scp命令,并且用expect处理交互),为后面的无密码访问client做准备
2. 给各个client传送hosts文件
3. 给各个client传送selinux的配置文件(通过这种方式设置关闭)
4. 调用client该执行的脚本,并用ssh远程执行: ssh root@$hostip 'bash -s' < client.sh
5. 将client生成的公钥(public key)收集回server:同样使用scp,如下
scp -r root@$hostip:~/.ssh/id_rsa.pub ~/.ssh/pub/$hostname.pub
6. 当所有client都处理完毕后,收集、整合所有的公钥再分发给各个client(下文的deploypubkeys.sh)
7. 最后再依次远程重启每个机器(ssh root@$hostip 'reboot' < /dev/null),以应用配置

建立一个hostlist文件(其实就是我们要传送的hosts)

  1. 10.xx.xxx.xxx master.hadoop
  2. 10.xx.xxx.xxx slave1.hadoop
  3. 10.xx.xxx.xxx slave2.hadoop

在这里我们用脚本读取hostlist文件的每个机器(包括master、slave)的ip与域名(hostname),然后依次执行上述的操作:

  1. cat hostlist | while read hostinfo
  2. do
  3. hostip=`echo $hostinfo|cut -d " " -f1`
  4. hostname=`echo $hostinfo|cut -d " " -f2`
  5. ...

具体实现主要采用bash脚本以及expect程序,expect程序用于需要输入密码等交互时使用,
这里将传送文件的那几个任务(1-3)都用expect程序实现(即下文的deployclient.sh),其余的用bash脚本实现。

关闭SELinux的配置文件需要提前存好,名字为disSELinuxCfg,内容如下:

  1. SELINUX=disabled
  2. SELINUXTYPE=targeted

下面就是脚本们,把所有的代码、配置放在一个文件夹下,运行initserver.sh即可。

initserver.sh

  1. #!/usr/bin/bash
  2. filepath=~/.ssh/id_rsa
  3. # read -p "Plase specify the ip of this server:" serverip
  4. serverip=xx.xx.xxx.xxx
  5. read -p "Enter the client password(all should be same):" -s pwd
  6. if [ -f $filepath ]; then
  7. echo
  8. echo "ssh-key already exists. it won't be generated again."
  9. echo "if you want to generate new key, please remove the key file first."
  10. else
  11. echo
  12. echo "===ssh key generating..."
  13. ssh-keygen -f ~/.ssh/id_rsa -P ""
  14. fi
  15. rm -rf ~/.ssh/pub/
  16. mkdir ~/.ssh/pub/
  17. cp ~/.ssh/id_rsa.pub ~/.ssh/pub/id_rsa.pub
  18. cat hosts_template hostlist > hosts
  19. echo
  20. echo "===Deploying Client..."
  21. cat hostlist | while read hostinfo
  22. do
  23. hostip=`echo $hostinfo|cut -d " " -f1`
  24. hostname=`echo $hostinfo|cut -d " " -f2`
  25. echo "===Deploy Client $hostip..."
  26. chmod +x deployclient.sh
  27. ./deployclient.sh $hostip $pwd
  28. head1="clientip=$hostip\n"
  29. head2="serverip=$serverip\n"
  30. head3="password=$pwd\n"
  31. head=$head1$head2$head3
  32. echo -e $head > head.tmp
  33. cat head.tmp client_template.sh > client.sh
  34. ssh root@$hostip 'bash -s' < client.sh
  35. echo
  36. echo "===Transfer pub key to server..."
  37. scp -r root@$hostip:~/.ssh/id_rsa.pub ~/.ssh/pub/$hostname.pub
  38. done
  39. echo
  40. echo "===gathering pub keys..."
  41. cat ~/.ssh/pub/*.pub > authorized_keys
  42. echo "===deploy pub keys..."
  43. cat hostlist | while read hostip
  44. do
  45. ./deploypubkeys.sh $hostip $pwd
  46. done
  47. echo
  48. echo "===Cleaning..."
  49. rm -f head.tmp
  50. rm -f client.sh
  51. rm -f hosts
  52. rm -f authorized_keys
  53. echo "===Clean finished."
  54. echo
  55. echo "===reboot all the machine..."
  56. cat hostlist | while read hostinfo
  57. do
  58. hostip=`echo $hostinfo|cut -d " " -f1`
  59. hostname=`echo $hostinfo|cut -d " " -f2`
  60. ssh root@$hostip 'reboot' < /dev/null
  61. done
  62. echo "===reboot finished."

expect脚本deployclient.sh(用于给各个client传送各种文件)

  1. #!/usr/bin/expect
  2. set clientip [lindex $argv 0]
  3. set pwd [lindex $argv 1]
  4. # deploy current pub key
  5. spawn ssh root@$clientip "mkdir ~/.ssh"
  6. expect {
  7. "*continue connecting*" { send "yes\r"; exp_continue }
  8. "*password*" { send "$pwd\r"; exp_continue }
  9. "#" { send "\r" }
  10. }
  11. # deploy current pub key
  12. spawn scp /root/.ssh/id_rsa.pub root@$clientip:~/.ssh/authorized_keys
  13. expect {
  14. "*continue connecting*" { send "yes\r"; exp_continue }
  15. "*password*" { send "$pwd\r"; exp_continue }
  16. "#" { send "\r" }
  17. }
  18. # deploy selinux config
  19. spawn scp disSELinuxCfg root@$clientip:/etc/selinux/config
  20. expect {
  21. "*continue connecting*" { send "yes\r"; exp_continue }
  22. "*password*" { send "$pwd\r"; exp_continue }
  23. "#" { send "\r" }
  24. }
  25. # deploy hosts
  26. spawn scp hosts root@$clientip:/etc/hosts
  27. expect {
  28. "*continue connecting*" { send "yes\r"; exp_continue }
  29. "*password*" { send "$pwd\r"; exp_continue }
  30. "#" { send "\r" }
  31. }

expect脚本deploypubkeys.sh(用于server给各个client分发汇总的公钥)

  1. !/usr/bin/expect
  2. set serverip [lindex $argv 0]
  3. set pwd [lindex $argv 1]
  4. spawn scp authorized_keys root@$serverip:~/.ssh/authorized_keys
  5. expect {
  6. "*continue connecting*" { send "yes\r"; exp_continue }
  7. "*password*" { send "$pwd\r"; exp_continue }
  8. "#" { send "\r" }
  9. }

Client端脚本(远程调用)

给每个client执行的脚本client_template.sh,在Server端通过ssh远程调用。

这里之所以是个template,这是因为我们在server端会根据不同的client生成前面的一些信息(包括clientip,serverip等),将信息放在这个template最前面,然后供client执行。(这里其实就是为了显示那一句echo,表示当前处理到哪个机器了……因此client_template.sh是可以直接被client执行的,不会有任何实质上的影响)

  1. hostname=`hostname -f`
  2. firewall="firewalld" #centos7中是firewalld,之前是iptables
  3. echo
  4. echo "client $clientip hostname: $hostname, server: $serverip"
  5. echo
  6. echo "===disable $firewall & it won't start after boot..."
  7. service $firewall stop
  8. chkconfig $firewall off
  9. echo
  10. echo "===install, start, config ntpd..."
  11. yum -y install ntp
  12. systemctl disable chronyd #centos7中要关闭这个否则冲突
  13. service ntpd restart
  14. chkconfig ntpd on
  15. echo
  16. echo "===deal with ssh key..."
  17. rm -f ~/.ssh/id_rsa*
  18. ssh-keygen -f ~/.ssh/id_rsa -P ""
  19. echo
  20. echo "===update openssl..."
  21. yum -y update openssl
  22. echo
  23. echo "===deal with sshd..."
  24. service sshd restart
  25. chkconfig sshd on
  26. echo
  27. echo "===set network start automatically..."
  28. chkconfig network on
  29. echo
  30. echo "===Finished!!!"

Yum Source的配置

由于教育网可以直接更新CentOS的软件,因此我这里没有配置CentOS的yum-source。这里我们仅仅配置Ambari和HDP、HDP-UTIL包的source。

首先下载各个安装包,地址可以在文档中找到,如2.2.0.0的网址是:
http://docs.hortonworks.com/HDPDocuments/Ambari-2.2.0.0/bk_Installing_HDP_AMB/content/_obtaining_the_repositories.html

然后将各个安装包解压放在/var/www/html下的hdp文件夹(自己建一个hdp文件夹),然后利用httpd(没有的话自己安装一下)把html整个目录对外开放。如果在另一台机器访问这台机器的域名,能看到整个目录以及文件信息,那么就说明ok了。

Ambari安装与配置

在安装之前,我们还需要告诉yum去哪里下载我们的ambari,建立一个ambari.repo并放在/etc/yum.repos.d/下面,内容如下:

  1. [Ambari-2.2.0.0]
  2. name=Ambari-2.2.0.0
  3. baseurl=http://yumsource.hadoop/hdp/ambari-2.2.0.0/centos7/2.2.0.0-1310/
  4. gpgcheck=0
  5. enabled=1
  6. [HDP-2.3.4.0]
  7. name=HDP-2.3.4.0
  8. baseurl=http://yumsource.hadoop/hdp/HDP/centos7/2.x/updates/2.3.4.0/
  9. gpgcheck=0
  10. enabled=1
  11. [HDP-UTILS-1.1.0.20]
  12. name=HDP-UTILS-1.1.0.20
  13. baseurl=http://yumsource.hadoop/hdp/HDP-UTILS-1.1.0.20/repos/centos7/
  14. gpgcheck=0
  15. enabled=1

配置好后, 调用yum install -y ambari-server即可开始安装ambari及其附属组件。
安装好后,调用ambari-server setup即可开始设置ambari,在这个过程中需要下载JDK,
我们可以提前下好JDK,然后放在对应的目录下:/var/lib/ambari-server/resources/,这样可以节约很多时间.

安装成功后,执行ambari-server start即可启动,接着就在浏览器中查看master这台机器的8080端口即可访问配置页面,按照提示一步步做就好。

节点重启怎么办

主节点调用ambari-server restart
子节点调用ambari-agent restart
剩下的具体Hadoop服务,直接在网页端就可以配置了


背景知识

expect

expect是一个解释器,可以处理交互式输入,例如:

  1. spawn scp authorized_keys root@$serverip:~/.ssh/authorized_keys
  2. expect {
  3. "*continue connecting*" { send "yes\r"; exp_continue }
  4. "*password*" { send "$pwd\r"; exp_continue }
  5. "#" { send "\r" }
  6. }

在调用scp命令时,会问你输入密码等;我们可以用spawn加个壳来调用scp,用expect来匹配可能的输出(例如\*password\*,这里*是通配符),从而做出动作;send "command"用于发送指令,exp_continue表示继续匹配,否则就直接进行下一条语句了。

另外,spawn套spawn貌似不是很好使。

无密钥SSH登录

ssh原理就是,自己生成一对公钥、私钥. 将公钥给要登录的服务器,自己是私钥. 登录时,client发送公钥给server,服务器看到自己这有匹配的公钥,加密一段信息返回给client. client用私钥解密,再给服务器,从而建立一个连接.

因此client要把公钥复制到服务器的~/.ssh/目录下,文件名为authorized_keys,如果有多个(多个client都想这么配置),直接cat起来就好。

配置好后,ssh 对方域名/ip,即可测试是否成功。

FQDN

Fully Qualified Domain Name, 是对应hosts文件中的名字
hostname -f查看

bash中指令结果存到变量

variable=`hostname -f`
echo $variable

用``把命令包起来即可。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注