我正在使用spark和kerberos身份验证。
我可以使用spark-shell
罚款运行代码,也可以在本地模式下使用spark-submit
(例如—master local[16]
)。两者都按预期运作。
本地模式 -
spark-submit --class "graphx_sp" --master local[16] --driver-memory 20G target/scala-2.10/graphx_sp_2.10-1.0.jar
我现在正在使用纱线以聚类模式运行。
从这里我可以看到您需要指定keytab
的位置并指定principal
。因此:
spark-submit --class "graphx_sp" --master yarn --keytab /path/to/keytab --principal login_node --deploy-mode cluster --executor-memory 13G --total-executor-cores 32 target/scala-2.10/graphx_sp_2.10-1.0.jar
但是,这返回:
Exception in thread "main" java.io.IOException: Login failure for login_node from keytab /path/to/keytab: javax.security.auth.login.LoginException: Unable to obtain password from user
at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:987)
at org.apache.spark.deploy.SparkSubmit$.prepareSubmitEnvironment(SparkSubmit.scala:564)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:154)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:121)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: javax.security.auth.login.LoginException: Unable to obtain password from user
at com.sun.security.auth.module.Krb5LoginModule.promptForPass(Krb5LoginModule.java:897)
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:760)
at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
at javax.security.auth.login.LoginContext.login(LoginContext.java:587)
at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:978)
... 4 more
在使用Spark-Shell或在Spark-Submit中运行的本地模式之前,我进行以下Kerberos设置:
kinit -k -t ~/keytab -r 7d `whoami`
显然,此设置未扩展到纱线设置。如何在集群模式下用纱线解决Kerberos问题?这是否必须在我的/src/main/scala/graphx_sp.scala文件中?
更新
通过在详细模式下运行 kinit -V -k -t ~/keytab -r 7d
whoami,我能够看到prinicpal以 user@node
的形式。
我对此进行了更新,检查了keytab
的位置,并通过此检查点进行了成功:
INFO security.UserGroupInformation: Login successful for user user@login_node using keytab file /path/to/keytab
但是,它会失败,以下内容:
client token: N/A
diagnostics: User class threw exception: org.apache.hadoop.security.AccessControlException: Authentication required
我已经检查了键盘上的权限,并且读取权限正确。有人建议下一个可能性是损坏的键盘
我们发现当应用程序尝试从HDFS读取时,Authentication
required
错误发生。斯卡拉(Scala)正在做懒惰的评估,所以它不会失败,直到开始处理文件。这是从HDFS系列读取的: webhdfs://name:50070
。
由于WebHDFS定义了公共HTTP REST API以允许访问,我认为它正在使用acls
,但是启用ui.view.acls
没有修复问题。添加--conf
spark.yarn.access.namenodes=webhdfs://name:50070
修复了问题。这提供了安全HDFS纳米诺德郡的逗号分隔列表,Spark应用程序将访问哪个。Spark获得了每个名称的安全令牌,以便应用程序可以访问那些远程HDFS群集。这修复了身份验证所需的错误。
另外,可以直接访问HDFS hdfs://file
使用kerberos进行工作和身份验证,并且在spark-submit
期间通过了主和keytab。