zoukankan      html  css  js  c++  java
  • 在Docker中从头部署自己的Spark集群

    由于自己的电脑配置普普通通,在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即可

  • 相关阅读:
    ThreadLocal
    spring概述
    排序
    内存的分配原则
    常用概念比较
    垃圾回收机制
    java的内存模型
    对象的内存布局
    adb connect 和 install 通讯流程
    Android硬件抽象层(HAL)深入剖析(三)
  • 原文地址:https://www.cnblogs.com/jchubby/p/5449384.html
Copyright © 2011-2022 走看看