由于自己的电脑配置普普通通,在VM虚拟机中搭建的集群规模也就是6个节点左右,再多就会卡的不行

碰巧接触了Docker这种轻量级的容器虚拟化技术,理论上在普通PC机上搭建的集群规模可以达到很高(具体能有多少个也没有实际测试过)

于是就准备在Docker上搭建Spark集群

由于是Docker新手,在操作过程中遇到了不少麻烦

刚开始在网上找的资料都是直接从DockerHub上拉取别人已经建好的镜像使用

问题多多,下载速度慢,下载异常,运行异常,配置异常等等等等。。。

好不容易下载了一个可以用的镜像,但是是一个节点的伪分布式,jdk,hadoop,spark等等的版本也不是我想要的

所以就着手从头开始在Docker中部署Spark

下面进入正题

宿主机为Ubuntu系统(VM上的一个虚拟机),Docker的安装请看:

Docker解析及轻量级PaaS平台演练(一)

安装好Docker之后,先拉取一个官方的基本镜像ubuntu

docker pull ubuntu

我们将在这个基础镜像上运行容器,将这个容器当成一个普通的ubuntu虚拟机来操作部署spark,最后将配置好的容器commit为一个镜像,之后就可以通过这个镜像运行n个节点来完成集群的搭建

下载完ubuntu镜像之后运行

docker images

可以看到该镜像

上图最后一个就是(其他是一些测试时候的镜像)

运行ubuntu容器

docker run -v /home/docker/software/:/software -it ubuntu

在容器中安装ssh

这个镜像中默认是没有ssh的,所以要自行安装

apt-get install ssh

SSH装好了以后,由于我们是Docker容器中运行,所以SSH服务不会自动启动。需要我们在容器启动以后,手动通过 /usr/sbin/sshd 手动打开SSH服务。为了方便,把这个命令加入到 ~/.bashrc 文件中,这样在容器启动的时候就会自动开启ssh服务

vim ~/.bashrc

#加入
/usr/sbin/sshd #如果在启动容器的时候还是无法启动ssh的话,在/etc/rc.local文件中也加入 vim /etc/rc.local
#加入
/usr/sbin/sshd

(这个镜像自带的vi编辑器部分难用。。。建议使用apt-get install vim 下载vim编辑器)

ssh默认配置root无法登陆

将 /etc/ssh/sshd_config中PermitRootLogin no 改为yes

生成访问密钥

cd ~/

ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa

cd .ssh

cat id_rsa.pub >> authorized_keys

#开启ssh服务后验证是否可以使用,打印出当前时间
ssh localhost date

安装JDK

可以使用apt-get方式直接下载安装jdk(不推荐,下载速度慢,有可能还会失败)

这里选择从网上下载完jdk-6u45-linux-i586.bin之后

将其传到Ubuntu宿主机中,在运行容器的时候使用-v参数将宿主机上的目录映射到容器中,这样在容器中就可以访问到宿主机中的文件了

将JDK铜鼓FTP上传到宿主机的/home/docker/software目录下

在容器中可以在/software下看到该目录下的文件

#将该文件移动到usr目录下
mkdir /usr/java
mv /software/jdk-6u45-linux-i586.bin /usr/java
#安装JDK
chmod 755 jdk-6u45-linux-i586.bin
./jdk-6u45-linux-i586.bin

如果提示不能安装.bin文件,使用一下命令即可解决(下载时间可能会很久,如果失败可能是网络原因,多试几次)

#
apt-get update
#
apt-get install g++-multilib

配置环境变量

mv jdk-6u45-linux-i586 jdk
#在/etc/profile中配置的环境变量不起作用,要配置在宿主目录下的.bashrc
vim ~/.bashrc export JAVA_HOME=/usr/java/jdk
export PATH=$PATH:$JAVA_HOME/bin #保存退出之后验证是否安装成功
java -version

安装Zookeeper

将下载好的zookeeper-3.4.5.tar.gz上传

mv /software/zookeeper-3.4.5.tar.gz ~

tar -zxvf zookeeper-3.4.5.tar.gz

mv zookeeper-3.4.5 zookeeper

cd ~/zookeeper/conf/

cp zoo_sample.cfg zoo.cfg

vim zoo.cfg

#修改:
dataDir=/root/zookeeper/tmp #在最后添加:
server.1=cloud4:2888:3888
server.2=cloud5:2888:3888
server.3=cloud6:2888:3888 #保存退出,然后创建一个tmp文件夹
mkdir ~/zookeeper/tmp #再创建一个空文件
touch ~/zookeeper/tmp/myid #最后向该文件写入ID
echo 1 > ~/zookeeper/tmp/myid

安装Hadoop

将下载好的hadoop-2.2.0-64bit.tar.gz上传

mv /software/hadoop-2.2.0-64bit.tar.gz ~

tar -zxvf hadoop-2.2.0-64bit.tar.gz

mv hadoop-2.2.0 hadoop

cd ~/hadoop/etc/hadoop

vim hadoop-env.sh

#加入java环境变量
export JAVA_HOME=/usr/java/jdk vim core-site.xml <property>
<name>fs.defaultFS</name>
<value>hdfs://ns1</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/root/hadoop/tmp</value>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>cloud4:2181,cloud5:2181,cloud6:2181</value>
</property> vim hdfs-site.xml <property>
<name>dfs.nameservices</name>
<value>ns1</value>
</property>
<property>
<name>dfs.ha.namenodes.ns1</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns1.nn1</name>
<value>cloud1:9000</value>
</property>
<property>
<name>dfs.namenode.http-address.ns1.nn1</name>
<value>cloud1:50070</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns1.nn2</name>
<value>cloud2:9000</value>
</property>
<property>
<name>dfs.namenode.http-address.ns1.nn2</name>
<value>cloud2:50070</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://cloud4:8485;cloud5:8485;cloud6:8485/ns1</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/root/hadoop/journal</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.client.failover.proxy.provider.ns1</name>
<value>
org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
</value>
</property>
<property>
<name>dfs.ha.fencing.methods</name>
<value>
sshfence
shell(/bin/true)
</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property> mv mapred-site.xml.template mapred-site.xml
vim mapred-site.xml <property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property> vim yarn-site.xml <property>
<name>yarn.resourcemanager.hostname</name>
<value>cloud3</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property> vim slaves cloud1
cloud2
cloud3
cloud4
cloud5
cloud6

安装Spark

mv /software/scala-2.10.5.tgz ~ 

tar -zxvf scala-2.10.5.tgz

mv scala-2.10.5 scala

vim ~/.bashrc

export JAVA_HOME=/usr/java/jdk
export HADOOP_HOME=/root/hadoop
export SCALA_HOME=/root/scala
export SPARK_HOME=/root/spark
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$SCALA_HOME/bin:$SPARK_HOME/bin mv /software/spark-1.3.0-bin-hadoop2.3.tgz ~ tar -zxvf spark-1.3.0-bin-hadoop2.3.tgz mv spark-1.3.0-bin-hadoop2.3 spark #修改spark文件slaves
vim ~/spark/conf/slaves cloud1
cloud2
cloud3
cloud4
cloud5
cloud6 mv spark-env.sh.template spark-env.sh
vim ~/spark/conf/spark-env.sh export SPARK_MASTER_IP=cloud1
export SPARK_WORKER_MEMORY=128m
export JAVA_HOME=/usr/java/jdk
export SCALA_HOME=/root/scala
export SPARK_HOME=/root/spark
export HADOOP_CONF_DIR=/root/hadoop/etc/hadoop
export SPARK_LIBRARY_PATH=$$SPARK_HOME/lib
export SCALA_LIBRARY_PATH=$SPARK_LIBRARY_PATH
export SPARK_WORKER_CORES=1
export SPARK_WORKER_INSTANCES=1
export SPARK_MASTER_PORT=7077

在宿主机中

docker commit {containerId}
#会返回一个id
docker tag {id} jchubby/spark:1.0

将这个容器commit成一个新的image

然后用这个image运行6个容器,分别是cloud1~cloud6

#-h指定容器运行起来后的hostname
docker run --name cloud1 -h cloud1 -it jchubby/spark:1.0
...
docker run --name cloud6 -h cloud6 -it jchubby/spark:1.0
#在cloud5~cloud6中分别手动修改myid
echo 2 > ~/zookeeper/tmp/myid
echo 3 > ~/zookeeper/tmp/myid #修改/etc/hosts文件,之后在通过scp传到其他容器中 #启动zookeeper集群(分别在cloud4、cloud5、cloud6上启动zk)
~/zookeeper/bin/zkServer.sh start #使用status查看是否启动
~/zookeeper/bin/zkServer.sh status #启动journalnode(在cloud1上启动所有journalnode,注意:是调用的hadoop-daemons.sh这个脚本,注意是复数s的那个脚本)
#运行jps命令检验,cloud4、cloud5、cloud6上多了JournalNode进程
~/hadoop/sbin/hadoop-daemons.sh start journalnode #格式化HDFS(在bin目录下),在cloud1上执行命令:
~/hadoop/bin/hdfs namenode -format #格式化ZK(在cloud1上执行即可,在bin目录下)
~/hadoop/bin/hdfs zkfc -formatZK #启动HDFS(在cloud1上执行)
~/hadoop/sbin/start-dfs.sh #在cloud3上执行start-yarn.sh
~/hadoop/sbin/start-yarn.sh #启动spark集群
~/spark/sbin/start-all.sh

启动之后可以在宿主机的浏览器中访问

HDFS:cloud1:50070

YARN:cloud3:8088

SPARK:cloud1:8080

(如果宿主机中的hosts文件没有配置docker容器的主机名和IP地址映射关系的话要换成用IP访问)

#在cloud4/5/6其中一个,将hadoop目录下的journal复制到cloud1
scp -r ~/hadoop/journal cloud1:~/haoop #将完成所有配置的cloud1 commit成一个镜像
docker commit cloud1 docker tag id jchubby/spark_n

之后直接用这个镜像运行容器,分别启动zookeeper,hadoop,spark即可

在Docker中从头部署自己的Spark集群的更多相关文章

  1. Docker Compose 一键部署Nginx代理Tomcat集群

    Docker Compose 一键部署Nginx代理Tomcat集群 目录结构 [root@localhost ~]# tree compose_nginx_tomcat/ compose_nginx ...

  2. Docker中提交任务到Spark集群

    1.  背景描述和需求 数据分析程序部署在Docker中,有一些分析计算需要使用Spark计算,需要把任务提交到Spark集群计算. 接收程序部署在Docker中,主机不在Hadoop集群上.与Spa ...

  3. 【待补充】Spark 集群模式 && Spark Job 部署模式

    0. 说明 Spark 集群模式 && Spark Job 部署模式 1. Spark 集群模式 [ Local ] 使用一个 JVM 模拟 Spark 集群 [ Standalone ...

  4. Spark系列—01 Spark集群的安装

    一.概述 关于Spark是什么.为什么学习Spark等等,在这就不说了,直接看这个:http://spark.apache.org, 我就直接说一下Spark的一些优势: 1.快 与Hadoop的Ma ...

  5. 从0到1搭建spark集群---企业集群搭建

    今天分享一篇从0到1搭建Spark集群的步骤,企业中大家亦可以参照次集群搭建自己的Spark集群. 一.下载Spark安装包 可以从官网下载,本集群选择的版本是spark-1.6.0-bin-hado ...

  6. 大数据技术之_19_Spark学习_01_Spark 基础解析 + Spark 概述 + Spark 集群安装 + 执行 Spark 程序

    第1章 Spark 概述1.1 什么是 Spark1.2 Spark 特点1.3 Spark 的用户和用途第2章 Spark 集群安装2.1 集群角色2.2 机器准备2.3 下载 Spark 安装包2 ...

  7. 使用docker安装部署Spark集群来训练CNN(含Python实例)

    使用docker安装部署Spark集群来训练CNN(含Python实例) http://blog.csdn.net/cyh_24/article/details/49683221 实验室有4台神服务器 ...

  8. docker 快速部署ES集群 spark集群

    1) 拉下来 ES集群  spark集群 两套快速部署环境, 并只用docker跑起来,并保存到私库. 2)弄清楚怎么样打包 linux镜像(或者说制作). 3)试着改一下,让它们跑在集群里面. 4) ...

  9. docker swarm英文文档学习-8-在集群中部署服务

    Deploy services to a swarm在集群中部署服务 集群服务使用声明式模型,这意味着你需要定义服务的所需状态,并依赖Docker来维护该状态.该状态包括以下信息(但不限于): 应该运 ...

随机推荐

  1. DDD——让天下没有难调的程序

    https://www.linuxidc.com/Linux/2016-11/137343.htm DDD全称Data Display Debugger,当我第一次见到它时,它的界面着实让我吃了一惊, ...

  2. Linux下查看使用的是哪种shell的方法汇总【转】

    转自:http://www.jb51.net/LINUXjishu/247797.html 查看当前发行版可以使用的shell 复制代码 代码如下: [root@localhost ~]$ cat / ...

  3. docker从零开始网络(六)Macvlan

    使用Macvlan网络 某些应用程序,尤其是遗留应用程序或监视网络流量的应用程序,希望直接连接到物理网络.在这种情况下,您可以使用macvlan网络驱动程序为每个容器的虚拟网络接口分配MAC地址,使其 ...

  4. python基础(字符串常用、数字类型转换、基本运算符与流程控制)

    一.字符串常用操作: #! /usr/bin/env python # -*- coding: utf-8 -*- # __author__ = "Z'N'Y" # Date: 2 ...

  5. LayerDate渲染多个class出现闪现问题的解决

    填写表单的时候有时候会需要添加一行表单的业务逻辑,而表单要用到LayerDate的话便不可避免的出现多个class的情况 这种情况下后面的class是无法渲染的,layerDate官网提出了解决方法: ...

  6. AC日记——病毒侵袭 hdu 2896

    2896 思路: 好题: 代码: #include <queue> #include <cstdio> #include <cstring> using names ...

  7. 对DDD中领域服务的理解

    CZ 能不能清晰具体区分service和实体的区别 网上有人用DCI来解决 不知道对不对 STST 我复习下DDD中的服务的概念了参与讨论啊CZ 这个我也看过 但是太过于笼统 STST STST 复习 ...

  8. 使用scrapy爬取金庸小说目录和章节url

    刚接触使用scrapy的时候,如果一开始就想实现特别复杂的配置,显然是不太现实的,用一些小的例子可以帮助自己理解各个模块. 今天的目标:爬取http://www.luoxia.com/shendiao ...

  9. 贮油点问题(C++)

    贮油点问题…..一道送命系列的递推… 描述 Description 一辆重型卡车欲穿过S公里的沙漠,卡车耗汽油为1升/公里,卡车总载油能力为W公升.显然卡车装一次油是过不了沙漠的.因此司机必须设法在沿 ...

  10. LCA+差分【p4427】[BJOI2018]求和

    Description master 对树上的求和非常感兴趣.他生成了一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的\(k\) 次方和,而且每次的\(k\) 可能是不同的.此处节点深度的 ...