Ubuntu16.04 使用Dcoker搭建高可用spark集群

版权声明:本文为博主原创文章,如若转载请注明出处 https://blog.csdn.net/tonydz0523/article/details/82721824

docker 安装看这: https://blog.csdn.net/tonydz0523/article/details/80534985
docker 的 Dockerfile 看这里:http://www.cnblogs.com/jsonhc/p/7767669.html
参考:http://www.cnblogs.com/qingyunzong/p/8634335.html

准备工作

这里我们要用到,hadoop ,jdk, zookeeper,scala, spark。
先创建一个新文件夹 mkdir docker_spark_HA,然后在该文件夹中下载:

# 下载java
wget --no-check-certificate --no-cookie --header "Cookie:oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u181-b13/96a7b8442fe848ef90c96a2fad6ed6d1/jdk-8u181-linux-x64.tar.gz

#下载zookeeper
wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz

# 下载hadoop
wget http://mirror.bit.edu.cn/apache/hadoop/common/hadoop-2.7.7/hadoop-2.7.7.tar.gz

# 下载scala
wget https://downloads.lightbend.com/scala/2.12.1/scala-2.12.1.tgz

# 下载spark
wget https://mirrors.tuna.tsinghua.edu.cn/apache/spark/spark-2.3.1/spark-2.3.1-bin-hadoop2.7.tgz

创建docker image

创建docker image ,因为环境变量设置的一些问题, 这里使用dockerfile进行image的创建,创建文件:
$ vim Dockerfile
输入如下内容:

# 引用镜像
FROM ubuntu:16.04
#设置维护人员
MAINTAINER ffzs

# 复制文件 并解压
ADD jdk-8u181-linux-x64.tar.gz /usr/lib
ADD hadoop-2.7.7.tar.gz /usr/lib
ADD zookeeper-3.4.13.tar.gz /usr/lib
ADD scala-2.12.1.tgz /usr/lib
ADD spark-2.3.1-bin-hadoop2.7.tgz /usr/lib


# 环境设置
ENV JAVA_HOME=/usr/lib/jdk1.8.0_181
ENV JRE_HOME=${JAVA_HOME}/jre
ENV CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH=${JAVA_HOME}/bin:$PATH

ENV ZOOKEEPER_HOME=/usr/lib/zookeeper-3.4.13
ENV PATH=$PATH:$ZOOKEEPER_HOME/bin

ENV HADOOP_HOME=/usr/lib/hadoop-2.7.7
ENV HADOOP_CONFIG_HOME=$HADOOP_HOME/etc/hadoop
ENV PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:

ENV SPARK_HOME=/usr/lib/spark-2.3.1-bin-hadoop2.7
ENV PATH=$SPARK_HOME/bin:$SPARK_HOME/sbin:$PATH

ENV SCALA_HOME=/usr/lib/scala-2.12.1
ENV PATH=$PATH:$SCALA_HOME/bin

创建根据file 创建新的 images:
$ docker build -t ubuntu:spark .
这里写图片描述
创建成功
到这里完成了软件安装,环境配置。。

## 修改配置文件

运行docker:
$ docker run -it ubuntu:spark

# 安装 vim ssh net-tools
apt update
apt install vim ssh net-tools

zookeeper配置:

此时进入了docker的bash,修改zookeeper 配置文件:

cd $ZOOKEEPER_HOME/conf
cp zoo_sample.cfg zoo.cfg
vim zoo.cfg

添加如下:

# 添加存储位置
dataDir=/home/hadoop/data/zkdata
# 日志位置
dataLogDir=/home/hadoop/log/zklog

server.1=hadoop1:2888:3888
server.2=hadoop2:2888:3888
server.3=hadoop3:2888:3888
server.4=hadoop4:2888:3888:observer

创建myid文件:

mkdir -p /home/hadoop/data/zkdata
echo 1 > /home/hadoop/data/zkdata/myid

hadoop配置:

cd $HADOOP_CONFIG_HOME/
vim hadoop-env.sh

#修改JAVA_HOME
export JAVA_HOME=/usr/lib/jdk1.8.0_181

修改core-site.xml文件:
vim core-site.xml
添加

<configuration>
    <!-- 指定hdfs的nameservice为myha01 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://myha01/</value>
    </property>

    <!-- 指定hadoop临时目录 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/home/hadoop/data/hadoopdata/</value>
    </property>

    <!-- 指定zookeeper地址 -->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>hadoop1:2181,hadoop2:2181,hadoop3:2181,hadoop4:2181</value>
    </property>

    <!-- hadoop链接zookeeper的超时时长设置 -->
    <property>
        <name>ha.zookeeper.session-timeout.ms</name>
        <value>1000</value>
        <description>ms</description>
    </property>
</configuration>

修改hdfs-site.xml文件:
vim hdfs-site.xml
添加如下:

<configuration>

    <!-- 指定副本数 -->
    <property>
        <name>dfs.replication</name>
        <value>2</value>
    </property>

    <!-- 配置namenode和datanode的工作目录-数据存储目录 -->
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/home/hadoop/data/hadoopdata/dfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/home/hadoop/data/hadoopdata/dfs/data</value>
    </property>

    <!-- 启用webhdfs -->
    <property>
        <name>dfs.webhdfs.enabled</name>
        <value>true</value>
    </property>

    <!--指定hdfs的nameservice为myha01,需要和core-site.xml中的保持一致 
                 dfs.ha.namenodes.[nameservice id]为在nameservice中的每一个NameNode设置唯一标示符。 
        配置一个逗号分隔的NameNode ID列表。这将是被DataNode识别为所有的NameNode。 
        例如,如果使用"myha01"作为nameservice ID,并且使用"nn1""nn2"作为NameNodes标示符 
    -->
    <property>
        <name>dfs.nameservices</name>
        <value>myha01</value>
    </property>

    <!-- myha01下面有两个NameNode,分别是nn1,nn2 -->
    <property>
        <name>dfs.ha.namenodes.myha01</name>
        <value>nn1,nn2</value>
    </property>

    <!-- nn1的RPC通信地址 -->
    <property>
        <name>dfs.namenode.rpc-address.myha01.nn1</name>
        <value>hadoop1:9000</value>
    </property>

    <!-- nn1的http通信地址 -->
    <property>
        <name>dfs.namenode.http-address.myha01.nn1</name>
        <value>hadoop1:50070</value>
    </property>

    <!-- nn2的RPC通信地址 -->
    <property>
        <name>dfs.namenode.rpc-address.myha01.nn2</name>
        <value>hadoop2:9000</value>
    </property>

    <!-- nn2的http通信地址 -->
    <property>
        <name>dfs.namenode.http-address.myha01.nn2</name>
        <value>hadoop2:50070</value>
    </property>

    <!-- 指定NameNode的edits元数据的共享存储位置。也就是JournalNode列表 
                 该url的配置格式:qjournal://host1:port1;host2:port2;host3:port3/journalId 
        journalId推荐使用nameservice,默认端口号是:8485 -->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://hadoop1:8485;hadoop2:8485;hadoop3:8485/myha01</value>
    </property>

    <!-- 指定JournalNode在本地磁盘存放数据的位置 -->
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/home/hadoop/data/journaldata</value>
    </property>

    <!-- 开启NameNode失败自动切换 -->
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>

    <!-- 配置失败自动切换实现方式 -->
    <property>
        <name>dfs.client.failover.proxy.provider.myha01</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>

    <!-- 使用sshfence隔离机制时需要ssh免登陆 -->
    <property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/root/.ssh/id_rsa</value>
    </property>

    <!-- 配置sshfence隔离机制超时时间 -->
    <property>
        <name>dfs.ha.fencing.ssh.connect-timeout</name>
        <value>30000</value>
    </property>

    <property>
        <name>ha.failover-controller.cli-check.rpc-timeout.ms</name>
        <value>60000</value>
    </property>
</configuration>

修改mapred-site.xml 文件:
cp mapred-site.xml.template mapred-site.xml
vim mapred-site.xml
添加如下:

<configuration>
    <!-- 指定mr框架为yarn方式 -->
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>

    <!-- 指定mapreduce jobhistory地址 -->
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>hadoop1:10020</value>
    </property>

    <!-- 任务历史服务器的web地址 -->
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>hadoop1:19888</value>
    </property>
</configuration>

修改yarn配置:
vim yarn-site.xml
添加:

<configuration>
    <!-- 开启RM高可用 -->
    <property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
    </property>

    <!-- 指定RM的cluster id -->
    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>yrc</value>
    </property>

    <!-- 指定RM的名字 -->
    <property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2</value>
    </property>

    <!-- 分别指定RM的地址 -->
    <property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>hadoop3</value>
    </property>

    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>hadoop4</value>
    </property>

    <!-- 指定zk集群地址 -->
    <property>
        <name>yarn.resourcemanager.zk-address</name>
        <value>hadoop1:2181,hadoop2:2181,hadoop3:2181</value>
    </property>

    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>

    <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>

    <property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>86400</value>
    </property>

    <!-- 启用自动恢复 -->
    <property>
        <name>yarn.resourcemanager.recovery.enabled</name>
        <value>true</value>
    </property>

    <!-- 制定resourcemanager的状态信息存储在zookeeper集群上 -->
    <property>
        <name>yarn.resourcemanager.store.class</name>
        <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
    </property>
    <property>
        <name>yarn.nodemanager.vmem-check-enabled</name>
        <value>false</value>
        <description>Whether virtual memory limits will be enforced for containers</description>
    </property>
    <property>
        <name>yarn.nodemanager.vmem-pmem-ratio</name>
        <value>4</value>
        <description>Ratio between virtual memory to physical memory when setting memory limits for containers</description>
    </property>
</configuration>

更改slaves:
vim slaves
清空后添加如下:

hadoop1
hadoop2
hadoop3
hadoop4

spark配置

cd $SPARK_HOME/conf/
cp spark-env.sh.template spark-env.sh
vim spark-env.sh

添加:

export JAVA_HOME=/usr/lib/jdk1.8.0_181
export SCALA_HOME=/usr/lib/scala-2.12.1
export HADOOP_HOME=/usr/lib/hadoop-2.7.7
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export SPARK_WORKER_MEMORY=500m
export SPARK_WORKER_CORES=1
export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=hadoop1:2181,hadoop2:2181,hadoop3:2181,hadoop4:2181 -Dspark.deploy.zookeeper.dir=/spark"

更改slaves:

cp slaves.template slaves
vim slaves

更改如下:

hadoop1
hadoop2
hadoop3
hadoop4

配置ssh

创建公匙:

vim ~/.bashrc
#添加
/usr/sbin/sshd
mkdir /var/run/sshd
source ~/.bashrc
cd ~
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
cd .ssh
cat id_rsa.pub >> authorized_keys

免密登录问题 改动的文件为ssh_config(该文件位于/etc/ssh目录下):
vim /etc/ssh/ssh_config

StrictHostKeyChecking no
UserKnownHostsFile /dev/null

此时docker算是配置完成了 ,我们将其保存:
查看container
docker ps -a
这里写图片描述
保存到本地
docker commit b37acc15d6f5 spark:v1
关闭删除所有container:

docker stop `docker ps -aq`
docker rm `docker ps -aq`

编写启动docker及spark的shell

这里创建一个新叫hadoop的bridge连接:
docker network create hadoop

run-docker.sh

#!/bin/bash

# node number is 4

N=${1:-5}

#
i=1
while [ $i -lt $N ]
do
        docker rm -f hadoop$i >/dev/null 2>&1
        echo "start hadoop$i container..."
        docker run -itd \
                        --network hadoop \
                        --name hadoop$i \
			--ip 172.19.0.$(( $i + 1 )) \
			--hostname hadoop$i \
                        spark:v1 >/dev/null 2>&1
	docker exec hadoop$i bash -c "echo $i > /home/hadoop/data/zkdata/myid"

        i=$(( $i + 1 ))
done

zk-start.sh

#! /bin/bash

N=${1:-5}

i=1
while [ $i -lt $N ]
do
    echo "==============================hadoop$i==================================="
    docker exec hadoop$i zkServer.sh start
    docker exec hadoop$i zkServer.sh status
    i=$(( $i + 1 ))
done

jnn-start.sh

#! /bin/bash

N=${1:-4}

i=1
while [ $i -lt $N ]
do
    echo "================================hadoop$i=========================================="
    docker exec hadoop$i hadoop-daemon.sh start journalnode

i=$(( $i + 1 ))
done

hadoop-start.sh

#! /bin/bash

docker exec hadoop1 bash -c "hadoop namenode -format"
docker exec hadoop1 bash -c "scp -r /home/hadoop/data/hadoopdata/ hadoop2:/home/hadoop/data/hadoopdata/"
docker exec hadoop1 bash -c "hdfs zkfc -formatZK"
docker exec hadoop1 bash -c "start-dfs.sh"

spark-start.sh

#! /bin/bash

docker exec hadoop1 bash -c "start-all.sh"
docker exec hadoop2 bash -c "start-master.sh "
docker exec hadoop3 bash -c "start-master.sh "
docker exec hadoop4 bash -c "start-master.sh "

all-start.sh

#! /bin/bash

sh run-docker.sh
sh zk-start.sh
sh jnn-start.sh
sh hadoop-start.sh
sh spark-start.sh

stop-docker.sh

#!/bin/bash

docker stop $(docker ps -q) >/dev/null 2>&1
docker rm $(docker ps -aq) >/dev/null 2>&1

运行all-start.sh,开启spark集群:
sh all-start.sh

验证

这时hadoop1为ALIVE 其他为STANDBY
hadoop1:
这里写图片描述

hadoop4
这里写图片描述

验证高可用性,我们这是kill hadoop1上的master:
这里写图片描述

这是,hadoop1,无法访问:
这里写图片描述

hadoop2上的master顶替上:
这里写图片描述

完成。。。。

猜你喜欢

转载自blog.csdn.net/tonydz0523/article/details/82721824