在集群 (YARN) 模式下,Spark 上的 Kerberos 问题
Kerberos issue on Spark when in cluster (YARN) mode
我正在使用带有 Kerberos 身份验证的 Spark。
我可以 运行 我的代码使用 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
我现在正在使用 YARN 在集群模式下 运行。
从here 可以看出,您需要指定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
然而,这个returns:
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[=12=]0(LoginContext.java:195)
at javax.security.auth.login.LoginContext.run(LoginContext.java:682)
at javax.security.auth.login.LoginContext.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`
显然,此设置并未扩展到 YARN 设置。如何解决集群模式下 YARN 的 Kerberos 问题?这是必须在我的 /src/main/scala/graphx_sp.scala 文件中的东西吗?
更新
通过 运行ning 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
然而,它随后失败了 post 这个:
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定义了一个publicHTTP RESTAPI来允许访问,我
以为它正在使用 acls
,但启用 ui.view.acls
并没有解决
问题。添加 --conf
spark.yarn.access.namenodes=webhdfs://name:50070
修复了
问题。这提供了以逗号分隔的安全 HDFS 名称节点列表,
Spark 应用程序将要访问的内容。 Spark 收购了
每个名称节点的安全令牌,以便应用程序可以
访问那些远程 HDFS 集群。这修复了身份验证
必填错误。
或者,直接访问 HDFS hdfs://file
使用 Kerberos 工作并进行身份验证,在 spark-submit
期间传递主体和密钥表。
我正在使用带有 Kerberos 身份验证的 Spark。
我可以 运行 我的代码使用 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
我现在正在使用 YARN 在集群模式下 运行。
从here 可以看出,您需要指定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
然而,这个returns:
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[=12=]0(LoginContext.java:195)
at javax.security.auth.login.LoginContext.run(LoginContext.java:682)
at javax.security.auth.login.LoginContext.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`
显然,此设置并未扩展到 YARN 设置。如何解决集群模式下 YARN 的 Kerberos 问题?这是必须在我的 /src/main/scala/graphx_sp.scala 文件中的东西吗?
更新
通过 运行ning 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
然而,它随后失败了 post 这个:
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定义了一个publicHTTP RESTAPI来允许访问,我
以为它正在使用 acls
,但启用 ui.view.acls
并没有解决
问题。添加 --conf
spark.yarn.access.namenodes=webhdfs://name:50070
修复了
问题。这提供了以逗号分隔的安全 HDFS 名称节点列表,
Spark 应用程序将要访问的内容。 Spark 收购了
每个名称节点的安全令牌,以便应用程序可以
访问那些远程 HDFS 集群。这修复了身份验证
必填错误。
或者,直接访问 HDFS hdfs://file
使用 Kerberos 工作并进行身份验证,在 spark-submit
期间传递主体和密钥表。