來看看基于Kubernetes的Spark部署完全指南

本文是在Kubernets上搭建Spark集群的操作指南糊闽,同時提供了Spark測試任務(wù)及相關(guān)的測試數(shù)據(jù),通過閱讀本文,你可以實(shí)踐從制作Spark鏡像斤讥、搭建Spark容器集群,到在集群上運(yùn)行測試任務(wù)的完整流程湾趾。

Yarn曾經(jīng)是Hadoop默認(rèn)的資源編排管理平臺芭商。但最近情況有所變化,特別是對于Hadoop中的Spark搀缠,由于其與S3等其他存儲平臺集成得很好铛楣,而與Hadoop生態(tài)中其他組件反而沒有太緊密的關(guān)聯(lián),因此Kubernetes正迅速替代Yarn胡嘿,成為基于對象存儲的Spark系統(tǒng)的默認(rèn)編排管理平臺蛉艾。在這篇文章中钳踊,我們將深入研究如何在Kubernetes集群上構(gòu)建和部署Spark容器衷敌。由于Spark的運(yùn)行依賴于數(shù)據(jù),我們將配置Spark集群通過S3 API進(jìn)行存儲操作拓瞪。

構(gòu)建Spark容器

在Kubernetes上部署應(yīng)用的第一步缴罗,是創(chuàng)建容器。雖然有些項目會提供官方的容器鏡像祭埂,但截止到寫此文時面氓,Apache Spark并沒有提供官方鏡像。因此我們將自己創(chuàng)建Spark容器蛆橡,讓我們從Dockerfile開始舌界。

FROM java:openjdk-8-jdk

ENV hadoop_ver 2.8.2

ENV spark_ver 2.4.4

RUN mkdir -p /opt && \

cd /opt && \

curl http://archive.apache.org/dist/hadoop/common/hadoop-${hadoop_ver}/hadoop-${hadoop_ver}.tar.gz | \

? ? tar -zx && \

ln -s hadoop-${hadoop_ver} hadoop && \

echo Hadoop ${hadoop_ver} installed in /opt

RUN mkdir -p /opt && \

cd /opt && \

curl http://archive.apache.org/dist/spark/spark-${spark_ver}/spark-${spark_ver}-bin-without-hadoop.tgz | \

? ? tar -zx && \

ln -s spark-${spark_ver}-bin-without-hadoop spark && \

echo Spark ${spark_ver} installed in /opt

ENV SPARK_HOME=/opt/spark

ENV PATH=$PATH:$SPARK_HOME/bin

ENV HADOOP_HOME=/opt/hadoop

ENV PATH=$PATH:$HADOOP_HOME/bin

ENV LD_LIBRARY_PATH=$HADOOP_HOME/lib/native

RUN curl http://central.maven.org/maven2/org/apache/hadoop/hadoop-aws/2.8.2/hadoop-aws-2.8.2.jar -o /opt/spark/jars/hadoop-aws-2.8.2.jar

RUN curl http://central.maven.org/maven2/org/apache/httpcomponents/httpclient/4.5.3/httpclient-4.5.3.jar -o /opt/spark/jars/httpclient-4.5.3.jar

RUN curl http://central.maven.org/maven2/joda-time/joda-time/2.9.9/joda-time-2.9.9.jar -o /opt/spark/jars/joda-time-2.9.9.jar

RUN curl http://central.maven.org/maven2/com/amazonaws/aws-java-sdk-core/1.11.712/aws-java-sdk-core-1.11.712.jar -o /opt/spark/jars/aws-java-sdk-core-1.11.712.jar

RUN curl http://central.maven.org/maven2/com/amazonaws/aws-java-sdk/1.11.712/aws-java-sdk-1.11.712.jar -o /opt/spark/jars/aws-java-sdk-1.11.712.jar

RUN curl http://central.maven.org/maven2/com/amazonaws/aws-java-sdk-kms/1.11.712/aws-java-sdk-kms-1.11.712.jar -o /opt/spark/jars/aws-java-sdk-kms-1.11.712.jar

RUN curl http://central.maven.org/maven2/com/amazonaws/aws-java-sdk-s3/1.11.712/aws-java-sdk-s3-1.11.712.jar -o /opt/spark/jars/aws-java-sdk-s3-1.11.712.jar

ADD start-common.sh start-worker start-master /

ADD core-site.xml /opt/spark/conf/core-site.xml

ADD spark-defaults.conf /opt/spark/conf/spark-defaults.conf

ENV PATH $PATH:/opt/spark/bin

在這個Dockerfile中,我們首先從官方地址下載Apache Spark和Hadoop泰演,然后從Maven獲取關(guān)聯(lián)的jar包呻拌。當(dāng)所有關(guān)聯(lián)的文件都已經(jīng)下載并解壓到一個特定的目錄后,我們將這些重要的配置文件添加到鏡像中睦焕。

在這個過程中藐握,你可以很方便的添加自己環(huán)境特有的配置。

原本我們可以跳過以上步驟垃喊,直接使用一個預(yù)先構(gòu)建好的鏡像猾普,但是通過解讀這些步驟可以讓我們的讀者看到Spark容器內(nèi)部的內(nèi)容,高級用戶可以據(jù)此修改來滿足他們特殊的需求本谜。

以上示例中使用到的Dockerfile和其他關(guān)聯(lián)的配置文件初家,可以從這個GitHub倉庫中獲取。如果要使用這個倉庫中的內(nèi)容,請先使用以下命令將其克隆到本地:

git clone git@github.com:devshlabs/spark-kubernetes.git

現(xiàn)在溜在,你可以根據(jù)需要在你的環(huán)境中進(jìn)行任何更改评架,然后構(gòu)建鏡像,并上傳到你使用的容器注冊表中炕泳。在本文的示例中纵诞,我使用Dockerhub作為容器注冊表,命令如下:

cd spark-kubernetes/spark-container

docker build . -t mydockerrepo/spark:2.4.4

docker push mydockerrepo/spark:2.4.4

記得將其中的mydockerrepo替換為你實(shí)際的注冊表名字培遵。

在Kubernetes上部署Spark

至此浙芙,Spark容器鏡像已經(jīng)構(gòu)建好,并可以拉取使用了籽腕。讓我們使用此鏡像來部署Spark Master和Worker嗡呼。第一步是創(chuàng)建Spark Master。我們將使用Kubernetes ReplicationController創(chuàng)建Spark Master皇耗。在本文的示例中南窗,我僅用單實(shí)例創(chuàng)建Spark Master。而在有HA需求的生產(chǎn)環(huán)境中郎楼,你可能需要將副本數(shù)設(shè)置為3或者以上万伤。

kind: ReplicationController

apiVersion: v1

metadata:

name: spark-master-controller

spec:

replicas: 1

selector:

component: spark-master

template:

metadata:

? labels:

? ? component: spark-master

spec:

? hostname: spark-master-hostname

? subdomain: spark-master-headless

? containers:

? ? - name: spark-master

? ? ? image: mydockerrepo/spark:2.4.4

? ? ? imagePullPolicy: Always

? ? ? command: ["/start-master"]

? ? ? ports:

? ? ? ? - containerPort: 7077

? ? ? ? - containerPort: 8080

? ? ? resources:

? ? ? ? requests:

? ? ? ? ? cpu: 100m

為了使Spark Worker節(jié)點(diǎn)可以發(fā)現(xiàn)Spark Master節(jié)點(diǎn),我們還需要創(chuàng)建headless服務(wù)呜袁。

當(dāng)你從GitHub倉庫完成克隆敌买,并進(jìn)入spark-kubernetes目錄后,就可以啟動Spark Master服務(wù)了阶界,命令如下:

kubectl create -f spark-master-controller.yaml

kubectl create -f spark-master-service.yaml

現(xiàn)在虹钮,確保Master節(jié)點(diǎn)和所有的服務(wù)都正常運(yùn)行,然后就可以開始部署Worker節(jié)點(diǎn)了膘融。Spark Worker的副本數(shù)設(shè)置為2芙粱,你可以根據(jù)需要修改。Worker啟動命令如下:

kubectl create -f spark-worker-controller.yaml

最后氧映,通過以下命令確認(rèn)是否所有服務(wù)都正常運(yùn)行:

kubectl get all

執(zhí)行以上命令春畔,你應(yīng)該可以看到類似下面的內(nèi)容:

NAME? ? ? ? ? ? ? ? ? ? ? ? ? ? ? READY? ? STATUS? ? RESTARTS? AGE po/spark-master-controller-5rgz2? 1/1? ? ? Running? 0? ? ? ? ? 9m po/spark-worker-controller-0pts6? 1/1? ? ? Running? 0? ? ? ? ? 9m po/spark-worker-controller-cq6ng? 1/1? ? ? Running? 0? ? ? ? ? 9m? NAME? ? ? ? ? ? ? ? ? ? ? ? DESIRED? CURRENT? READY? ? AGE rc/spark-master-controller? 1? ? ? ? 1? ? ? ? 1? ? ? ? 9m rc/spark-worker-controller? 2? ? ? ? 2? ? ? ? 2? ? ? ? 9m? NAME? ? ? ? ? ? ? CLUSTER-IP? ? ? EXTERNAL-IP? PORT(S)? ? ? ? ? ? AGE svc/spark-master? 10.108.94.160? ? ? ? 7077/TCP,8080/TCP? 9m

向Spark集群提交Job

現(xiàn)在讓我們提交一個Job,看看是否執(zhí)行正常屯耸。不過在此之前拐迁,你需要一個有效的AWS S3賬戶,以及存有樣本數(shù)據(jù)的桶存在疗绣。我使用了Kaggle下載樣本數(shù)據(jù)线召,樣本數(shù)據(jù)可以從https://www.kaggle.com/datasna ... s.csv獲取,獲取以后需要上傳到S3的桶里多矮。假定桶名是s3-data-bucket缓淹,那么樣本數(shù)據(jù)文件則位于s3-data-bucket/data.csv哈打。

數(shù)據(jù)準(zhǔn)備好以后,將其加載到一個Spark master pod中執(zhí)行讯壶。以Pod名為spark-master-controller-5rgz2為例料仗,命令如下:

kubectl exec -it spark-master-controller-v2hjb /bin/bash

如果你登錄進(jìn)入了Spark系統(tǒng),可以運(yùn)行Spark?Shell

export SPARK_DIST_CLASSPATH=$(hadoop classpath)

spark-shell

Setting default log level to "WARN".

To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).

Spark context Web UI available at http://192.168.132.147:4040

Spark context available as 'sc' (master = spark://spark-master:7077, app id = app-20170405152342-0000).

Spark session available as 'spark'.

Welcome to

? ____? ? ? ? ? ? ? __

/ __/__? ___ _____/ /__

_\ \/ _ \/ _ `/ __/? '_/

/___/ .__/\_,_/_/ /_/\_\? version 2.4.4

? /_/

Using Scala version 2.11.12 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_221)

Type in expressions to have them evaluated.

Type :help for more information.

scala>

現(xiàn)在讓我們告訴Spark Master伏蚊,S3存儲的詳細(xì)信息立轧,在上文所示的Scale提示符中輸入以下配置:

sc.hadoopConfiguration.set("fs.s3a.endpoint", "https://s3.amazonaws.com")

sc.hadoopConfiguration.set("fs.s3a.access.key", "s3-access-key")

sc.hadoopConfiguration.set("fs.s3a.secret.key", "s3-secret-key")

現(xiàn)在,只需將以下內(nèi)容粘貼到Scala提示符中躏吊,以提交Spark Job(請記得修改S3相關(guān)字段):

import org.apache.spark._

import org.apache.spark.rdd.RDD

import org.apache.spark.util.IntParam

import org.apache.spark.sql.SQLContext

import org.apache.spark.graphx._

import org.apache.spark.graphx.util.GraphGenerators

import org.apache.spark.mllib.regression.LabeledPoint

import org.apache.spark.mllib.linalg.Vectors

import org.apache.spark.mllib.tree.DecisionTree

import org.apache.spark.mllib.tree.model.DecisionTreeModel

import org.apache.spark.mllib.util.MLUtils

val conf = new SparkConf().setAppName("YouTube")

val sqlContext = new SQLContext(sc)

import sqlContext.implicits._

import sqlContext._

val youtubeDF = spark.read.format("csv").option("sep", ",").option("inferSchema", "true").option("header", "true").load("s3a://s3-data-bucket/data.csv")

youtubeDF.registerTempTable("popular")

val fltCountsql = sqlContext.sql("select s.title,s.views from popular s")

fltCountsql.show()

最后氛改,你可以使用kubectl patch command命令更新Spark部署。比如比伏,你可以在負(fù)載較高時添加更多工作節(jié)點(diǎn)胜卤,然后在負(fù)載下降后刪除這些工作節(jié)點(diǎn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赁项,一起剝皮案震驚了整個濱河市葛躏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌悠菜,老刑警劉巖舰攒,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異李剖,居然都是意外死亡芒率,警方通過查閱死者的電腦和手機(jī)囤耳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門篙顺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人充择,你說我怎么就攤上這事德玫。” “怎么了椎麦?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵宰僧,是天一觀的道長。 經(jīng)常有香客問我观挎,道長琴儿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任嘁捷,我火速辦了婚禮造成,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘雄嚣。我一直安慰自己晒屎,他們只是感情好喘蟆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鼓鲁,像睡著了一般蕴轨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上骇吭,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天橙弱,我揣著相機(jī)與錄音,去河邊找鬼燥狰。 笑死膘螟,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的碾局。 我是一名探鬼主播荆残,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼净当!你這毒婦竟也來了内斯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤像啼,失蹤者是張志新(化名)和其女友劉穎俘闯,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體忽冻,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡真朗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了僧诚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片遮婶。...
    茶點(diǎn)故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖湖笨,靈堂內(nèi)的尸體忽然破棺而出旗扑,到底是詐尸還是另有隱情,我是刑警寧澤慈省,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布臀防,位于F島的核電站,受9級特大地震影響边败,放射性物質(zhì)發(fā)生泄漏袱衷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一笑窜、第九天 我趴在偏房一處隱蔽的房頂上張望致燥。 院中可真熱鬧,春花似錦怖侦、人聲如沸篡悟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搬葬。三九已至荷腊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間急凰,已是汗流浹背女仰。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抡锈,地道東北人疾忍。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像床三,于是被迫代替她去往敵國和親一罩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評論 2 351