本文比较初级,主要介绍spark和k8s入门知识;
k8s
简单执行流程
Kubecfg将特定的请求,比如创建Pod,发送给Kubernetes Client
用户执行kubectl/userClient向api server发起一个命令,
经过认证授权后,经过scheduler的各种策略,得到一个目标node,然后告诉api server,
api server 会请求相关node的kubelet,通过kubelet把pod运行起来,apiserver还会将pod的信息保存在etcd;
pod运行起来后,controllermanager就会负责管理pod的状态,如,若pod挂了,controllermanager就会重新创建一个一样的pod,或者像扩缩容等;
pod有一个独立的ip地址,但pod的IP是易变的,如异常重启,或服务升级的时候,IP都会变,这就有了service;
完成service工作的具体模块是kube-proxy;
在每个node上都会有一个kube-proxy,在任何一个节点上访问一个service的虚拟ip,都可以访问到pod;
service的IP可以在集群内部访问到,在集群外呢?service可以把服务端口暴露在当前的node上,外面的请求直接访问到node上的端口就可以访问到service了;
重要组成部分
Master组件
APIServer
提供资源操作的唯一入口,并且提供认证/授权/kubernets的访问控制
可以通过kubectl和自己开发的客户端,通过http的请求通过restapi的形式来访问apiserver,从而实现对整个集群的控制
ControllerManager
负责维护整个集群的状态,如,故障检测/扩缩容/滚动更新等
Scheduler
负责资源的调度,按照预定的调度策略,把pod调度到相应的node节点
Etcd
主要用于一致性存储,保存pod/service和集群的状态等信息
相当于k8s集群需要持久化的数据都会存储在etcd
Kube-dns
负责整个集群的dns服务,但并不是必须的,若不需要通过名字来访问,可以不安装kube-dns,但通常会安装,因为通过名字访问是一个比较重要的功能
Node组件
Kubelet
维护当前节点的容器的生命周期,维护当前节点的volume/网络等的管理
Kube-proxy
每个node都会运行一个kube-proxy,提供内部的服务发现和负载均衡,为service的概念提供一个落地的方法
Kube-dns
负责整个集群的dns服务,但并不是必须的,若不需要通过名字来访问,可以不安装kube-dns,但通常会安装,因为通过名字访问是一个比较重要的功能
Dashboard
提供一个集群相关数据展示和操作的ui界面
配置存储中心
etcd
K8S的存储服务。etcd 是分布式键值存储系统,存储了K8S 的关键配置和用户配置,K8S中仅API Server 才具备读写权限,其他组件必须通过API Server的接口才能读写数据
架构
Spark
简单执行流程
Spark任务的任务执行流程_爱写代码的小小程序员的博客-CSDN博客_spark任务执行流程
spark执行流程图_青眼酷白龙的博客-CSDN博客_spark运行流程图
重要组成部分
driver
它会运行客户端写好的main方法,并且它会创建sparkcontext对象,该对象是所有spark程序的执行入口
application
它就是一个应用程序,它包括了Driver端的代码逻辑和任务在执行的时候需要的资源信息
clusterManager
给当前任务提供计算资源的外部服务
clusterManager-standalone
它是spark自带的集群模式,整个任务的资源分配由master负责
clusterManager-yarn
Spark程序可以提交到yarn中去运行,整个任务的资源分配由ResourceManager负责
clusterManager-k8s
Spark程序可以提交到k8s,连接apiserver
master
它是整个spark集群的老大,它负责资源的分配
worker
它是整个spark集群的小弟,它负责任务的计算节点
executor
它是一个进程,它会在worker节点上启动对应的executor进程
task
它就是一个线程,它是以线程的方式运行在worker节点的executor进程中
架构
Cluster Mode Overview - Spark 3.2.1 Documentation
Spark on k8s(Native)
简单执行流程
客户端通过spark-submit将任务提交到K8s集群中,并在集群中启动一个Spark Driver Pod;
Spark Driver通过调用K8s API启动相应的Executor Pod, 组成一个Spark Application集群并执行作业任务;任务执行完成后,Executor Pod会被销毁, 而Driver Pod会持久化相关日志,并保持在’completed’状态,直到用户手清理或被K8s集群的垃圾回收机制回收;
优点:
可以更好的利用K8s的集群资源,通过K8s赋能,更好的进行资源的隔离;
缺点:
Spark-submit在K8s集群之外,使用非声明式的提交接口;
Spark Application之间没有协同调度,在小集群中很容易出现调度饿死的情况;
需要手动配置网络,来访问WebUI;
任务监控比较麻烦,没有接入Prometheus集群监控;
架构
Spark Operator
简单执行流程
用户使用 sparkctl 或 kubectl 创建 SparkApplication 对象。SparkApplication controller 从 kube-api server 接收对象请求,创建 submission (实际上就是 参数化以后的 spark-submit 命令),然后发送给 submission runner。 Submission runner 提交 app 到 k8s 集群,并创建 driver pod。一旦 driver pod 正常运行,则由 driver pod 创建 executor pod。 当应用正常运行时,spark pod monitor 监听 application 的 pod 状态,并将pod 状态的更新发送给 controller,由 controller 负责调用 kube-api 更新 spark application 的状态(实际上是更新 SparkApplication CRD 的状态字段)
重要组成部分
SparkApplication controller
监听 SparkApplication 对象的创建、更新、删除,然后对不同的事件做不同的处理。
submission runner,
在 控制器收到 spark app 创建请求的时候,运行 spark-submit 提交应用到 k8s 集群。
spark pod monitor
监听 spark pods 状态,pod 状态更新时,发送给控制器
mutation adminssion webhook
可选项,处理spark driver 和 executor pod 的定制化功能需求
命令行工具-sparkctl
从功能上类似于 kubectl,专用于 spark app on k8s
架构
Spark on k8s 对比 spark operator
spark on k8s:
命令行方式启动
sparkOperator:
声明式 API方式启动