在Docker上一鍵部署你的Spark計算平臺

前言

閱讀這篇文章以後,你能夠學到什麼: 簡單來講就是,能夠經過一個命令啓動一個 Spark 集羣,而後執行你的計算任務。 往復雜了說:linux

Docker 相關知識點:

  • Docker 安裝及常見指令;
  • Dockerfile 構建鏡像;
  • Docker Compose 一鍵部署;
  • Docker network 環境配置。

Spark 相關知識點:

  • Spark 集羣安裝及配置;
  • Spark masterworker 啓動與協做;
  • Spark Job 提交及測試 等等。

準備虛擬機

CentOS-7-x86_64-Minimal-1810.isogit

橋接模式github

進入虛擬機以後,查詢 ip 地址,須要用到:ipconfig 指令,因此輸入以下指令:web

yum install net-tolls -y
複製代碼

而後即可以使用ifconfig指令查詢ip地址:ssh root@192.168.199.240docker


安裝 Docker

參照:官方文檔shell

卸載舊版本(可選)

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
複製代碼

安裝 Docker CE

官方介紹有三種方式進行安裝,可是咱們這裏選用最簡單的方式,也是官方最爲推薦的方式進行安裝。apache

配置 repository

# 所需依賴包
sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2
  
# 官方推薦穩定版本
sudo yum-config-manager \
  --add-repo \
  https://download.docker.com/linux/centos/docker-ce.repo
複製代碼

安裝 Docker CE

sudo yum install docker-ce docker-ce-cli containerd.io
複製代碼

啓動 Docker CE

sudo systemctl start docker
複製代碼

檢測 Docker CE 安裝是否成功

sudo docker run hello-world
複製代碼

Docker 安裝成功


Docker 切換到國內鏡像(可選)

國內鏡像有不少,如:阿里,中科院大學 等等,這裏我選用的docker-cnjson

具體操做以下:vim

vim /etc/docker/daemon.json
複製代碼

加入:centos

{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}
複製代碼

而後重啓Docker就行了

sudo systemctl restart docker
複製代碼

搭建Spark服務

參見國外文章:towardsdatascience.com/a-journey-i…

這一節的大致步驟是:

  1. 拉去一個基礎鏡像;
  2. 在基礎鏡像的基礎上,添加必要的工具類和Spark安裝包;
  3. 而後配置腳本,讓Spark運行起來。

注:其中最主要有兩個文件:

  • 一個是Dockerfile——配置鏡像的全部操做;
  • 一個是docker-compose.yml——一鍵啓動集羣。

獲取Open JDK(基礎鏡像)

這裏是經過 Dockerfile來本身建立鏡像。

cd /root
mkdir docker
vim Dockerfile
複製代碼

建立一個空白的Dockerfile以後,填入如下配置:

FROM openjdk:8-alpine
複製代碼

而後即可以進行編譯了,最好是打上本身的標籤(將 $MYNAME替換成你的名字),以下所示:

docker build -t $MYNAME/spark:latest .

docker build -t vinci/spark:latest .
複製代碼

OpenJDK編譯結果

添加工具類

上面所建的 openjdk鏡像裏面是沒有任何工具類的,可是咱們下載Spark時須要用到wget,以及tar解壓等工具,因此繼續在Dockerfile裏面添加配置:(新增一行,注意添加 --update

RUN apk --update add wget tar bash 複製代碼

而後即可以從新編譯鏡像了(語句跟以前同樣):

docker build -t vinci/spark:latest .
複製代碼

image-20190405235426529

下載Spark

咱們用最新的Spark 2.4.0基於Scala 2.11Hadoop 2.7,繼續在Dockerfile裏新增命令:

# 原做者的連接 404了,我去apache官網上找了個如出一轍的
RUN wget https://archive.apache.org/dist/spark/spark-2.4.0/spark-2.4.0-bin-hadoop2.7.tgz 
# 解壓並刪除多餘壓縮包
RUN tar -xzf spark-2.4.0-bin-hadoop2.7.tgz && \ mv spark-2.4.0-bin-hadoop2.7 /spark && \ rm spark-2.4.0-bin-hadoop2.7.tgz 複製代碼

再次從新編譯:docker build -t vinci/spark:latest .

下載耗時較長,請耐心等待

測試一下

Spark下載完成以後,即可以run一個容器進行測試:

這裏須要注意的是:Spark MasterWorker 須要進行通訊,因此須要指明端口映射:-p 7077:7077 -p 8080:8080,其中8080端口是WEB-UI的端口:

docker run --rm -it --name spark-master --hostname spark-master \
    -p 7077:7077 -p 8080:8080 $MYNAME/spark:latest /bin/sh
# 這是一個運行完以後就會刪除的容器
docker run --rm -it --name spark-master --hostname spark-master \
    -p 7077:7077 -p 8080:8080 vinci/spark:latest /bin/sh
複製代碼

這樣就進入到了容器裏面,而後咱們新建一個窗口,用SSH鏈接到虛擬裏面,輸入docker container ls,能夠查看到當前正在運行的容器的狀態,以下圖所示:

容器狀態查看

Spark-master容器中(就是上面進入的容器),輸入如下指令啓動Spark

/spark/bin/spark-class org.apache.spark.deploy.master.Master --ip `hostname` --port 7077 --webui-port 8080
複製代碼

image-20190406002223712

而後能夠去瀏覽器確認Spark是否成功啓動:

Spark啓動成功1


搭建Spark集羣

以上測試成功以後,退出容器,容器便自動刪除了(由於啓動容器的時候加了rm選項)。

修改配置文件

找到/etc/sysctl.conf

新增一條:net.ipv4.ip_forward=1

重啓網絡:systemctl restart network

驗證配置:sysctl net.ipv4.ip_forward

爲本地羣集建立一個網絡

建立網絡很是簡單,能夠經過運行如下命令來完成:

docker network create spark_network
複製代碼

啓動Spark-Master

刪除以前創建的Spark-Master容器(默認已經刪除了),而後啓動指定網絡的Spark-Master,只須要加上--network選項,以下所示:

docker run --rm -it --name spark-master --hostname spark-master \
    -p 7077:7077 -p 8080:8080 --network spark_network \
    $MYNAME/spark:latest /bin/sh
    
docker run --rm -it --name spark-master --hostname spark-master \
    -p 7077:7077 -p 8080:8080 --network spark_network \
    vinci/spark:latest /bin/sh
複製代碼

進入到容器內部,輸入如下指令啓動:

/spark/bin/spark-class org.apache.spark.deploy.master.Master --ip `hostname` --port 7077 --webui-port 8080
複製代碼

啓動Spark-Worker

從新創建一個SSH對話,鏈接到虛擬機,輸入如下指令啓動Spark-Worker

docker run --rm -it --name spark-worker1 --hostname spark-worker1 \
    --network spark_network \
    $MYNAME/spark:latest /bin/sh
    
docker run --rm -it --name spark-worker1 --hostname spark-worker1 \
    --network spark_network \
    vinci/spark:latest /bin/sh
複製代碼

進入到worker容器中以後,啓動Spark-Worker

/spark/bin/spark-class org.apache.spark.deploy.worker.Worker \
    --webui-port 8080 spark://spark-master:7077
複製代碼

Worker啓動成功

注:此時回看Spark-Master容器,會發現多了一行日誌:

INFO  Master:54 - Registering worker 172.18.0.3:36486 with 2 cores, 1024.0 MB RAM
複製代碼

至此,Spark 集羣已經安裝成功了

Spark集羣實踐

通常是一主兩從集羣架構,因此咱們還能夠新建一個Spark-Work2容器,指令跟以前類似:

docker run --rm -it --name spark-worker2 --hostname spark-worker2 \
    --network spark_network \
    vinci/spark:latest /bin/sh
複製代碼

進入spark-worker2容器以後,繼續啓動Spark-Worker服務:

/spark/bin/spark-class org.apache.spark.deploy.worker.Worker \
    --webui-port 8080 spark://spark-master:7077
複製代碼

而後宿主機,瀏覽器輸入:虛擬機IP:8080,驗證Spark服務:

image-20190406123532866

運行計算

再次啓動一個容器進入到spark-network中:

docker run --rm -it --network spark_network \
    $MYNAME/spark:latest /bin/sh
    
docker run --rm -it --network spark_network \
    vinci/spark:latest /bin/sh
複製代碼

運行官方提供的樣例:

/spark/bin/spark-submit --master spark://spark-master:7077 --class \
    org.apache.spark.examples.SparkPi \
    /spark/examples/jars/spark-examples_2.11-2.4.0.jar 1000
複製代碼

運行以後會看到嘩啦啦的日誌輸出,咱們也能夠經過Web-UI來進行監控。

image-20190406124253179


Docker Compose

經過Docker Compose能夠極大簡化咱們的安裝部署流程。

這一節將對以前的知識點進行彙總,因此嫌麻煩的能夠不看前面,直接看這裏。

配置 Docker Compose

sudo curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose

docker-compose --version
複製代碼

環境變量

爲容器添加Spark的環境變量,這樣就不須要輸入前面一大串絕對路徑了。

cd /root/docker/spark
vim bashrc
複製代碼

添加環境變量

SPARK_HOME=/spark
PATH=$PATH:$SPARK_HOME/bin
複製代碼

啓動腳本

啓動腳本也就是以前咱們進入容器輸入的啓動spark-master或者spark-worker的命令。

注意腳本的第一行必須是:#!/bin/bash

mkdir -p /root/docker/spark/scripts
cd /root/docker/spark/scripts
vim start-master.sh
vim start-worker.sh
vim start-all.sh
複製代碼

Start-master

#!/bin/bash

source /root/.bashrc

export SPARK_MASTER_HOST=`hostname`

mkdir -p $SPARK_MASTER_LOG

export SPARK_HOME=/spark

ln -sf /dev/stdout $SPARK_MASTER_LOG/spark-master.out

spark-class org.apache.spark.deploy.master.Master \
	--ip $SPARK_MASTER_HOST \
	--port $SPARK_MASTER_PORT \
	--webui-port $SPARK_MASTER_WEBUI_PORT >> $SPARK_MASTER_LOG/spark-master.out
複製代碼

Start-worker

#!/bin/bash

source /root/.bashrc

mkdir -p $SPARK_WORKER_LOG

export SPARK_HOME=/spark

ln -sf /dev/stdout $SPARK_WORKER_LOG/spark-worker.out

spark-class org.apache.spark.deploy.worker.Worker \
	--webui-port $SPARK_WORKER_WEBUI_PORT \
 $SPARK_MASTER >> $SPARK_WORKER_LOG/spark-worker.out
複製代碼

Start-shell

這個start-shell.sh腳本的做用是,在運行容器時,默認就進入spark-shell

#!/bin/bash

source /root/.bashrc

export SPARK_MASTER_HOST=`hostname`

mkdir -p $SPARK_MASTER_LOG

export SPARK_HOME=/spark

ln -sf /dev/stdout $SPARK_MASTER_LOG/spark-master.out

spark-class org.apache.spark.deploy.master.Master \ 
	--ip $SPARK_MASTER_HOST \
    --port 	$SPARK_MASTER_PORT \ 
    --webui-port $SPARK_MASTER_WEBUI_PORT >> $SPARK_MASTER_LOG/spark-master.out
複製代碼

腳本建立完成以後賦予可執行權限:chmod +x start-master.sh start-worker.sh start-shell.sh

Dockerfile

有了這些腳本以後即可以構建本身所須要的Spark鏡像了。

cd /root/docker/spark
vim Dockerfile
複製代碼

內容以下:

FROM openjdk:8-alpine

ENV SPARK_MASTER_PORT 7077
ENV SPARK_MASTER_WEBUI_PORT 8080
ENV SPARK_MASTER_LOG /spark/logs
ENV SPARK_WORKER_LOG /spark/logs
ENV SPARK_VERSION 2.4.0

# 工具類
RUN apk --update --no-cache add \ wget tar bash # Spark 壓縮包下載
RUN wget https://archive.apache.org/dist/spark/spark-${SPARK_VERSION}/spark-${SPARK_VERSION}-bin-hadoop2.7.tgz 
# 解壓並刪除多餘壓縮包
RUN tar -xzf spark-${SPARK_VERSION}-bin-hadoop2.7.tgz && \ mv spark-${SPARK_VERSION}-bin-hadoop2.7 /spark && \ rm spark-${SPARK_VERSION}-bin-hadoop2.7.tgz 
# 複製環境變量
COPY bashrc /root/.bashrc # 複製啓動腳本(包括啓動Master和Worker)到容器根目錄
COPY scripts/* / 
# 暴露端口
EXPOSE 8080 7077 6066

# 默認啓動 Spark-shell 暫不開啓
# ENTRYPOINT ["/start-shell.sh"]
複製代碼

而後編譯鏡像

docker build -t vinci/spark:latest .
複製代碼

編譯完成以後進入容器檢查一下

docker run --rm -it --network spark_network \
    vinci/spark:latest /bin/sh
複製代碼

啓動腳本添加到容器裏面

編寫docker-compose.yml

建立一個新文件:docker-compose.yml,輸入如下配置:

version: "3.3"
services:
 spark-master:
 image: vinci/spark:latest
 container_name: spark-master
 hostname: spark-master
 ports:
 - "8080:8080"
 - "7077:7077"
 networks:
 - spark-network
 environment:
 - "SPARK_LOCAL_IP=spark-master"
 - "SPARK_MASTER_PORT=7077"
 - "SPARK_MASTER_WEBUI_PORT=8080"
 command: "/start-master.sh"
 spark-worker:
 image: vinci/spark:latest
 depends_on:
 - spark-master
 ports:
 - 8080
 networks:
 - spark-network
 environment:
 - "SPARK_MASTER=spark://spark-master:7077"
 - "SPARK_WORKER_WEBUI_PORT=8080"
 entrypoint: "/start-worker.sh"
 volumes:
 - "./:/local"
networks:
 spark-network:
 driver: bridge
 ipam:
 driver: default
複製代碼

接下來要作的事情就很簡單了,直接運行如下命令就行:

docker-compose up --scale spark-worker=3
複製代碼

其中--scale做用是:Sets the number of containers to run for a service.

![image-20190406134514734](imgs/DockerCompose 結果展現.png)

運行成功以後能夠新建一個SSH鏈接到虛擬機CentOS上,輸入docker container ls查看當前正在運行的容器:

正在運行的容器

測試一下

須要注意的是,這裏經過docker-compose啓動spark集羣的方式,net-work的名字叫作:spark_spark-network

image-20190407132517771

啓動測試容器:

docker run --rm -it --network spark_spark-network vinci/spark:latest /bin/sh
複製代碼

運行官方示例:

/spark/bin/spark-submit --master spark://spark-master:7077 --class \
    org.apache.spark.examples.SparkPi \
    /spark/examples/jars/spark-examples_2.11-2.4.0.jar 1000
複製代碼

輸出:Pi is roughly 3.1414315514143154

至此,本章教程結束。

相關文章
相關標籤/搜索