Spark on Kubernetes任务卡壳,日志报kubernetes client已关闭警告
解决思路
排查K8s客户端连接异常根源
日志中的kubernetes client has been closed警告虽标注“正常关闭”,但实际应用未终止,大概率是Spark与K8s API Server的连接出现异常中断或超时。可以调整以下参数:- 增大
spark.kubernetes.client.connectionTimeout(默认10s)和spark.kubernetes.client.socketTimeout(默认10s),延长连接等待时间; - 调整
spark.kubernetes.allocation.batch.size,减少批量请求K8s API的压力,避免触发API Server限流; - 检查驱动Pod的ServiceAccount是否有足够权限(如
pods的list/watch权限),权限不足可能导致客户端连接异常。
- 增大
定位阶段卡壳的具体原因
通过kubectl port-forward映射驱动Pod的Spark UI端口,查看卡壳阶段的详情:- 如果是Shuffle阶段:检查各任务的输入数据量,确认是否存在数据倾斜(某任务数据量远超其他任务)。若存在,可通过加盐拆分倾斜键、过滤异常大键等方式处理;同时检查执行器节点的磁盘使用情况,Shuffle数据写满磁盘会导致任务停滞;开启
spark.shuffle.service.enabled并确保Shuffle Service在K8s集群中正常部署,避免单个执行器故障导致Shuffle数据不可用。 - 如果是数据读取阶段:检查数据源(如HDFS、S3、数据库)的连通性和响应速度,是否存在外部数据源超时或阻塞;确认读取分区的划分是否合理,是否有分区数据量过大导致任务卡住。
- 如果是Shuffle阶段:检查各任务的输入数据量,确认是否存在数据倾斜(某任务数据量远超其他任务)。若存在,可通过加盐拆分倾斜键、过滤异常大键等方式处理;同时检查执行器节点的磁盘使用情况,Shuffle数据写满磁盘会导致任务停滞;开启
检查集群资源与网络状态
- 用
kubectl top nodes和kubectl top pods查看节点及Pod的CPU、内存使用率,确认是否存在节点资源耗尽(CPU被其他Pod占满、内存不足触发OOM但未杀死进程)的情况; - 测试执行器之间的网络连通性:在任意执行器Pod中执行
ping <其他执行器Pod IP>或telnet <IP> <Shuffle端口>,排查是否存在网络丢包或端口不通的问题; - 检查K8s API Server的状态,通过
kubectl get componentstatuses(或kubectl get pods -n kube-system | grep kube-apiserver)确认API Server是否正常运行,是否有请求堆积。
- 用
分析进程线程状态
- 进入驱动Pod:
kubectl exec -it <driver-pod-name> -- /bin/bash,找到Spark驱动进程ID(ps aux | grep spark),执行jstack <pid>导出线程栈,查看是否有线程处于BLOCKED或WAITING状态,是否存在死锁或等待外部资源的情况; - 同理排查执行器Pod的线程栈,确认执行器进程是否真的在运行任务,而非挂起。
- 进入驱动Pod:
排查版本兼容性问题
确认Spark版本与K8s版本是否兼容,例如Spark 3.0.x及以下与K8s 1.20+部分特性不兼容,可能导致K8s客户端异常。查看对应Spark版本的官方文档,确认已知的K8s兼容性bug,必要时升级或降级Spark/K8s版本。检查代码逻辑与外部依赖
排查任务代码中是否存在无限循环、未设置超时的外部调用(如HTTP请求、数据库查询),这类问题会导致任务卡住但进程不退出;检查是否使用了非线程安全的依赖库,导致线程阻塞。
内容的提问来源于stack exchange,提问作者user3085596
相关产品推荐
相关产品推荐

