在寫這個(gè)的時(shí)候完慧,spark版本為2.2.1秧秉。
基于kubernetes部署的兩種方式
- 直接使用kubernetes作為集群管理器(Cluster Manager)仰禀,類似與mesos和yarn甜攀,使用方式可以看running-on-kubernetes浑劳。但是這個(gè)部署方式阱持,一是還不成熟,不推薦在生產(chǎn)環(huán)境使用魔熏。第二是要求k8s版本大于1.6衷咽,但我這邊版本1.5.1,線上在用蒜绽,不太想升級(jí)镶骗,而spark只是想搭起來玩玩...
- 第二種方式是standalone的方式,即便是不用集群也能很方便的用sbin下的腳本來部署躲雅,不過使用k8s有幾個(gè)好處鼎姊,一個(gè)是提高機(jī)器使用率。這邊的k8s集群大部分是在白天使用,晚上空閑相寇,剛好能拿來跑數(shù)據(jù)慰于。二是方便一鍵擴(kuò)容,一鍵升級(jí)唤衫,能復(fù)用本身在k8s集群上做好的監(jiān)控以及日志收集
在k8s上部署standalone集群
以下內(nèi)容主要依據(jù)github 上k8s example中spark的例子婆赠。做了一些適應(yīng)版本的修改。
首先我們需要一個(gè)有spark以及其依賴的的docker鏡像佳励,這邊我就很簡(jiǎn)單的下載了spark-2.2.1-bin-hadoop2.7并放在了/opt目錄下休里,打包的dockerfile就不發(fā)了,docker store上也有很多做好的鏡像植兰。另外份帐,k8s需要有dns(現(xiàn)在似乎默認(rèn)帶的)。
namespace
為了方便管理楣导,還是新建一個(gè)namespace废境,將所有的相關(guān)的都放在這個(gè)namespace下,方便資源管理筒繁。
apiVersion: v1
kind: Namespace
metadata:
name: "spark-cluster"
labels:
name: "spark-cluster"
kubectl create -f namespace-spark-cluster.yaml 新建一個(gè)名為spark-cluster的namespace噩凹。
master
master分為兩個(gè)部分,一個(gè)是類型為rc的主體毡咏,命名為spark-master-controller.yaml驮宴,另一部分為一個(gè)service,暴露master的端口給slaver使用呕缭。
kind: ReplicationController
apiVersion: v1
metadata:
name: spark-master-controller
spec:
replicas: 1
selector:
component: spk-master
template:
metadata:
labels:
component: spk-master
spec:
containers:
- name: spk-master
image: spark:2.2.1.1
command: ["/bin/sh"]
args: ["-c","sh /opt/spark-2.2.0-bin-hadoop2.7/sbin/start-master.sh && tail -f /opt/spark-2.2.0-bin-hadoop2.7/logs/spark--org.apache.spark.deploy.master.Master-1-*"]
ports:
- containerPort: 7077
- containerPort: 8080
以上為controller堵泽,直接使用spark的start-master腳本啟動(dòng),但是啟動(dòng)后他會(huì)退到后臺(tái)恢总,導(dǎo)致k8s啟動(dòng)不了pod迎罗,所以還加了個(gè)tail -f一個(gè)master輸出的log,順便也方便查看log片仿。
kind: Service
apiVersion: v1
metadata:
name: spk-master
spec:
ports:
- port: 7077
targetPort: 7077
name: spark
- port: 8080
targetPort: 8080
name: http
selector:
component: spk-master
一個(gè)service纹安,把7077端口和8080端口暴露出來給集群,方便slaver直接用spk-master:8080這樣的方式進(jìn)行訪問砂豌。注意厢岂,只是暴露給集群,外部訪問的方式最后會(huì)說阳距。
kubectl create -f spark-master-controller.yaml —namespace=spark-cluster
kubectl create -f spark-master-service.yaml —namespace=spark-cluster
這里有個(gè)坑塔粒,start-master這個(gè)啟動(dòng)腳本中會(huì)用到SPARK_MASTER_PORT這個(gè)參數(shù),而上邊這個(gè)service如果名字為spark-master的話剛好沖突了筐摘,會(huì)把SPARK_MASTER_PORT設(shè)置為 host:port的形式卒茬,導(dǎo)致腳本啟動(dòng)失敗映跟。所以我一股腦把所有的spark-master改成spk-master了
worker
kind: ReplicationController
apiVersion: v1
metadata:
name: spark-worker-controller
spec:
replicas: 1
selector:
component: spark-worker
template:
metadata:
labels:
component: spark-worker
spec:
containers:
- name: spark-worker
image: spark:2.2.1.1
command: ["/bin/sh"]
args: ["-c","sh /opt/spark-2.2.0-bin-hadoop2.7/sbin/start-slave.sh spark://spk-master.spark-cluster:7077;tail -f /opt/spark-2.2.0-bin-hadoop2.7/logs/spark--org.apache.spark.deploy.worker.Worker*"]
ports:
- containerPort: 8081
resources:
requests:
cpu: "1"
memory: "10Gi"
limits:
cpu: "2"
memory: "12Gi"
kubectl create -f spark-worker-controller.yaml —namespace=spark-cluster
啟動(dòng)worker腳本中需要傳入master的地址,因?yàn)橛衐ns且設(shè)置了service的緣故扬虚,可以通過spk-master.spark-cluster訪問。把replicas設(shè)置為N即可啟動(dòng)N個(gè)worker球恤。另外辜昵,我還在worker上加了資源的限制,限制最多使用2個(gè)cpu以及12g內(nèi)存咽斧。
proxy
image為elsonrodriguez/spark-ui-proxy:1.0 這玩意在一般啟動(dòng)standalone集群的時(shí)候是沒有的堪置,但是在k8s集群里邊,則必不可缺张惹。
設(shè)想一下舀锨,如果只是簡(jiǎn)單的暴露master的8080端口出來,我們只能看到master的管理頁(yè)面宛逗,但是進(jìn)一步從master訪問worker的ui則變得不太現(xiàn)實(shí)(每個(gè)worker都有自己的ui地址坎匿,且ip分配很隨機(jī),這些ip只能在集群內(nèi)部訪問)雷激。所以我們需要一個(gè)代理服務(wù)替蔬,從內(nèi)部訪問完我們需要的頁(yè)面后,返回給我們屎暇,這樣我們只需要暴露一個(gè)代理的地址即可承桥。
kind: ReplicationController
apiVersion: v1
metadata:
name: spark-ui-proxy-controller
spec:
replicas: 1
selector:
component: spark-ui-proxy
template:
metadata:
labels:
component: spark-ui-proxy
spec:
containers:
- name: spark-ui-proxy
image: elsonrodriguez/spark-ui-proxy:1.0
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
args:
- spk-master:8080
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 120
timeoutSeconds: 5
kubectl create -f spark-ui-proxy-controller.yaml —namespace=spark-cluster
并且暴露proxy的80端口
kind: Service
apiVersion: v1
metadata:
name: spark-ui-proxy
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 32180
selector:
component: spark-ui-proxy
kubectl create -f spark-ui-proxy-service.yaml —namespace=spark-cluster
至此,集群搭建完畢根悼⌒滓欤可以通過集群的32180端口訪問管理頁(yè)面。