如何在Kubernetes上成功部署运行Spark?求可用分步指南
Spark on Kubernetes 可落地分步部署指南(4节点集群管理员适用)
前置准备与环境清理
先清理所有历史失败部署的残留资源,避免配置冲突:
- 执行
helm uninstall <之前安装Bitnami Spark用的release名> -n <对应命名空间>,未通过Helm安装过可跳过 - 清理残留的Spark相关资源并重建专用命名空间:
kubectl delete ns spark --ignore-not-found=true kubectl create ns spark
- 提前确认环境满足以下要求,不满足直接调整后再往下操作:
- 4节点集群每节点剩余可用CPU≥2核、可用内存≥4G,避免资源不足导致任务调度失败
- 管理机已安装
kubectl,版本与集群版本差不超过1个小版本,且已配置管理员权限的kubeconfig - 集群已配置默认StorageClass,无默认配置可后续手动绑定临时存储
- 集群节点可拉取所需容器镜像,离线环境提前将镜像同步到私有镜像仓库
步骤1:配置Spark所需RBAC权限
公开教程普遍遗漏这步,权限不足会直接导致Executor无法创建,触发资源不接收类报错:
- 编写RBAC配置文件,保存为
spark-rbac.yaml:
apiVersion: v1 kind: ServiceAccount metadata: name: spark namespace: spark --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: spark-cluster-role rules: - apiGroups: [""] resources: ["pods", "pods/log", "services", "configmaps", "persistentvolumeclaims"] verbs: ["get", "list", "watch", "create", "delete", "patch"] - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: spark-cluster-role-binding subjects: - kind: ServiceAccount name: spark namespace: spark apiGroup: "" roleRef: kind: ClusterRole name: spark-cluster-role apiGroup: rbac.authorization.k8s.io
- 执行命令应用配置:
kubectl apply -f spark-rbac.yaml
步骤2:选用稳定版Spark镜像
直接使用官方维护的稳定版镜像即可,无需自行打包:
- 验证可用的稳定镜像版本为
apache/spark:3.5.0-scala2.12-java17-ubuntu,该版本无已知K8s调度类Bug - 注意:Spark on K8s原生模式不需要部署常驻Master/Worker进程,之前通过Helm部署的Standalone模式Master服务本身不适配原生调度逻辑,连接该服务是触发
URI has an authority component报错的核心原因
步骤3:安装匹配版本的Spark提交客户端
在可访问K8s集群的管理机上安装客户端,不要使用系统源自带的旧版本:
- 从Spark官方发布渠道获取
spark-3.5.0-bin-hadoop3.tgz预编译包,解压到管理机本地目录 - 将解压后目录下的
bin路径加入系统PATH环境变量 - 执行
spark-submit --version验证安装,输出版本号为3.5.0即为正常
注意:客户端版本必须和镜像内的Spark版本完全一致,否则会触发序列化、调度类异常
步骤4:提交测试任务验证部署
使用官方自带的Pi计算示例做验证,所有参数显式指定,避免默认值适配问题:
spark-submit \ --master k8s://https://<你的K8s APIServer地址>:6443 \ --deploy-mode cluster \ --name spark-pi-test \ --class org.apache.spark.examples.SparkPi \ --conf spark.executor.instances=2 \ --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark \ --conf spark.kubernetes.namespace=spark \ --conf spark.kubernetes.container.image=apache/spark:3.5.0-scala2.12-java17-ubuntu \ --conf spark.driver.memory=1g \ --conf spark.driver.cores=1 \ --conf spark.executor.memory=1g \ --conf spark.executor.cores=1 \ local:///opt/spark/examples/jars/spark-examples_2.12-3.5.0.jar
关键参数说明(对应之前踩坑的核心问题):
--master参数格式必须为k8s://https://<K8s APIServer地址>:6443,不能附加多余路径,不能填写之前Helm部署的Standalone模式Master服务地址- 必须显式指定Driver、Executor的CPU和内存配额,不要使用默认值,默认配额超过单节点剩余资源时就会触发
Initial job has not accepted any resources报错 - 示例Jar包路径以
local://开头,代表读取容器镜像内置的文件,不要填写管理机本地文件路径,否则Executor无法获取任务资源
步骤5:验证运行结果
- 提交任务后执行
kubectl get pods -n spark,会先创建1个Driver Pod,运行10秒左右自动创建2个Executor Pod - 所有Pod状态变为Completed后,执行
kubectl logs <Driver Pod名称> -n spark | grep "Pi is roughly",能看到类似Pi is roughly 3.14156...的输出即代表部署完全正常 - 任务运行结束后Executor Pod会自动销毁,Driver Pod默认保留用于日志排查,不需要可手动删除
常见问题快速修复
- 仍报
Initial job has not accepted any resources:执行kubectl describe pod <处于Pending状态的Pod名> -n spark查看Events字段,99%场景为节点剩余资源不足,调小Driver/Executor的CPU、内存配额即可 - 报镜像拉取失败:提前在节点上手动拉取对应镜像,或配置集群镜像加速
- 需要访问Spark UI:执行
kubectl port-forward <Driver Pod名> 4040:4040 -n spark,本地访问4040端口即可
不推荐使用Bitnami Spark Helm Chart部署K8s原生模式Spark,该Chart默认适配Standalone架构,和Spark原生K8s调度逻辑不兼容,会出现Worker正常启动但任务无法调度的问题。
内容的提问来源于stack exchange,提问作者mxcolin
相关产品推荐
相关产品推荐

