一、概述

Apache Spark 是专为大规模数据处理而规划的快速通用的核算引擎。Spark是UC Berkeley AMP lab (加州大学伯克利分校的AMP实验室)所开源的类Hadoop MapReduce的通用并行框架,Spark,具有Hadoop MapReduce所具有的优点;但不同于MapReduce的是——Job中心输出成果能够保存在内存中,从而不再需求读写HDFS,因而Spark能更好地适用于数据挖掘与机器学习等需求迭代的MapReduce的算法。

官方文档:spark.apache.org/docs/latest…
Spark on k8s官方文档:spark.apache.org/docs/latest…
关于spark的介绍,能够参阅我这篇文章:大数据Hadoop之——核算引擎Spark

【云原生】Spark on k8s 讲解与实战操作

二、开端 Spark on k8s 运转原理

【云原生】Spark on k8s 讲解与实战操作
spark-submit 能够直接用于向Kubernetes集群提交spark应用程序。提交机制的作业原理如下:

  • Spark创立一个Spark driver 在Kubernetes pod 运转。
  • driver 程序创立也在Kubernetes pods中运转的执行器,并连接到它们,然后执行应用程序代码。
  • 当应用程序完结时,执行程序pod将停止并被整理,但驱动程序pod会保存日志并在Kubernetes API中保持“已完结”状态,直到终究进行垃圾收集或手动整理。

三、Spark 运转形式

  • Client :客户端进程,担任提交作业到Master。
  • Master :Standalone形式中主控节点,担任接纳Client提交的作业,办理Worker,并指令Worker发动Driver和Executor。
  • Worker :Standalone形式中slave节点上的看护进程,担任办理本节点的资源,定时向Master报告心跳,接纳Master的指令,发动Driver和Executor。
  • Driver : 一个Spark作业运转时包含一个Driver进程,也是作业的主进程,担任作业的解析、生成Stage并调度Task到Executor上。包含 DAGScheduler , TaskScheduler 。

1)cluster 形式

【云原生】Spark on k8s 讲解与实战操作

  1. Driver程序在某个worker节点,可是这个节点由Master指定;
  2. Driver程序占据Worker的资源;
  3. cluster mode下Master能够运用–supervise对Driver进行监控,假如Driver挂了能够主动重启;
  4. cluster mode下Master节点和Worker节点一般不在同一局域网,因而就无法将Jar包分发到各个Worker,所以cluster mode要求有必要提前把Jar包放到各个Worker节点对应的目录下面。

2)client 形式

【云原生】Spark on k8s 讲解与实战操作

  1. Driver进程便是开端执行你Spark程序的那个Main函数,它能够在任何节点(能够是spark集群内的节点,Master节点或Worker节点;也能够是有spark环境但不是spark集群内的某台机器);Worker便是Slave节点,Executor进程必然在Worker节点上,用来进行实践的核算;
  2. client mode下Driver进程不运转在Worker节点上,所以相对于参与实践核算的Worker节点而言,Driver就适当于是一个第三方的“client”;
  3. 正由于Driver进程不在Worker节点上,所以不会消耗Worker节点上的资源;
  4. client mode下Master和Worker节点有必要处于同一片局域网内,由于Drive要和Executor通信,例如Driver需求将Jar包通过Netty HTTP分发到Executor,Driver要给Executor分配使命等;
  5. client mode下没有监督重启机制,Driver进程假如挂了,需求额定的程序重启。

四、开端Spark on k8s 编排

1)下载Spark包

wget https://dlcdn.apache.org/spark/spark-3.3.0/spark-3.3.0-bin-hadoop3.tgz
tar -xf spark-3.3.0-bin-hadoop3.tgz
export SPARK_HOME=/opt/bigdata/servers/spark/spark-3.3.0-bin-hadoop3

2)构建镜像

Spark(从2.3版开端)顺便了一个Dockerfile,能够在kubernetes/dockerfiles/目录中找到它。

【云原生】Spark on k8s 讲解与实战操作
Spark还顺便一个构建和push镜像的脚本 bin/docker-image-tool.sh。构建镜像指令如下:


cd $SPARK_HOME
# 构建镜像
# -p ./kubernetes/dockerfiles/spark/Dockerfile,-p 指定Dockerfile
$SPARK_HOME/bin/docker-image-tool.sh -r myharbor.com/bigdata -t 3.3.0-hadoop3 build  build
# push
$SPARK_HOME/bin/docker-image-tool.sh -r myharbor.com/bigdata -t 3.3.0-hadoop3 push

3)装备 spark 用户权限

kubectl create ns spark
kubectl create serviceaccount spark -n spark
kubectl create clusterrolebinding spark-role --clusterrole=edit --serviceaccount=spark:spark
##在spark-submit中增加
--conf spark.kubernetes.authenticate.driver.serviceAccountName=spark

4)提交 Spark 使命(cluster 形式)

# 查看k8s apiserverl:kubectl cluster-info
cd $SPARK_HOME
./bin/spark-submit \
    --master k8s://https://192.168.182.110:6443 \
    --deploy-mode cluster \
    --name spark-pi \
    --class org.apache.spark.examples.SparkPi \
    --conf spark.executor.instances=5 \
    --conf spark.kubernetes.namespace=spark \
    --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark \
    --conf spark.kubernetes.container.image=myharbor.com/bigdata/spark:3.3.0-hadoop3 \
    local:///opt/spark/examples/jars/spark-examples_2.12-3.3.0.jar

【云原生】Spark on k8s 讲解与实战操作

【注意】这儿的 local:///opt/spark/examples/jars/spark-examples_2.12-3.3.0.jar 指的是 容器的文件系统路径,不是执行 spark-submit 的机器的文件系统路径,假如不运用 local 的话,也能够用 HTTPHDFS 等系统,没指定的话默认是 local 形式

5)装备spark历史服务器

这儿依靠与Hadoop hdfs环境,Hadoop on k8s环境布置能够参阅我以下两篇文章:

  • 【云原生】Hadoop on k8s 环境布置
  • 【云原生】Hadoop HA on k8s 环境布置

存储目录需求提前创立

kubectl exec -it hadoop-hadoop-hdfs-dn-0 -n hadoop -- bash
hdfs dfs -mkdir  hdfs://hadoop-hadoop-hdfs-nn.hadoop:9000/sparkhistory
hdfs dfs -chmod 777  hdfs://hadoop-hadoop-hdfs-nn.hadoop:9000/sparkhistory

spark-history.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spark-history-server
spec:
  selector:
    matchLabels:
      run: spark-history-server
  replicas: 1
  template:
    metadata:
      labels:
        run: spark-history-server
    spec:
      containers:
        - image: myharbor.com/bigdata/spark:3.3.0-hadoop3
          name: spark-history-server
          args: ["/opt/spark/bin/spark-class", "org.apache.spark.deploy.history.HistoryServer"]
          ports:
            - containerPort: 18080
              name: http
          env:
          - name: SPARK_HISTORY_OPTS
            value: "-Dspark.history.fs.logDirectory=hdfs://hadoop-hadoop-hdfs-nn.hadoop:9000/sparkhistory"
---

apiVersion: v1
kind: Service
metadata:
  name: spark-hs-svc
spec:
  ports:
  - port: 18080
    protocol: TCP
    targetPort: 18080
    nodePort: 31180
  selector:
    run: spark-history-server
  type: NodePort
status:
  loadBalancer: {}

执行

kubectl apply -f spark-history.yaml -n spark

【云原生】Spark on k8s 讲解与实战操作
web:http://192.168.182.110:31180
【云原生】Spark on k8s 讲解与实战操作
再提交使命

# 增加装备项:
# --conf spark.eventLog.enabled=true \
# --conf spark.eventLog.dir=hdfs://hadoop-hadoop-hdfs-nn.hadoop:9000/sparkhistory \
cd $SPARK_HOME
./bin/spark-submit \
    --master k8s://https://192.168.182.110:6443 \
    --deploy-mode cluster \
    --name spark-pi \
    --class org.apache.spark.examples.SparkPi \
    --conf spark.executor.instances=5 \
    --conf spark.kubernetes.namespace=spark \
    --conf spark.eventLog.enabled=true \
    --conf spark.eventLog.dir=hdfs://hadoop-hadoop-hdfs-nn.hadoop:9000/sparkhistory \
    --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark \
    --conf spark.kubernetes.container.image=myharbor.com/bigdata/spark:3.3.0-hadoop3 \
    local:///opt/spark/examples/jars/spark-examples_2.12-3.3.0.jar
### jar放在hdfs
kubectl cp examples/jars/spark-examples_2.12-3.3.0.jar hadoop/hadoop-hadoop-hdfs-dn-0:/tmp/ -n hadoop
kubectl exec -it hadoop-hadoop-hdfs-dn-0 -n hadoop -- bash
hdfs dfs -put /tmp/spark-examples_2.12-3.3.0.jar hdfs://hadoop-hadoop-hdfs-nn.hadoop:9000/sparkhistory/
cd $SPARK_HOME
./bin/spark-submit \
    --master k8s://https://192.168.182.110:6443 \
    --deploy-mode cluster \
    --name spark-pi \
    --class org.apache.spark.examples.SparkPi \
    --conf spark.executor.instances=5 \
    --conf spark.kubernetes.namespace=spark \
    --conf spark.eventLog.enabled=true \
    --conf spark.eventLog.dir=hdfs://hadoop-hadoop-hdfs-nn.hadoop:9000/sparkhistory \
    --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark \
    --conf spark.kubernetes.container.image=myharbor.com/bigdata/spark:3.3.0-hadoop3 \
    hdfs://hadoop-hadoop-hdfs-nn.hadoop:9000/sparkhistory/spark-examples_2.12-3.3.0.jar

【云原生】Spark on k8s 讲解与实战操作

6)提交 Spark 使命(client 形式)

从Spark 2.4.0开端,能够在客户端形式下在Kubernetes上运转Spark应用程序。当应用程序在客户端形式下运转时,驱动程序能够在k8s pod或物理主机上运转。

【云原生】Spark on k8s 讲解与实战操作

1、装备 spark 用户权限

# 上面已经装备,这儿能够忽略
kubectl create ns spark
kubectl create serviceaccount spark -n spark
kubectl create clusterrolebinding spark-role --clusterrole=edit --serviceaccount=spark:spark
##在spark-submit中增加
--conf spark.kubernetes.authenticate.driver.serviceAccountName=spark

2、准备独立Pod

装备 spark 容器,会在这个容器里以 client 形式 submit spark 程序,所以这个容器也会作为 driver。 spark-client-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spark-client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spark-client
      component: spark-client
  template:
    metadata:
      labels:
        app: spark-client
        component: spark-client
    spec:
      containers:
      - name: spark-client
        image: myharbor.com/bigdata/spark:3.3.0-hadoop3
        workingDir: /opt/spark
        command: ["/bin/bash", "-c", "while true;do echo spark-client;sleep 6000;done"]
      serviceAccountName: spark

3、露出service

咱们任意指定一个端口露出,后续client mode将通过去DNS去查找Driver Pod的位置,这也是Spark on k8s要求DNS的原因。 spark-client-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: spark-client-service
spec:
  selector:
    app: spark-client
  ports:
    - protocol: TCP
      port: 7321
      targetPort: 7321
  clusterIP: None

执行

kubectl apply -f spark-client-deployment.yaml -n spark
kubectl apply -f spark-client-service.yaml -n spark
kubectl get pods -n spark

4、提交 spark 使命

cd $SPARK_HOME
./bin/spark-submit \
    --master k8s://https://192.168.182.110:6443 \
    --deploy-mode client \
    --name spark-pi \
    --class org.apache.spark.examples.SparkPi \
    --conf spark.executor.instances=3 \
    --conf spark.kubernetes.namespace=spark \
    --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark \
    --conf spark.kubernetes.container.image=myharbor.com/bigdata/spark:3.3.0-hadoop3 \
    --conf spark.driver.host=spark-client-service  \
    --conf spark.driver.port=7321 \
    file:///opt/bigdata/servers/spark/spark-3.3.0-bin-hadoop3/examples/jars/spark-examples_2.12-3.3.0.jar

client 形式很少运用,略微了解即可,Spark on k8s解说与实战操作 就先到这儿了,有疑问的小伙伴欢迎给我留言,后续会继续更新【云原生+大数据】相关的文章,请小伙伴耐性等候~