359025439 发表于 2015-10-13 10:13:19

使用Docker建立Hadoop 2集群

准备工作
  首先通过
  docker pull sequenceiq/hadoop-docker:2.7.0
  把hadoop镜像拉取下来。
  根据文档显示,启动镜像的命令为:
  docker run -it sequenceiq/hadoop-docker:2.7.0 /etc/bootstrap.sh -bash
  此镜像已经配置好了伪分布式模式的hadoop,可以直接体验伪分布式环境。
  
  接下来着手建立真正的分布式集群。规划如下:
  建立一个主机“hdp1”,作为namenode,secondarynamenode和resourcemanager。
  同时建立另一个主机“hdp2”,作为datanode和nodemanager。
  在下面的讲述中,hdp1是master机器,hdp2是slave机器。
第一步,让主从机互相ssh无密码登录。
  首先启动hdp1机器,脚本如下:
  docker run --name hdp1 \
  -it \
  -h hdp1 \
  -v /home/zhujianfeng/docker_data/hadoop_share:/var/local/hadoop_share \
  -p 50070:50070 \
  -p 8088:8088 \
  sequenceiq/hadoop-docker:2.7.0 \
  /etc/bootstrap.sh -bash
  脚本说明:
  1,50070是namenode的web查看端口,8088是resourcemanager的web查看端口,所以要暴露出来,这样就能通过浏览器查看是否正常运行起来了。
  2,主机名和容器名设置很有用,第一是docker对于建立起来的容器而言,之前已经存在的容器是可以直接通过主机名访问的,之后建立的容器就不能直接访问主机名。第二是此镜像中的hdfs访问slave主机不能直接访问ip,会出错,所以slaves文件中只能存主机名。具体后面会有讲述。
  3,挂载一个目录是为了在容器间共享登录所需的公钥文件,每个容器启动脚本里都是一致的写法。
  
  首先注意这个镜像为了避免容器ssh端口和主机ssh端口冲突,已经将容器端口设置成了2122,这样hadoop是不能直接登录到其他主机的,所以需要
  vi /etc/ssh/sshd_config
  把指定2122端口的那一行配置去掉。保存退出后重启sshd服务:
  service sshd restart
  
  接着我们生成可以让其他主机直接登陆的rsa公钥:
  ssh-keygen -t rsa -P “”
  如果之前生成过,会问要不要覆盖,选择要。
  然后把公钥信息添加到授权文件末尾:
  cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
  这样做的用意是在本机ssh 到本机也是可以的,这看似多此一举的事情很有必要,因为hadoop操作本机的方式也是ssh到本机,而且ssh成功之前会有一个问询,需要接受之后才能继续,所以务必要在第一步结束之前一一确认:master ssh master,master ssh slave通畅;slave ssh slave,slave ssh master 通畅。
  由于这个公钥文件需要给其他容器使用,接下来我们需要把他拷贝到公用文件夹中:
  cp ~/.ssh/id_rsa.pub /var/local/hadoop_share/id_rsa.hdp1.pub
  这样在其他容器中就可以从这个文件夹中导入对应主机的公钥,在hdp1中,如果要导入hdp2的公钥,写法是这样的:
  cat /var/local/hadoop_share/id_rsa.hdp2.pub >> ~/.ssh/authorized_keys
  
  接下来我们该启动hdp2作为slave机器了,由于所有的slave机器都有十分相似的配置,为了简便操作,我们可以将hdp1的一些修改提交成新的镜像(本次实践中新镜像名为“hadoop2:latest”),然后再从新镜像创建容器。
  首先容器内修改/etc/bootstrap.sh文件,这是容器启动时要执行的脚本。
  由于我们计划将hdp1作为namenode,这样core-site.xml中的默认hdfs都是以hdp1作为服务器的,所以fs.defaultFS这一项的所有值都是hdfs://hdp1:9000/,不能再根据$HOSTNAME制订了,所以可以将$HOSTNAME直接替换成hdp1。
  另外每次启动都直接执行start-dfs.sh和start-yarn.sh会让启动浪费在错误的配置当中,进入容器后还要先stop-all.sh。可以将这两行注释掉。等进入容器后再启动。
  这样我们就可以:
  docker commit hdp1 hadoop2:latest
  提交修改后的容器为新镜像了。
  新建hdp2的脚本如下:
  docker run --name hdp2 \
  -it \
  --link hdp1:hdp1 \
  -h hdp2 \
  -v /home/zhujianfeng/docker_data/hadoop_share:/var/local/hadoop_share \
  hadoop2:latest \
  /etc/bootstrap.sh -bash
  这里我们将master机器hdp1连接到了slave机器hdp2,可以在hdp2中免去配置hdp1网络信息的操作。
第二步 配置主从机
  镜像中已经配置好了主要的环境变量,我们主要的操作位置是在hadoop的主目录中,所以我们在控制台中:
  cd $HADOOP_PREFIX
  就可以切换到hadoop的主目录。注意,操作是在$HADOOP_PREFIX下进行的,hadoop的目录组织和linux根目录组织很像,如下图所示:

  
  首先我们关注./etc/hadoop/core-site.xml
  这个文件主从机都是一样的,设置(注意写法只是示意,实际是<property>标签):
  fs.defaultFS = hdfs://hdp1:9000
  
  接着是./etc/hadoop/hdfs-site.xml
  这个文件主从机也是一样的,设置如下图:


  因为我们只有hdp2这一台slave机器,如果有更多的slave可以配置,这里的值必须相应修改。
  同时必须注意指定namenode和datanode的工作目录,hdfs很容易出现目录内文件不同步或者锁定而导致hdfs启动失败的情况,所以不能使用默认的配置路径,需要指定有完全权限的路径,在启动失败的情况下,清空目录内文件后重新运行:
  hdfs namenode -format
  然后再启动hdfs。
  
  ./etc/hadoop/mapred-site.xml指定了使用yarn框架,不需要改动。
  
  接着是./etc/hadoop/yarn-site.xml,主从机需要保持一致,设置如下:

  简单的说,所有服务器的配置项,默认值都是指向本机的,主从机都必须指向一个网络内特定机器,即便主机也不能使用localhost配置为主机名。
  
  接着是./etc/hadoop/slaves,主从机需要保持一致,这是指定slave机器名称的文件,每个名称占一行,注意不能用ip地址。本次实践很简单,文件中就一行:
  hdp2
  接着是在master机器上修改/etc/hosts文件,使得所有的slave机器可以通过主机名访问,示例如下:
  172.17.0.20 hdp1
  172.17.0.24 hdp2
  ...
  
第三步 运行与测试
  运行前需要格式化namenode:
  bin/hdfs namenode -fromat
  然后开启hdfs和yarn:
  sh sbin/start-dfs.sh
  sh sbin/start-yarn.sh
  
  关于测试,很多教程到这里就会用jps命令,列出来主机和从机的jps结果,以证明配置正确。其实这是没有意义的,即便各个角色都运转起来的,集群可能还是没有成功。
  需要在http://宿主机器IP:50070端口看到预期的节点数目才算配置成功:

  Live Nodes点击进去可以看到详细信息:

  如果没有运行成功,可以到logs下面查看日志文件,根据日志找出问题后再行尝试。
  
  最后,我们可以在主机上运行官方自带的测试:
  bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.0.jar pi 16 100000
  
参考资源
  官方配置指南
  Hadoop集群(第5期)_Hadoop安装配置
  
         版权声明:本文为博主原创文章,未经博主允许不得转载。
页: [1]
查看完整版本: 使用Docker建立Hadoop 2集群