使用K8s作为Spark资源管理器提交任务时遇匿名用户Pod权限错误求助
解决Spark on Kubernetes提交任务时的匿名用户权限错误
问题定位
报错pods is forbidden: User "system:anonymous" cannot watch resource "pods" in API group "" in the namespace "default"说明Spark提交请求时未正确使用有权限的ServiceAccount,导致以匿名身份访问Kubernetes API被拒绝。核心问题是ServiceAccount创建、权限绑定与Spark提交配置三者不匹配。
修复步骤
1. 修正ClusterRoleBinding的ServiceAccount关联
你创建了名为spark的ServiceAccount,但ClusterRoleBinding错误绑定到了default:default(default命名空间下的default账户),需要重新绑定到spark账户:
- 先删除原有绑定:
kubectl delete clusterrolebinding spark-role
- 创建正确的绑定:
kubectl create clusterrolebinding spark-role \ --clusterrole=edit \ --serviceaccount=default:spark \ --namespace=default
2. 调整Spark提交命令的ServiceAccount配置
当前spark-submit中指定的spark.kubernetes.authenticate.driver.serviceAccountName=default与实际使用的sparkServiceAccount不符,修改为:
./bin/spark-submit --master k8s://https://vm:6443 --class com.example.WordCounter --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark --conf spark.kubernetes.container.image=private-docker-registery/spark/spark:3.2.1-3 --conf spark.kubernetes.namespace=default --conf spark.kubernetes.authenticate.submission.oauthToken=$TOKEN --conf spark.kubernetes.authenticate.caCertFile=api.cert java-word-count-1.0-SNAPSHOT.jar
3. 确保使用正确的Spark ServiceAccount Token
你之前获取的是spark-token-86tns的token,需确认该secret确实属于sparkServiceAccount:
- 验证secret归属:
kubectl describe secret spark-token-86tns | grep "kubernetes.io/service-account.name"
- 若归属正确,重新获取并赋值token(避免base64编码问题):
TOKEN=$(kubectl get secret spark-token-86tns -o jsonpath='{.data.token}' | base64 -d)
4. 验证权限有效性
用获取的token直接调用Kubernetes API,确认权限正常:
curl -H "Authorization: Bearer $TOKEN" --cacert api.cert https://vm:6443/api/v1/namespaces/default/pods
若能返回pod列表,说明权限配置正确,此时重新执行spark-submit即可。
内容的提问来源于stack exchange,提问作者Mohammad Abdollahzadeh
相关产品推荐
相关产品推荐

