Spark on k8s: 调试Driver Pod的方法

相关文章

1 . Spark on k8s: 调试客户端spark-submit进程

通过前一篇博客的学习,已经学会了客户端 spark-submit 这个进程的调试方式,由于是本地进程整个过程还是比较方便的。我们知道 Spark 提交模式一般分为 client/cluster 两种,直观上的区别就是 SparkContext 类是否在客户端进程中进行实例化。Spark on K8S 从2.3版本开始支持cluster模式,从2.4开始支持client模式,对于调试 Driver 而言,client 模式可以直接按照之前的文章进行,对于 cluster 模式,Diver 运行在 Pod 里面,我们改如何调试呢?

前置条件

  • 你有一个可以提交 Spark on k8s 作业的 k8s 集群,可以参考https://spark.apache.org/docs/latest/running-on-kubernetes.html,自己弄一个 minikube
  • 你最爱的的 IDE
    • 推荐 Intellj IDEA
  • 把 Spark 源码放进 IDE
  • 把源码打包 或者 checkout至已存在包的git revision

原理说明

spark on k8s架构

上图所示是 Spark 官方文档中的 Spark on k8s 的架构图,图很简单,左边的 Client 和右边的 k8s 集群,当然这个官方图比较老,也不是很准确的描述 Spark on k8s 所有的提交方式, 它所示的是 cluster 模式是的运行时形态, 我们可见 Spark 的 Driver Pod 在 k8s 的某个 kubelet 之上,我们要调试它,就需要和他内部的 jvm 建立 JPDA Transport 通信。

配置 IDE

这边我们可以直接建立一个 local host 的远程调试配置


ide debug 配置

开始调试

我们需要在spark的提交参数中加入如下的关键配置,该配置的值可以从 IDE 中copy

-conf spark.driver.extraJavaOptions=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=50014

总的提交命令如下

bin/spark-submit \
    --conf spark.driver.extraJavaOptions=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=50014 \
    --conf spark.kubernetes.namespace=ns1 \
    --conf spark.kubernetes.container.image.pullSecrets=mysecret \
    --conf spark.kubernetes.hadoop.configMapName=hz10-hadoop-dir \
    --conf spark.master=k8s://https://10.120.238.100:7443 \
    --conf spark.kubernetes.container.image=harbor-inner.sparkonk8s.netease.com/tenant1-project1/spark:v3-SPARK-28896
    --conf spark.kerberos.keytab=/Users/Kent/Downloads/kyuubi.keytab \
    --conf spark.kerberos.principal=kyuubi/[email protected] \
    --conf spark.kubernetes.kerberos.krb5.path=/etc/krb5.conf  \
    --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

如果提交成功我们看到如下图所示的信息,拿到 Spark Driver Pod 的 pod name,它的状态转变成running状态时,说明已经ok,可以进行下一步操作

Spark on k8s: 调试Driver Pod的方法_第1张图片
submit

通过kubectl命令也可以查看该 pod的状态,如下图所示
Spark on k8s: 调试Driver Pod的方法_第2张图片
list pods

通过kubectl log hehe-2c6c6c6cdbf66f13-driver -nns1命令查看日志,可以看到,我们的 Driver pod 正阻塞在监听状态。

Spark on k8s: 调试Driver Pod的方法_第3张图片
listening

我们需要将这个端口给port-forward 出来,

port-forward

然后我们就可以在 IDE 中进行启动调试了,当然也不忘在该打断点的地方打上断点

点击debug按钮后,port-forward 会继续打印如下信息。

image.png

重新打印 pod 日志,可以发现日志已经打印到断点所在的最前面位置


Spark on k8s: 调试Driver Pod的方法_第4张图片
log

回转到我们的 IDE, 可以看到已经进入我们设置的断点,接下来就可以进行正常的调试过程了。

ide breakpoint

下一个断点


image.png

我们从上图中可以看到在 Spark Driver Pod 中还会实例化一个 kubernetes 的 client,通过这个 client,Spark Driver进程可以实现与 k8s api server 的通信,实现诸如 executor 分配等逻辑。

总结

对于 Spark On K8S 调试Driver 的 Pod,我们需要通过
-conf spark.driver.extraJavaOptions=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=50014, 在Driver Pod中启动监听服务,然后通过 k8s 提供的 port-forward功能, 将这个地址弄到本地,方便的进行调试。

你可能感兴趣的:(Spark on k8s: 调试Driver Pod的方法)