我们正尝试使用代码(java)访问以kerberized形式化的Hadoop集群(Cloudera发行版),但出现以下异常。
原因:javax.security.auth.login.LoginException:无法获取 来自用户的密码 com.sun.security.auth.module.Krb5LoginModule.promptForPass(Krb5LoginModule.java:897) 在 com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5Login Module.java:760)在 com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617)
我们已将属性“ hadoop.security.authentication”用作kerberos
,将fs.defaultFS
用作hdfs://devha:8020
,并在用户信息组中传递了keytabfilepath。
答案 0 :(得分:0)
首先,阅读有关您问题的评论。好东西。
后退一步,因为该信息可能使您不知所措,因此有两种可能的方法可以对Hadoop集群进行身份验证。 用户通常将使用用户名(本金)和密码。 应用程序通常将使用主体和密钥表文件。 Kerberos管理员使用“ kadmin”应用程序创建密钥表文件。
此外,还有“登录”用户的概念-应用程序范围内的默认用户,或特定于您当前需求的“当前”用户。您经常会使用前者来访问本地集群上的资源,而后者则用来访问外部集群上的资源。
由于我使用的是后者,因此我可以为您提供一个快速的代码段以帮助您入门。进行初始化:
UserGroupInformation.setConfiguration(configuration);
其中“配置”是从标准位置(/ etc / hadoop)读取的,或者是即时生成的。注意-设置了一个静态值,因此您需要非常小心!
对于我使用的单个用户(应用程序)
UserGroupApplication user = UserGroupInformation.loginUserFromKeytabAndReturnUGI(principal, keytabFile);
此方法有多种变体-例如,它们采用用户名还是密钥表文件?他们设置“登录”用户还是返回新的UserGroupInformation对象?请注意,由于某些设置了全局值,因此您要了解使用哪一个的后果。
您现在必须在doAs()调用中包装对集群的调用:
user.doAs(new PrivilegedExceptionAction<Void>() {
public Void run() throws Exception {
// do all of your hadoop calls here
return null;
}
}
如果您一直使用“登录”用户,我不记得是否需要这样做。我们需要同时支持本地和外部集群,对于我们来说,总是像这样包装所有东西是最简单的。这意味着我们只需在操作开始时设置一次“用户”即可。
如果要获取有关用户模拟,使用SSL加密(rpc.privacy)等的详细信息,请参见上面提到的资源。