Spark on K8s执行器Pod长期Pending问题排查求助
从你提供的所有信息来看,你的Spark Executor Pod一直处于Pending状态的核心原因是Kubernetes调度器无法找到满足资源需求的节点,具体来说就是minikube节点的CPU和内存剩余资源不足以支撑Executor Pod的资源请求。下面我来一步步拆解原因和对应的解决办法:
一、直接触发原因:节点资源不足
从Executor Pod的事件日志里可以看到明确的调度失败提示:
Warning FailedScheduling 83s (x541 over 91m) default-scheduler 0/1 nodes are available: 1 Insufficient cpu, 1 Insufficient memory.
这说明你的minikube节点当前剩余的CPU和内存,达不到Executor Pod申请的资源量,所以调度器无法为它分配节点。
二、为什么调整了minikube资源还是不行?
你已经执行了minikube start --kubernetes-version v1.12.0 --cpus 4 --memory 8192来扩容节点资源,但要注意两个关键点:
- minikube的总资源会被K8s系统组件(kubelet、docker、kube-proxy等)占用一部分,实际可分配给业务Pod的资源会比你设置的4核CPU、8G内存少。比如系统组件可能会占用1核左右的CPU和1-2G内存,剩下的才是给Spark驱动和Executor用的。
- 你可能没有同步调整Spark提交时的Executor资源参数,默认情况下Spark on K8s的Executor可能会请求1核CPU+1G内存,但如果你的应用设置了更高的请求(比如通过
--executor-cores、--executor-memory参数),就会超过节点剩余资源。
三、具体解决步骤
1. 先确认节点的实际可用资源
执行以下命令查看minikube节点的资源使用和剩余情况:
kubectl describe node minikube
找到Allocatable(节点可分配给Pod的总资源)和Allocated resources(已分配的资源)部分,示例输出如下:
Allocatable: cpu: 3800m # 这里是3.8核,因为系统占用了0.2核 memory: 7855148Ki # 约7.5G,系统占用了0.5G Allocated resources: Resource Requests Limits -------- -------- ------ cpu 1000m (26%) 1000m (26%) memory 2Gi (26%) 2Gi (26%)
这里可以算出剩余的CPU是3800m - 1000m = 2800m,剩余内存是7.5G - 2G = 5.5G,你的Executor资源请求不能超过这个数值。
2. 调整Spark提交的Executor资源参数
在spark-submit命令里显式设置Executor的核数和内存,确保不超过节点的剩余资源。示例命令如下:
spark-submit \ --master k8s://https://$(minikube ip):8443 \ --deploy-mode cluster \ --name simpleapp \ --class com.example.SimpleApp \ --executor-cores 1 \ --executor-memory 1G \ --conf spark.executor.instances=1 \ # 如果需要更精细控制,还可以设置K8s的资源请求/限制 --conf spark.kubernetes.executor.request.cores=1000m \ --conf spark.kubernetes.executor.request.memory=1G \ local:///path/to/your/app.jar
注意:如果你的驱动Pod已经占用了一部分资源,要把这部分也算进去,比如驱动用了1核1G,那Executor最多只能用剩余的2.8核5.5G以内的资源。
3. 进一步扩容minikube资源(如果物理机允许)
如果调整Spark参数后还是不够,可以继续增加minikube的资源,比如:
minikube stop minikube start --kubernetes-version v1.12.0 --cpus 6 --memory 12288
但要确保你的物理机本身有足够的CPU和内存(比如物理机至少有8核16G内存,否则minikube会占用过多物理资源导致卡顿)。
4. (可选)降低kubectl和K8s服务器的版本差
你的kubectl客户端是v1.17,而K8s服务器是v1.12,虽然跨版本兼容,但偶尔可能会有一些资源计算的小问题。如果有条件,可以把kubectl降级到v1.12.x版本,尽量保持客户端和服务器版本一致。
四、额外注意点
- 驱动Pod已经处于Running状态,说明驱动的资源请求是满足的,问题完全集中在Executor的资源配置上。
- 可以通过
kubectl describe pod <executor-pod-name>查看Executor Pod的具体资源请求,确认是不是请求过高。
内容的提问来源于stack exchange,提问作者cpchung

