【Spark on K8S】Spark里的k8s client

1 Overview

目前在我们的应用下,会有这样的一种特殊的场景。比如说 Driver 创建在 A 集群,但是需要 Driver 将 Executor Pod 创建到 B 集群去。所以我们这里会有两个集群的 master url,分别是集群 A 和集群 B。那么创建任务的模式就是 spark-subtit 的 master url 指向集群 A,然后给 Driver 的 k8s client 设置其创建 Executor Pod 的 master url 指向 B,那么在现有 Spark 的参数下,能否直接通过 SparkConf 或者环境变量来实现这一点呢?我们看看源码。
对于这样的需求,我们首先需要去了解 Spark 是如何跟 k8s 集群打交道的。Spark on K8S 在 submit 的时候默认是直接在 K8S Master 节点提交,通过 --master 或者 SparkConf 中的 spark.master 来指定。

The Spark master, specified either via passing the --master command line argument to spark-submit or by setting spark.master in the application’s configuration, must be a URL with the format k8s://<api_server_url>. Prefixing the master string with k8s:// will cause the Spark application to launch on the Kubernetes cluster, with the API server being contacted at api_server_url. If no HTTP protocol is specified in the URL, it defaults to https. For example, setting the master to k8s://example.com:443 is equivalent to setting it to k8s://https://example.com:443, but to connect without TLS on a different port, the master would be set to k8s://http://example.com:8443.

这样其实就很容易理解了,就是在 spark-submit 的时候,通过 Java 的 k8s client 来连接集群的 apiserver url,并且将 Driver Pod 的构建信息,通过 POST 请求发过去 k8s 集群的 apiserver,apiserver 在收到请求之后,创建出 Driver Pod。Spark 中封装的 k8s client 的主要代码在 SparkKubernetesClientFactory,这里构建一个 client,需要传入一些参数,比如 namespacesparkConf 这些,这些是用来给 Java 版本的 k8s client 构建时候需要的参数来传递的。
在这里插入图片描述
查看这个方法在下面几个类中有使用。可以理解的是,当进行 spark-submit 的时候,就需要创建一个 k8s client 来连接 k8s 集群。其次就是创建完 Driver Pod 之后,同样在 Driver 的进程中,也需要创建一个 k8s client 的实例来连接 k8s 集群,从而创建 Executor Pod。
在这里插入图片描述
这里通过代码,也可以看到,在 Spark 里,k8s client 分为两类,Driver 和 Submission。
在这里插入图片描述

2 Submission 的 k8s client

spark-submit 阶段连接 k8s 集群的目的是创建 Driver Pod,下图的过程是先通过 createKubernetesClient 这个方法,传入参数,构建出 Spark 封装出来的 k8s client,然后进入 run() 方法仔细看一下创建的过程。
在这里插入图片描述
先看一下 master 参数,这里的 master 就是 spark-submit 的时候指定的了,如果要改,那就直接改提交时候的脚本就可以了。
在这里插入图片描述
从下图可以看到,构建 Driver Pod 的过程就是先构建好 Driver 容器,然后配置一些 Volumes 之类的其他属性或者组件,最后包出来一个 DrIver Pod,扔给 Spark 的 k8s client 来给 apiserver 发。最后还能看到注册了一个 watcher,这个 watcher 就是来 watch spark-submit 的过程。
在这里插入图片描述
Submission 的 k8s client 的作用就是直接跟 k8s 的 apiserver 通信,把需要提交的命令提交给 apiserver,然后 apiserver 去创建 Driver 的 Pod。

3 Driver 的 k8s client

KubernetesClusterManager 要做的事情是继承了 ExternalClusterManager 也就是 Spark 里的外部集群管理的组件,k8s client 是在创建调度的 Backend 做的事情 createSchedulerBackend,因为没有 k8s client,那这个 k8s 的集群管理器 ClusterManager。
在这里插入图片描述
在 Driver 里创建一个 k8s client 需要一个 masterURL。如果我们希望在 Driver 里传入另一个 apiserver 的地址,而不是用 in-cluster 的模式来创建 Executor,那么这段代码就需要仔细看看了。
在这里插入图片描述
经过测试之后,发现这里面的 apiServerUri 恒等于默认值 https://kubernetes.default.svc。所以说目前如果要通过 Spark Conf 来直接修改 Driver 创建 Executor 发送的 apiserver 地址,可能是做不到的。源码做不到,也不代表我们没办法,可能对于需要鉴权和安全认证的 apiserver 是比较麻烦的,以为还需要传证书之类的东西,如果是简单的不需要鉴权和认证的 apiserver,这里加个环境变量,或者 Spark Conf,去控制 Driver 的行为,读环境变量里的 apiserver 的 url 就可以了。
在这里插入图片描述
在 Driver 中真正通过 k8s client 来创建 Executor Pod 是在 ExecutorPodAllocator 中。类似于 spark-submit 创建 Driver Pod 的过程,这里也是通过各种步骤把 Executor 从容器到 Pod 定义定好,然后再通过 spark k8s client 提交给 apiserver。
在这里插入图片描述

4 Summary

Spark on Kubernetes 的模块代码量不多,源码很好分析,当然因为还比较新,所以很多功能支持上也就可能不如 Yarn 了,不过 Kuberenetes 本身有很多 trick,Spark 任务只要被 spark-submit 提交上去了,基本上就是 Kubernetes 里随便玩了,但是 Executor 毕竟是 Drvier 来创建的,所以想随心所欲,还是很难的,有时候甚至要去改 Spark 里 Driver 去创建 Executor Pod 的逻辑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值