对于目前基于 k8s 的的 spark 利用,次要采纳两种形式运行
- spark 原生反对的 spark on k8s
- 基于 k8s 的 operator 的 spark on k8s operator
前者是 spark 社区反对 k8s 这种资源管理框架而引入的 k8s client 的实现
后者是 k8s 社区为了反对 spark 而开发的一种 operator
区别 | spark on k8s | spark on k8s operator |
---|---|---|
社区反对 | spark 社区 | GoogleCloudPlatform 非官方反对 |
版本要求 | spark>=2.3,Kubernetes>=1.6 | spark>2.3,Kubernetes>=1.13 |
装置 | 依照官网装置,须要 k8s pod 的 create list edit delete 权限,且须要本人编译源码进行镜像的构建,构建过程繁琐 | 须要 k8s admin 装置 incubator/sparkoperator,须要 pod create list edit delete 的权限 |
应用 | 间接 spark submit 提交,如: 上面 code 1, 反对 client 和 cluster 模式,spark on k8s | 通过 yaml 配置文件模式提交,反对 client 和 cluster 模式,提交如 code2,具体参数参考 spark operator configuration |
长处 | 合乎 sparker 的形式进行工作提交,对于习惯了 spark 的使用者来说,应用起来更棘手 | k8s 配置文件形式提交工作,复用性强 |
毛病 | 运行完后 driver 的资源不会主动开释 | 运行完后 driver 的资源不会主动开释 |
实现形式 | 对于 spark 提交形式来说,无论是 client 提交还是 cluster 提交,都是继承 SparkApplication。以 client 提交,子类则是 JavaMainApplication, 该形式以反射运行, 对于 k8s 工作来剖析,clusterManager 为 KubernetesClusterManager, 该形式和向 yarn 提交工作的形式没什么区别; 以 cluster 形式提交, 对于 k8s 工作来说,spark 程序的入口为 KubernetesClientApplication,client 端会建设 clusterIp 为 None 的 service,executor 跟该 service 进行 rpc,如工作的提交的交互,且会建设以 driver-conf-map 后缀的 configMap,该 configMap 在建设 spark driver pod 的时候,以 volumn 挂载的模式被援用, 而该文件的内容最终在 driver 提交工作的时候以 –properties-file 模式提交给 spark driver,从而 spark.driver.host 等配置项就传输给了 driver,与此同时也会建设以 -hadoop-config 为后缀的 configMap,可是 k8s 镜像怎么辨别是运行 executor 还是 driver 的呢?一切都在 dockerfile(具体构建的时候依据 hadoop 和 kerbeors 环境的不一样进行区别配置) 和 entrypoint 中, 其中 shell 中是辨别 driver 和 executor 的; | 采纳 k8s CRD Controller 的机制,自定义 CRD, 依据 operator SDK, 监听对应的增删改查 event,如监听到对应的 CRD 的创立事件,则依据对应 yaml 文件配置项,建设 pod,进行 spark 工作的提交,具体的实现,可参考 spark on k8s operator design, 具体以 cluster 和 client 模式提交的原理和 spark on k8s 统一, 因为镜像复用的是 spark 的官网镜像 |
code 1
---
bin/spark-submit \
--master k8s://https://192.168.202.231:6443 \
--deploy-mode cluster \
--name spark-pi \
--class org.apache.spark.examples.SparkPi \
--conf spark.executor.instances=2 \
--conf "spark.kubernetes.namespace=dev" \
--conf "spark.kubernetes.authenticate.driver.serviceAccountName=lijiahong" \
--conf "spark.kubernetes.container.image=harbor.k8s-test.uc.host.dxy/dev/spark-py:cdh-2.6.0-5.13.1" \
--conf "spark.kubernetes.container.image.pullSecrets=regsecret" \
--conf "spark.kubernetes.file.upload.path=hdfs:///tmp" \
--conf "spark.kubernetes.container.image.pullPolicy=Always" \
hdfs:///tmp/spark-examples_2.12-3.0.0.jar
code 2
---
apiVersion: "sparkoperator.k8s.io/v1beta2"
kind: SparkApplication
metadata:
name: spark-pi
namespace: dev
spec:
type: Scala
mode: cluster
image: "gcr.io/spark-operator/spark:v3.0.0"
imagePullPolicy: Always
mainClass: org.apache.spark.examples.SparkPi
mainApplicationFile: "local:///opt/spark/examples/jars/spark-examples_2.12-3.0.0.jar"
sparkVersion: "3.0.0"
restartPolicy:
type: Never
volumes:
- name: "test-volume"
hostPath:
path: "/tmp"
type: Directory
driver:
cores: 1
coreLimit: "1200m"
memory: "512m"
labels:
version: 3.0.0
serviceAccount: lijiahong
volumeMounts:
- name: "test-volume"
mountPath: "/tmp"
executor:
cores: 1
instances: 1
memory: "512m"
labels:
version: 3.0.0
volumeMounts:
- name: "test-volume"
mountPath: "/tmp"
本文由博客群发一文多发等经营工具平台 OpenWrite 公布