Spark-on-K8s中Pending与Completed状态Executor Pod处理方案咨询
问题1:资源受限环境下Executor Pod持续创建导致节点过载
问题分析
你已设置spark.executor.instances=1,但资源不足时Executor Pod处于Pending状态,Driver会持续尝试创建新的Executor补充,导致大量Pending Pod堆积。这是因为Spark默认的Executor重试机制未限制次数,会不断尝试满足配置的Executor数量。
解决方案
关闭动态资源分配
禁用动态分配,避免Driver自动调整Executor数量,确保严格遵循固定实例数配置:--conf spark.dynamicAllocation.enabled=false限制Executor重试次数
通过配置最大重试次数,阻止Driver无限创建Pending Pod:--conf spark.kubernetes.executor.maxRetries=0设为0表示仅尝试创建一次Executor;若允许一次重试,可设为1,从根源上避免Pod数量失控。
清理已存在的Pending Pod
Spark无原生自动清理Pending Pod的机制,可通过K8s命令批量清理指定作业的Pending Executor:kubectl delete pods -n default --field-selector=status.phase=Pending -l spark-role=executor,spark-app-name=${APP_NAME}
问题2:Driver因LivenessProbe重启后Executor Pod残留为Completed状态
问题分析
从日志可见,Driver的优雅关闭钩子因超时被强制终止(ShutdownHook '$anon$2' timeout),导致Driver未能完成Executor的清理指令发送。K8s LivenessProbe触发容器重启时会直接终止Driver进程,而Spark的优雅关闭流程需要足够时间完成任务收尾和Executor通信。
解决方案
延长Spark关闭超时时间
调整关闭钩子超时参数,给优雅关闭流程足够时间完成:--conf spark.shutdownHook.timeout=60s默认超时为30秒,你的日志显示30秒后触发超时,延长该时间可确保Executor收到清理指令。
优化LivenessProbe配置
调整探测参数,避免在Driver优雅关闭期间触发重启:- 延长
initialDelaySeconds,确保Driver完全启动后才开始探测 - 增大
failureThreshold和periodSeconds,给Driver足够的关闭缓冲时间
示例配置(需根据实际启动时间调整):
livenessProbe: httpGet: path: /healthz port: 4040 initialDelaySeconds: 120 periodSeconds: 30 failureThreshold: 3- 延长
自动清理Completed状态的Executor Pod
通过K8s TTL控制器自动清理已完成的Executor Pod,提交作业时添加配置:--conf spark.kubernetes.executor.podTemplate.spec.annotations=kubernetes.io/ttlSecondsAfterFinished: "60"该配置会让Completed状态的Executor Pod在60秒后被自动删除,避免残留。
强化Executor与Driver的关联
确保Executor Pod的OwnerReference指向Driver Pod,让K8s能正确管理Executor的生命周期:--conf spark.kubernetes.executor.ownerReference.type=Pod
内容的提问来源于stack exchange,提问作者thebluemagician

