Spark on K8S模块的代码又臭又长,离我们上生产环境,也就一个debug的距离。干干巴巴,麻麻咧咧,盘它。。。
前置条件
-
你有一个可以提交 Spark on k8s 作业的 k8s 集群,可以参考https://spark.apache.org/docs/latest/running-on-kubernetes.html,自己搭一个玩玩
- 理论上没有也没关系,因为我们客户端进程只是一个本地的java程序,只是如果没有真正的 k8s 集群,这个作业在debug到一定阶段会走不下去而已
-
一只你熟练使用的 IDE
- 推荐 Intellj IDEA
一份新鲜热乎的 Spark 源码
-
一坨打包过的Spark package
- 可以根据上面的spark源码自己打包 - building-a-runnable-distribution
- 也可以下载 release,然后将代码 checkout 到对应的 tag
原理说明
上图所示是 Spark 官方文档中的 Spark on k8s 的架构图,图很简单,左边的 Client 和右边的 k8s 集群,其中 client 通过 spark-submit 接口和 k8s 集群进行交互,主要完成的是Spark Driver Pod的构建,当然由于本文主要讲的是 Client 进程调试相关的东西,后面的细节就先搁置了。
配置 IDE
通过 Remote 模板新建一份配置,默认的话 Host 的指向的一般是localhost,如果你在远程的机器上启动 spark-submit 进程,需要正确的设置Host,我们本地提交的话,直接改个name就可以使用了,如下图所示,
我们需要复制 Command line arguments for remote JVM 的内容,来配置到 spark-submit 进程的 java options里。
配置SPARK_SUBMIT_OPTS
设置 spark-submit 的客户端 java 参数可以通过 SPARK_SUBMIT_OPTS
环境变量来搞定,具体如下,
echo SPARK_SUBMIT_OPTS=\"-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=50014\" >> conf/spark-env.sh
开始调试
我们使用spark自带的示例程序 org.apache.spark.examples.HdfsTest
来进行调试,
Kent@KentsMacBookPro ~/Documents/spark-on-k8s/spark-3.0.0-SNAPSHOT-bin-2.7.3 bin/spark-submit \
--master k8s://https://10.120.238.100:7443 \
--name hehe \
--deploy-mode cluster \
--class org.apache.spark.examples.HdfsTest \
local:///opt/spark/examples/jars/spark-examples_2.12-3.0.0-SNAPSHOT.jar \
hdfs://hz-cluster10/user/kyuubi/hive_db/kyuubi.db/hive_tbl
当出现如下打印信息,即可切换到 IDE 中点击 debug 按钮。
Listening for transport dt_socket at address: 50014
当然,在这之前,必须要在合适的位置加上断点。
运气好的话,启动 debug 后,你就可以在如下位置进入断点。
我们注意到这个类中有一个 KubernetesClient
对象,我们试着用它来和 k8s 集群做个亲密交互。
上面的例子是访问我在 k8s 上提前建立好的一个ConfigMap。
所以我们可以看到 Client 进程中主要就是实例化了一个 KubernetesClient
对象来达到了和 k8s 集群,也就是 api server 的交互,完成对Spark Driver Pod的描述。
总结
文章很长,干干巴巴,麻麻咧咧,其实就是设置一个 SPARK_SUBMIT_OPTS
环境变量的事情,233333~